skip to Main Content

I wanted to create some sort of FAQ page using a nested accordion but it somewhat didn’t work. I wanted to search through the title and the body of each card. So far I can only search through the title and it‘s still not hiding the irrelevant results.

When I search “nostro three”, nothing shows up. Only when I type “what to do”, the first parent accordion disappears.

I wanted to search all the content and hide the irrelevant information not related to the search result.

$(document).ready(function() {
  $("#searchfaq").on("keypress click input", function() {
    var val = $(this).val();

    if (val.length) {
      $(".accordion .card").hide().filter(function() {
        return $('.card-title', this).text().toLowerCase().indexOf(val.toLowerCase()) > -1;
      }).show();
    } else {
      $(".accordion .card").show();
    }
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.2.1/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.2.1/css/bootstrap.min.css" />

<!-- Search Bar -->
<div class="row gap-y">
  <div class="offset-md-2 col-md-8 col-12">
    <div class="form-group input-group">
      <input id="searchfaq" type="text" class="form-control" placeholder="Search FAQ">
    </div>
  </div>
</div>

<!-- Accordion -->
<div class="row">
  <div class="col-md-8 mx-auto">
    <div class="accordion accordion-connected accordion-arrow-right" id="accordion-1">
      <div class="card">
        <h5 class="card-title">
          <a data-toggle="collapse" href="#collapse-1-1">About</a>
        </h5>
        <div id="collapse-1-1" class="collapse" data-parent="#accordion-1">
          <h6 class="card-title card-inside">
            <a data-toggle="collapse" href="#collapse-1-1-1">What is you?</a>
          </h6>
          <div id="collapse-1-1-1" class="collapse" data-parent="#accordion-1-1">
            <div class="card-body" style="padding-left: 30px">
              Lorem Ipsum dolor sit amet one.
            </div>
          </div>

          <h6 class="card-title card-inside">
            <a data-toggle="collapse" href="#collapse-1-1-2">What is other you?</a>
          </h6>
          <div id="collapse-1-1-2" class="collapse" data-parent="#accordion-1-1">
            <div class="card-body" style="padding-left: 30px">
              Lorem Ipsum dolor sit amet two.
            </div>
          </div>

          <h6 class="card-title card-inside">
            <a data-toggle="collapse" href="#collapse-1-1-3">What are we??</a>
          </h6>
          <div id="collapse-1-1-3" class="collapse" data-parent="#accordion-1-1">
            <div class="card-body" style="padding-left: 30px">
              Lorem Ipsum dolor sit amet three.
            </div>
          </div>

          <h6 class="card-title card-inside">
            <a data-toggle="collapse" href="#collapse-1-1-4">What we do?</a>
          </h6>
          <div id="collapse-1-1-4" class="collapse" data-parent="#accordion-1-1">
            <div class="card-body" style="padding-left: 30px">
              Lorem Ipsum dolor sit amet four.
            </div>
          </div>

          <h6 class="card-title card-inside">
            <a data-toggle="collapse" href="#collapse-1-1-5">What you need?</a>
          </h6>
          <div id="collapse-1-1-5" class="collapse" data-parent="#accordion-1-1">
            <div class="card-body" style="padding-left: 30px">
              Lorem Ipsum dolor sit amet five.
            </div>
          </div>
        </div>
      </div>

      <div class="card">
        <h5 class="card-title" style="font-family: 'Raleway Bold'">
          <a class="collapsed" data-toggle="collapse" href="#collapse-1-2">Details</a>
        </h5>

        <div id="collapse-1-2" class="collapse" data-parent="#accordion-1">
          <h6 class="card-title card-inside">
            <a data-toggle="collapse" href="#collapse-1-2-1">How to do ?</a>
          </h6>
          <div id="collapse-1-2-1" class="collapse" data-parent="#accordion-1-2">
            <div class="card-body" style="padding-left: 30px">
              nostro apeirian cu est one
            </div>
          </div>

          <h6 class="card-title card-inside">
            <a data-toggle="collapse" href="#collapse-1-2-2">How it is?</a>
          </h6>
          <div id="collapse-1-2-2" class="collapse" data-parent="#accordion-1-2">
            <div class="card-body" style="padding-left: 30px">
              nostro apeirian cu est two.
            </div>
          </div>

          <h6 class="card-title card-inside">
            <a data-toggle="collapse" href="#collapse-1-2-3">When to do?</a>
          </h6>
          <div id="collapse-1-2-3" class="collapse" data-parent="#accordion-1-2">
            <div class="card-body" style="padding-left: 30px">
              nostro apeirian cu est three.
            </div>
          </div>

          <h6 class="card-title card-inside">
            <a data-toggle="collapse" href="#collapse-1-2-4">Where to do?</a>
          </h6>
          <div id="collapse-1-2-4" class="collapse" data-parent="#accordion-1-2">
            <div class="card-body" style="padding-left: 30px">
              nostro apeirian cu est four.
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

2

Answers


  1. Chosen as BEST ANSWER

    adding this line of code inside the in: if(val.length)

    $(".accordion .card .child-card").hide().filter(function () {
                return $('.card-title', this).text().toLowerCase().indexOf(val.toLowerCase()) > -1 || $('.card-body', this).text().toLowerCase().indexOf(val.toLowerCase()) > -1;
    }).show();
    

    and this inside else:

    $(".accordion .card .child-card").show;
    

    and wrapping the child accordion with another div

    <div class="child-card">
     <h6 class="card-title card-inside">
      <a data-toggle="collapse" href="#collapse-1-2-4">Where to do?</a>
     </h6>
     <div id="collapse-1-2-4" class="collapse" data-parent="#accordion-1-2">
      <div class="card-body" style="padding-left: 30px">
      nostro apeirian cu est four.
     </div>
    </div>
    


  2. I’ve created some code that works as an accordion, allowing a user to open up accordions (and nested accordions).

    Search functionality is also demonstrated, with automatically opening any accordions where the term is found, and their parents.

    The code is fully commented, but let me know if it isn’t clear.

    Thanks to SLaks for the function to find the element’s text without its childrens’ text (link).


    Demonstration

    // Add click event to all .accordian-title
    $(".accordian-title").click(function() {
    
      // Check if this is already active
      wasActive = $(this).closest(".accordian-element").hasClass("active");
    
      // Remove all the .active siblings
      $(this).closest(".accordian-wrapper").find(".accordian-element.active").removeClass("active");
    
      // Activate the clicked .accordian-element if it wasn't active
      if (wasActive != true) {
        $(this).closest(".accordian-element").toggleClass("active");
      }
    
    });
    
    
    // Launch search code after any change to input
    $("#search").on('change keydown paste input', function() {
    
      // Remove search term matching
      $(".accordian-wrapper .found-term").removeClass("found-term");
    
      // Remove all active classes 
      $(".accordian-wrapper .accordian-element.active").removeClass("active");
    
      // Get search term
      searchTerm = $(this).val().toUpperCase();
    
      // Quit if search term is empty
      // IT MIGHT BE A GOOD IDEA TO ADD A MINIMUM 3 CHARACTERS OR SIMILAR
      if (searchTerm == "") {
        $(".accordian-wrapper").removeClass("searched");
        return;
      }
    
      $(".accordian-wrapper").addClass("searched");
    
      // Check anything within an accordian against the term
      $(".accordian-wrapper *").each(function() {
    
        // Get text only of this element (not children)
        tempText = $(this).immediateText().toUpperCase();
    
        // Check if search term is present in element
        if (tempText.indexOf(searchTerm) >= 0) {
    
          // Add found-term to highlight the element with the search text
          $(this).addClass("found-term");
    
          // Activate all parent accordians to that it is visible
          $(this).parents(".accordian-element").addClass("active");
    
        }
    
      });
    
    });
    
    
    // Get text of given element, but not it's children
    // Taken from : https://stackoverflow.com/questions/3442394/using-text-to-retrieve-only-text-not-nested-in-child-tags#answer-32170000
    $.fn.immediateText = function() {
      return this.contents().not(this.children()).text();
    };
    /* Styling to hide and show content on click */
    
    .accordian-content {
      display: none;
    }
    
    .accordian-element.active>.accordian-content {
      display: inherit;
    }
    
    .accordian-title {
      cursor: pointer;
    }
    
    
    /* Styling for searching content and highlighting it */
    
    .accordian-wrapper.searched .accordian-element {
      display: none;
    }
    
    .accordian-wrapper.searched .accordian-element.active {
      display: inherit;
    }
    
    .found-term {
      color: red;
    }
    
    
    /* Just some general styling to make it look nice */
    
    .accordian-wrapper {
      border-left: 5px solid grey;
      border-top: 1px dashed grey;
    }
    
    .accordian-element {
      padding: 10px 0px 10px 20px;
      border-bottom: 1px dashed grey;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    
    Search: <input id="search">
    
    <hr style="margin: 20px 0px;">
    
    <div class="accordian-wrapper">
    
      <div class="accordian-element">
    
        <h4 class="accordian-title">Registering</h4>
        <div class="accordian-content">
    
          <p>This is an explaination text area, because I am not inside the child .accordian-wrapper I am visible when my accoridan-title is clicked!</p>
    
          <div class="accordian-wrapper">
    
            <div class="accordian-element">
              <h4 class="accordian-title">Registration Page</h4>
              <div class="accordian-content">
                <p>The URL to the registration page is '/register.html'</p>
              </div>
            </div>
    
            <div class="accordian-element">
              <h4 class="accordian-title">Registration Form</h4>
              <div class="accordian-content">
                <p>The form requires you to fill out your e-mail, name and phone number.</p>
              </div>
            </div>
    
          </div>
    
        </div>
    
      </div>
    
      <div class="accordian-element">
    
        <h4 class="accordian-title">How do I login?</h4>
        <div class="accordian-content">
          <p>Logging in is easy, you can loging at '/login.html' or use a linked social media account.</p>
        </div>
    
      </div>
    
      <div class="accordian-element">
    
        <h4 class="accordian-title">Some other title</h4>
        <div class="accordian-content">
          <p>Lorem ipsum</p>
        </div>
    
      </div>
    
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search