JQuery嵌套列表过滤器 - 当父匹配时显示所有子项

时间:2018-02-09 18:53:39

标签: javascript jquery html list filter

我有这个jQuery函数,它根据标签文本和文本框输入过滤列表。

它需要根据匹配类型以两种不同的方式运作:

  1. 如果孩子匹配,请显示父母。那是有效的。
  2. 如果父母是匹配,则显示所有孩子。那不行。
  3. 小提琴:https://jsfiddle.net/xtLwnshd/

    var labels = $('label');  // cache this for better performance
    
    $('#filter').keyup(function() {
      var valThis = $(this).val().toLowerCase();
      
      if (valThis == "") {
        labels.parent().show();          // show all lis
      } else {
        labels.each(function() {
          var label = $(this);                    // cache this
          var text = label.text().toLowerCase();
          if (text.indexOf(valThis) > -1) {
            label.parents('li').show()           // show all li parents up the ancestor tree
          } else {
           label.parent().hide();                // hide current li as it doesn't match
          }
        });
      };
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <input type="text" id="filter" />
    <span class="checkbox-list">
    <ul>
        <li>
            <label>Parent1</label>
            <ul>
                <li>
                    <label>Child12</label>
                </li>
                <li>
                    <label>Child3</label>
                </li>
                <li>
                    <label>Item4</label>
                </li>
                <li>
                    <label>Item5</label>
                </li>
            </ul>
        </li>
        <li>
            <label>Item6</label>
        </li>
        <li>
            <label>Item7</label>
            <ul>
                <li>
                    <label>Item4</label>
                </li>
                <li>
                    <label>Item8</label>
                </li>
            </ul>
        </li>
    </ul>
    </span>

    我怎样才能让这个也适用于#2?我尝试在任何比赛中展示所有的孩子,但我认为它正在取消自己或其他东西。我对JQuery不太满意。

1 个答案:

答案 0 :(得分:1)

我们需要相同的功能,经过数小时的搜索,我决定编写自己的功能。

它是这样工作的:

  • 第一个循环执行搜索,并根据是否找到匹配项为每个项目设置显示属性。该函数通过将匹配项推入matches列表来记住匹配项。

  • 第二个循环遍历每个匹配项,并检查匹配项的所有子项是否都被隐藏,这反过来意味着只有父项才是匹配项。

  • 如果所有子项都被隐藏,则父项为匹配项,我们希望让其所有项重新出现。

它可以使用突出显示的匹配,但这又是一天。

function filter(inputSelector, dataSelector) {
  let input = document.getElementById(inputSelector);
  let filter = input.value.toUpperCase();
  let ul = document.getElementById(dataSelector);
  let items = ul.getElementsByTagName('li');

  // Treffer merken
  let matches = [];

  // Suchlauf: Treffer ermitteln, DOM-Elemente zeigen/verstecken
  for (let i = 0; i < items.length; i++) {
    currentItem = items[i];

    txtValue = currentItem.textContent || currentItem.innerText || '';

    if (txtValue.toUpperCase().indexOf(filter) > -1) {
      currentItem.style.display = '';
      matches.push(currentItem);
    } else {
      currentItem.style.display = 'none';
    }
  }

  // Trefferlauf: Alle getroffenen Elemente ablaufen und deren Kinder prüfen
  for (let i = 0; i < matches.length; i++) {
    let childListItemsOfMatch = matches[i].getElementsByTagName('li');

    // Ermitteln, ob der Treffer ggf. bei einem Kind lag
    let allChildrenInvisible = true;
    for (let k = 0; k < childListItemsOfMatch.length; k++) {
      if (childListItemsOfMatch[k].style.display == '') {
        allChildrenInvisible = false;
        break;
      }
    }

    // Treffer lag beim Parent, also alle Kinder anzeigen
    if (allChildrenInvisible) {
      for (let k = 0; k < childListItemsOfMatch.length; k++) {
        childListItemsOfMatch[k].style.display = '';
      }
    }
  }
}
<!DOCTYPE html>
<html lang="de">

  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Liste mit Filter</title>
  </head>

  <body>
    <h1>Entwurfsmuster</h1>
    <p>Beispielsuchen: 'er', 'gof', 'method', 'lorem'/'ipsum'/'dolar', 'Erzeugungsmuster'</p>
    <input type="text" id="filter" placeholder="Suchbegriff eingeben..." onkeyup="filter('filter', 'data')">
    <ul id="data">
      <li>
        <h2>Erzeugungsmuster</h2>
        <ul>
          <li>Abstract Factory (GoF)</li>
          <li>Builder (GoF)</li>
          <li>Factory Method (GoF)</li>
          <li>Multiton</li>
          <li>Object Pool</li>
          <li>Prototype (GoF)</li>
          <li>Singleton (GoF)</li>
        </ul>
      </li>
      <li>
        <h2>Strukturmuster</h2>
        <ul>
          <li>Adapter (GoF)</li>
          <li>Bridge (GoF)</li>
          <li>Composite (GoF)</li>
          <li>Decorator (GoF)</li>
          <li>Fassade (GoF)</li>
          <li>Flyweight (GoF)</li>
          <li>Proxy (GoF)</li>
        </ul>
      </li>
      <li>
        <h2>Verhaltensmuster</h2>
        <ul>
          <li>Chain of Responsibility (GoF)</li>
          <li>Command (GoF)</li>
          <li>Interceptor</li>
          <li>Interpreter (GoF)</li>
          <li>Iterator (GoF)</li>
          <li>Mediator (GoF)</li>
          <li>Memento (GoF)</li>
          <li>Null Object</li>
          <li>Observer (GoF)</li>
          <li>Protocol Stack</li>
          <li>State (GoF)</li>
          <li>Strategy (GoF)</li>
          <li>Template Method (GoF)</li>
          <li>Visitor (GoF)</li>
        </ul>
      </li>
      <li>
        <h2>Andere Muster</h2>
        <ul>
          <li>Business Delegate</li>
          <li>Data Access Object</li>
          <li>Dependency Injection</li>
          <li>Extension Interface</li>
          <li>Fluent Interface</li>
          <li>Inversion of Control (IoC)</li>
          <li>Model View Controller (MVC)</li>
          <li>Model View Presenter (MVP)</li>
          <li>Model View Update (MVU)</li>
          <li>Model View ViewModel (MVVM)</li>
          <li>Registry</li>
          <li>Repository</li>
          <li>Service Locator</li>
          <li>Threadpool</li>
          <li>Transferobjekt</li>
        </ul>
      </li>
      <li>
        Lorem
        <ul>
          <li>ipsum
            <ul>
              <li>dolor</li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
  </body>

</html>