Home > Software design >  jQuery search title and contents with accordion
jQuery search title and contents with accordion

Time:01-08

I wanted to create a live search on the title and the description or content with an accordion. I've seen this post How to search through nested accordion using JS and see if it could help and I've tried it and it works fine.

The problem is I don't think it looks for the title, it only look for the description. I wanted to look at it for both title and description.

HTML

<input type="text" placeholder="Search Keyword Info"  id="search-qa">

<div >
  <div >
    <div >
      <label  data-category="location"> Where is Test</label>
    </div>
    <div >
      <div >
        <div  data-category="location">
          <p>Qweeee not a description.</p>
        </div>
      </div>
    </div>
  </div>
  <div >
    <div >
      <label  data-category="location"> What is a Test</label>
    </div>
    <div >
      <div >
        <div  data-category="location">
          <p>Lorem Ips</p>
        </div>
      </div>
    </div>
  </div>
  <div >
    <div >
      <label  data-category="location"> Who is Test</label>
    </div>
    <div >
      <div >
        <div  data-category="location">
          <p>Dolor it</p>
        </div>
      </div>
    </div>
  </div>
</div>

JS

$("#search-qa").on('keyup', function() {

  let searchText = $(this).val().toLowerCase();

  $(".collapse *").each(function() {
  
    let text = $(this).immediateText().toLowerCase();

    if (text.indexOf(searchText) == -1) {
      $(this).parents('.collapse').addClass('hidden');
    }
    else {
      $(this).parents('.collapse').removeClass('hidden');
    }
  });

});

$.fn.immediateText = function() {
  return this.contents().not(this.children()).text();
};

Fiddle: https://jsfiddle.net/idonthaveagirlfriend/3con2p4x/13/

Thanks for the help!

CodePudding user response:

The logic is already searching in both the titles and descriptions of each collapsible section.

The issue is due to the fact you add or remove the hidden class in every iteration of the loop through the child elements. As such, you could remove the class when a match is found in one child but then the class is added to hide the parent again when there is no match in the next child.

To fix this you can amend you logic so that you hide everything before the search starts and unhide only when a match is found within the loop. Try this:

jQuery($ => {
  $("#search-qa").on('keyup', function() {
    let searchText = $(this).val().toLowerCase().trim();
    $('.collapse').addClass('hidden', searchText.length > 0); // hide all elements when a search starts

    $(".collapse *").each(function() {
      let $child = $(this);
      let $collapse = $child.closest('.collapse');
      let text = $child.immediateText().toLowerCase().trim();

      if (text.indexOf(searchText) !== -1)
        $collapse.removeClass('hidden'); // show the current collapse container when a match is found
    });
  });
})

$.fn.immediateText = function() {
  return this.contents().not(this.children()).text();
};
.collapse {
  border: 1px solid currentColor;
  margin: 10px 0;
  -webkit-transition: background 0.2s ease-in;
  -moz-transition: background 0.2s ease-in;
  -o-transition: background 0.2s ease-in;
  transition: background 0.2s ease-in;
}

.collapse__head {
  font-size: 20px;
  font-weight: 700;
  position: relative;
  cursor: pointer;
}

.collapse__body {
  max-height: 0;
  overflow: hidden;
  transition: all 300ms ease;
}

.hidden {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<input type="text" placeholder="Search Keyword Info"  id="search-qa">

<div >
  <div >
    <div >
      <label  data-category="location"> Where is Test</label>
    </div>
    <div >
      <div >
        <div  data-category="location">
          <p>Qweeee not a description.</p>
        </div>
      </div>
    </div>
  </div>
  <div >
    <div >
      <label  data-category="location"> What is a Test</label>
    </div>
    <div >
      <div >
        <div  data-category="location">
          <p>Lorem Ips</p>
        </div>
      </div>
    </div>
  </div>
  <div >
    <div >
      <label  data-category="location"> Who is Test</label>
    </div>
    <div >
      <div >
        <div  data-category="location">
          <p>Dolor it</p>
        </div>
      </div>
    </div>
  </div>
</div>

  •  Tags:  
  • Related