js Поиск слов по аккордеону

прошу помощи по js

Как сделать раскрытие аккордеон по поиску слова? То есть у нас есть поле поиска, на пример мы вводим слово "one", если в каком то аккордеоне имеется данное слово или выражение аккордеон открывает, а слово присваивает тэг strong/b

Пример кода:

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>

<form method="" class="px-3 mt-3 mb-4">
  <input type="text" id="search" name="search">
  <input type="submit" value="search">
</form>

<div class="accordion" id="">
  <div class="card">
<div class="card-header" id="headingOne">
  <h2 class="mb-0">
    <button class="btn btn-link" type="button" data-toggle="collapse" data-target="#collapseOne" aria-expanded="false" aria-controls="collapseOne">
      Collapsible Group Item #1
    </button>
  </h2>
</div>

<div id="collapseOne" class="collapse" aria-labelledby="headingOne">
  <div class="card-body">
    one
  </div>
</div>
  </div>
  <div class="card">
<div class="card-header" id="headingTwo">
  <h2 class="mb-0">
    <button class="btn btn-link collapsed" type="button" data-toggle="collapse" data-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
      Collapsible Group Item #2
    </button>
  </h2>
</div>
<div id="collapseTwo" class="collapse" aria-labelledby="headingTwo">
  <div class="card-body">
    two
  </div>
</div>
  </div>
  <div class="card">
<div class="card-header" id="headingThree">
  <h2 class="mb-0">
    <button class="btn btn-link collapsed" type="button" data-toggle="collapse" data-target="#collapseThree" aria-expanded="false" aria-controls="collapseThree">
      Collapsible Group Item #3
    </button>
  </h2>
</div>
<div id="collapseThree" class="collapse" aria-labelledby="headingThree">
  <div class="card-body">
    one three
  </div>
</div>
  </div>
</div>

Так же код на jsfiddle: https://jsfiddle.net/synapse3/voq4gfc2/7/


Ответы (1 шт):

Автор решения: Tilea Website

Может кому-то, когда-то понадобится, вот готовое решение: https://jsfiddle.net/synapse3/wo6j32ex/17/

$('#find').click(function(){
    var btn = $(this);
    btn.prop("disabled",true);  //__________________________________________________________ disable the button, otherwise clicking fast will cause bugs due to the animation times
    var term = $('#term').val(); //_________________________________________________________ get the search term from the input
    $('.collapse').collapse("hide"); //_____________________________________________________ colapse all the sections
    var rd = new RegExp('<span class="found">('+term+')<\/span>', "ig"); //_________________ remove anything we might have found with a previous search
    $('#accordion-faq').html( $('#accordion-faq').html().replace(rd, '$1' ) ); 
    var occurences=[]; //___________________________________________________________________ this array will hold the idexes of any sections we find our search term in 
    $('#accordion-faq .panel-body').each(function(i,e){ //_____________________________________ loop through each section looking for our term
        var r = new RegExp('('+term+')', "ig"); //__________________________________________ create a regex from our term 
        if( $(this).html().match(r) ){ 
            var matches = $(this).html().match(r); //_______________________________________ get all the matches 
            $.each(matches, function(){ //__________________________________________________ loop through them
                occurences.push(i); //______________________________________________________ push the index of this section `$('#accordion-faq .panel-body')` onto the array 
            });
            $(this).html( $(this).html().replace(r, '<span class="found">$1</span>') ); //__ wrap each found search term with our `found` span to highlight it 
        }
    });
    var l =occurences.length; //____________________________________________________________ get how many matches we found
    var c = Number( $('#current').html() ); //______________________________________________ get the currentlly viewed match 
        c =  c > 0 ? c+1: 0; //_____________________________________________________________ if we are currently viewing a match, increment so we move to the next one 
        c =  c > l ? 1 : c; // _____________________________________________________________ if the incremented number is higher than the number of matches, reset it to 0
        c =  c == 0 && l > 0 ? 1 : c ; //___________________________________________________ if this is the first click and we found matches, set current to the first match
    $('#count').html( l > 0 ? ' of '+ l : ' matches found in document');  //________________ set the text for our number of matches found  
    $('#current').html( c ); // ____________________________________________________________ set the text for the currently viewed match 
    if(c != 0){
        $('#accordion-faq .titlecollapse').eq( occurences[c-1] ).click();//_________________ open the section holding the currently viewed match using the indexes we stored earlier
        $('.found').eq(c-1).focus();//________________________________________________________ set focus to the currently viewed match
    }
    setTimeout(function() { btn.prop("disabled",false); }, 1000); //________________________ set a timmer to re-enable the button, this gives the animations time to playout, otherwise bugs will occur and multiple setcions will stay open if the user clicks fast
});

// _________________________________________________________________________________________ reset everything if the user starts typing again
$('#term').keydown(function(){
    var term = $('#term').val(); //_________________________________________________________ get the search term from the input
    var rd = new RegExp('<span class="found">('+term+')<\/span>', "ig"); //_________________ remove anything we might have found with a previous search
    $('#accordion-faq').html( $('#accordion-faq').html().replace(rd, '$1' ) ); 
    $('#count').html(''); // reset our labels
    $('#current').html('');
});
.found{
  background-color:yellow;
  font-size:16px;
}
#labels{
  margin-left:15px;
  font-size:16px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"></script>

<input type="text" id="term" placeholder="search.."/>
<input type="button" id="find" value="Find"/>
<div id="labels">
  <span id="current"></span><span id="count"></span>
</div>

<div class="accordion" id="accordion-faq">

  <div class="titlecollapse" data-toggle="collapse" data-target="#accordion1" aria-expanded="false"> Sample heading one </div>
  <div id="accordion1" class="collapse">
    <div class="panel-body">
      <p>Cool sample paragraph one</p>
    </div>
  </div>  

  <div class="titlecollapse" data-toggle="collapse" data-target="#accordion2" aria-expanded="false">Sample heading two</div>
  <div id="accordion2" class="collapse">
    <div class="panel-body">
      <p>Cool sample paragraph two</p>
    </div>
  </div>  

  <div class="titlecollapse" data-toggle="collapse" data-target="#accordion3" aria-expanded="false">Sample heading three</div>
  <div id="accordion3" class="collapse">
    <div class="panel-body">
      <p>Cool sample paragraph one</p>
    </div>
  </div>  

  <div class="titlecollapse" data-toggle="collapse" data-target="#accordion4" aria-expanded="false">Sample heading four</div>
  <div id="accordion4" class="collapse">
    <div class="panel-body">
      <p>Cool sample paragraph two cool</p>
    </div>
  </div>  
    
</div>

→ Ссылка