klewis
klewis

Reputation: 8360

Bootstrap 4 how to filter list based on data attribute values

I have the following form running on PHP

    <form method="get" id="searchform" action="<?php echo esc_url( home_url( '/' ) ); ?>" role="search">
        <label class="assistive-text" for="s">
            <?php esc_html_e( 'Search', 'ithub' ); ?>
        </label>
        <div class="input-group">
            <input class="field form-control" id="s" name="s" type="text" value="<?php the_search_query(); ?>">
            <span class="input-group-append">
                <input class="submit btn btn-primary" id="searchsubmit" name="submit" type="submit" ?>">
            </span>
        </div>
        <div class="col-lg-12 ml-auto p-2">
          <ul class="list-group" id="myList">
            <li class="list-group-item"><a href="#" data-meta="First item, house">First item</a></li>
            <li class="list-group-item"><a href="#" data-meta="Second item, car">Second item</a></li>
            <li class="list-group-item"><a href="#" data-meta="Third item, garage">Third item</a></li>
            <li class="list-group-item"><a href="#" data-meta="Fourth item, yard">Fourth</a></li>
        </ul>  
    </form>

With Bootstrap 4, is there a way (perhaps a component or technique) I can filter my list-group based on characters I type into my input field? For example, if I start typing in "hou", it will only display the first line item in my list-group due to it being close enough to house as a data value?

Is this possible?

Upvotes: 1

Views: 2824

Answers (2)

NoWar
NoWar

Reputation: 37632

Just in case if someone have to use Bootstrap form-check-input I could offer another Jquery selector.

Html (ASP NET MVC Razor)

<input class="form-control py-2 border-right-0 border" maxlength="100" type="search"
  value="" id="search-input" name="search-input">
    
<div class="list-group">
   @foreach (var item in Model.Where(x => x.DeviceNodeFaultTypeID == (int)DeviceNodeFaultTypeEnums.General).OrderBy(x => x.Definition))
   {
     <div class="list-group-item list-group-item-action p-1">
       <div class="form-check">
          <input class="form-check-input" type="radio" name="faults" id="[email protected]" value="@item.ID">
          <label class="form-check-label" for="[email protected]">
            @item.Definition
          </label>
          </div>
     </div>
   }    
</div>

JS

document.getElementById('search-input').addEventListener('input', function (e) {
   let filter = $(this).val();
   if (filter.length > 0) {
      filter = filter.toUpperCase();
   }
   $('.list-group .list-group-item').each(function () {
     let li = $(this)
     let label = li.children('.form-check').children('.form-check-label');
     if (label.text().toUpperCase().indexOf(filter) > -1) {
        li.removeClass('d-none')
     } else {
        li.addClass('d-none')
     }
    });
});

Upvotes: 1

StaticBeagle
StaticBeagle

Reputation: 5185

Here is a solution using jQuery. I filtered on .data('meta') to be able to find 'hou' as in your example. If you need to filter by the text in the anchor itself, you can use .text() instead (uncomment the lines below)

$('#s').on('input',function(e){
    let input = $(this).val()
    let filter = input.toUpperCase()
    $('.list-group .list-group-item').each(function() {
      let li = $(this)
      let anchor = li.children('a')
      // Filter by text
      // if(anchor.text().toUpperCase().indexOf(filter) > -1) {
      // Filter by meta
      if(anchor.data('meta').toUpperCase().indexOf(filter) > -1) {
        li.removeClass('d-none')
      } else {
        li.addClass('d-none')
      }
    });
});

Here is a live demo
https://www.bootply.com/hKmCpyJvUS

Upvotes: 3

Related Questions