Javascript применить фильтр к списку объектов и скрыть соответствующий разделитель раздела (разделитель раздела и элементы списка разделены) - PullRequest
1 голос
/ 19 февраля 2020

Я использовал javascript для создания таблицы, которую можно фильтровать.
Таблица разделена на алфавитные секции, визуально представленные разделителем.
После фильтрации таблицы разделитель не исчезает, так как он имеет имя класса, отличное от самого элемента списка.
Я бы не хотел перезагружать всю таблицу после изменения входных данных фильтра, так как я думаю, что javascript тоже должна выполнить эту работу.

Здесь изображена ситуация

<div class="address_book_wrapper">
  <div class="address_top_wrapper"></div>
  <div class="address_center_wrapper">

  </div>
  <div class="contact_list_wrapper">
          <!-- search input fiels -->
      <input id="address_search_input" type="text" placeholder="Who are you looking for <?= $first_name ?>?"/>
      <div id="contact_list"></div>
    </div>
</div>
<div class="address_bottom_wrapper"></div>

</div>
//global variables
var initial_char = null;
var address_table_container = document.getElementById('contact_list');

function process_address_data(address_data) {

  function createAddressRow(rowAddressData) {
    var name = rowAddressData[1];
    var first_char = name.charAt(0);

    if (first_char != initial_char) {
      //create new section divider
      var table_section_wrap = document.createElement("div");
      // add a class name
      table_section_wrap.className = 'rowSectionAddress';
      // letter holder
      var first_letter = document.createElement("span");
      first_letter.innerHTML = first_char;
      first_letter.className = 'address_name_table';
      //create new user row
      var table_data_wrap = document.createElement("div");
      table_data_wrap.className = 'rowDataAddress';
      //first name as well
      var address_name = document.createElement("span");
      address_name.innerHTML = rowAddressData[1] + " " + rowAddressData[2];
      address_name.className = 'address_name_table';  
      //append section divider
      table_section_wrap.appendChild(first_letter);
      table_data_wrap.appendChild(address_name);
      address_table_container.appendChild(table_section_wrap);
      address_table_container.appendChild(table_data_wrap);

      //update initial_char and set to current char
      initial_char = first_char;
    } else {
      //create new user row
      var table_data_wrap = document.createElement("div");
      table_data_wrap.className = 'rowDataAddress';
      // name holder
      var address_name = document.createElement("span");
      address_name.innerHTML = rowAddressData[1] + " " + rowAddressData[2];
      address_name.className = 'address_name_table';
      //append name
      table_data_wrap.appendChild(address_name);
      address_table_container.appendChild(table_data_wrap);
    }
  }

    // loop through the data and call createRow function
  for (var i = 0, len = address_data.length; i < len; i++) {
    // get each data
    var userAddressData = address_data[i];
    // create the row (see above function)
    createAddressRow(userAddressData);
  }
}


//filter list
//todo: if filter then delete section letters
function filterContactList() {
  var input, filter, li, i, txtValue;
  input = document.getElementById("address_search_input");
  filter = input.value.toUpperCase();
  li = document.getElementsByClassName("rowDataAddress");
  for (i = 0; i < li.length; i++) {
    var li_val = li[i];
    txtValue = li_val.textContent || li_val.innerText;
    if (txtValue.toUpperCase().indexOf(filter) > -1) {
      li[i].style.display = "";
    } else {
      li[i].style.display = "none";
    }
  }
}

Текущий результат выглядит следующим образом, и я хочу избавиться от делителей. Другие записи скрыты из-за фильтра
enter image description here

Надеюсь, это правильно отображает мою проблему.

1 Ответ

0 голосов
/ 19 февраля 2020

То, как вы кодируете, действительно трудоемко ..

, чтобы упростить код, я использовал набор данных, чтобы сохранить первую букву непосредственно на элементе для отображения или скрытия. Я также добавил noDisplaySub класс. для поиска / отображения задания

https://developer.mozilla.org/en-US/docs/Web/API/HTMLOrForeignElement/dataset

const DomParser = new DOMParser()
  ,   ctx_List  = document.getElementById('contact_list')
  ,   inSearch  = document.getElementById('address_search_input')
  ;
function createSection(firstChar)
  {
  let section= 
   `<div class="rowSectionAddress" data-char1="${firstChar}">
       <span class="address_name_table">${firstChar}</span>
    </div>`;
  return DomParser.parseFromString( section, 'text/html').body.firstChild ;
  }
function createRows(arrData)
  {
  let row =
   `<div class="rowDataAddress">
        <span class="address_name_table">${arrData[1]} ${arrData[2]}</span>
    </div>`;
  return DomParser.parseFromString( row, 'text/html').body.firstChild ;
  }
function process_address_data(address_data)
  {
  let initial_char = null
    , ref_section  = null
    ;
  for (let address of address_data)
    {
    let first_char = address[1].charAt(0).toUpperCase()

    if (initial_char != first_char)
      {
      initial_char = first_char
      ref_section  = createSection(first_char)
      ctx_List.appendChild(ref_section)
      }
    
    ref_section.appendChild( createRows(address) )
    }
  }
var inSearch_key = '*'   // current address_search_input value
  ;
inSearch.oninput=e=>
  {
  let SearchLetter = inSearch.value.toUpperCase();

  SearchLetter = (SearchLetter.length > 0) ? SearchLetter.charAt(0) : '*'

  if (inSearch_key!== SearchLetter )
    {
    inSearch_key = SearchLetter
    ctx_List.querySelectorAll('.rowSectionAddress').forEach(section=>
      {
      if (inSearch_key===section.dataset.char1
      || inSearch_key==='*' )
        { section.classList.remove('noDisplaySub') }
      else
        { section.classList.add('noDisplaySub')    }
  }) } }


// --------------- test part --------------------------
const address_data
        = [ [ '', 'abc 1', 'abc 2' ] 
          , [ '', 'bcd x', 'bcd y' ] 
          , [ '', 'bcd w', 'bcd z' ] 
          , [ '', 'ecd m', 'ecd n' ] 
          , [ '', 'ecd v', 'ecd n' ] 
          , [ '', 'ecd w', 'ecd n' ] 
          ]

process_address_data(address_data)
.noDisplaySub > div { display: none; }
<div class="address_book_wrapper">
  <div class="address_top_wrapper"></div>
  <div class="address_center_wrapper">
   
  </div>
  <div class="contact_list_wrapper">
            <!-- search input fiels -->
    <input id="address_search_input" type="text" placeholder="type '*' for All (or a,b,e) "/>
    <div id="contact_list"></div>
  </div>
<div class="address_bottom_wrapper"></div>
    
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...