Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery search filter show the list item header

I have following list

<ul id="fromList">
    <li class="header">-ABC-</li>
    <li class="item">123</li>
    <li class="item">258</li>
    <li class="item">189</li>
    <li class="item">545</li>

    <li class="header">-CDE-</li>
    <li class="item">789</li>
    <li class="item">215</li>
    <li class="item">897</li>
    <li class="item">999</li>

    <li class="header">-EFG-</li>
    <li class="item">701</li>
    <li class="item">566</li>
    <li class="item">511</li>       
</ul>

When searching the item it should show the list item header
For example when i am searching '9'
It should show

  • -ABC-
  • 189
  • -CDE-
  • 789
  • 897
  • 999

Now I am getting search list only:

function filter(element) {
  var value = $(element).val();
  $("#fromList li").each(function() {
    if ($(this).text().search(new RegExp(value, "i")) > -1) {
      $(this).show();
    } else {
      $(this).hide();
    }
  });
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type='text' id='txtList' onkeyup="filter(this)" />
<ul id="fromList">
  <li class="header">ABC</li>
  <li class="item">123</li>
  <li class="item">258</li>
  <li class="item">189</li>
  <li class="item">545</li>

  <li class="header">CDE</li>
  <li class="item">789</li>
  <li class="item">215</li>
  <li class="item">897</li>
  <li class="item">999</li>

  <li class="header">E</li>
  <li class="item">701</li>
  <li class="item">566</li>
  <li class="item">511</li>
</ul>
like image 324
CnuVas Avatar asked Apr 19 '15 02:04

CnuVas


2 Answers

You could combine the .prevAll() method with the .first() method in order to select the header element of the li that should be shown:

$(this).prevAll('.header').first().show();

Updated Example

function filter(element) {
    var value = $(element).val();
    $("#fromList li").each(function () {
        if ($(this).text().search(value) > -1) {
            $(this).show();
            $(this).prevAll('.header').first().show();
        } else {
            $(this).hide();
        }
    });
}

I'd suggest using unobtrusive JavaScript. I also shortened your code a little.

Updated Example

$('#txtList').on('keyup', function () {
    var value = this.value;
    $('#fromList li').hide().each(function () {
        if ($(this).text().search(value) > -1) {
            $(this).prevAll('.header').first().add(this).show();
        }
    });
});

As a side note, if you want to exclude the header from being selected if you were to type something like "ABC", just use the .not() method to negate the .header element from the selection:

Updated Example

if ($(this).not('.header').text().search(value) > -1) {
    // ..
}
like image 72
Josh Crozier Avatar answered Nov 10 '22 22:11

Josh Crozier


Alternatively, you could just specify sorting the list items with the items class, rather than every item in the list:

$('#txtList').keyup(function () {
    var value = this.value;
    $('#fromList li.item').each(function () {
        if ($(this).text().search(value) > -1) {
            $(this).show();
        } else {
            $(this).hide();
        }
    });
});
like image 37
ryebread Avatar answered Nov 10 '22 20:11

ryebread