htmljquerydomdynamicparent-child

Open a collapsible parent class on page load when a child class is active


I have an html page with accordion sections with buttons btn-acc-tab. The sections acc-tab open when a user clicks on a button, and each section contains links tab-link that can be active. The sections open and close using the JQuery scripts shown below. I'm trying to have a section acc-tab collapse with a currently active link open when a page loads by adding a class show, not waiting for a user to click. Most answers I could find here deal with activating a show class on click or some other event. Simply substituting event for onload hasn't worked for me. I know I am missing something simple, but I've banged my head on the wall long enough to know that I am not going to see it on my own. Your help will be greatly appreciated.

HTML code:

<div class="container">
    <div class="accordion" id="accordion_Foo">
        <div class="card">
            <div class="card-header" id="heading_Foo_Bar">
                <button class="btn btn-acc-tab" type="button" id="button_Foo_Bar" data-toggle="collapse" data-target="#collapse_Foo_Bar" aria-expanded="true" aria-controls="collapse_Foo_Bar">
                    <h4>Foo Bar</h4>
                </button>
            </div>
            <div class="acc-tab collapse show" id="collapse_Foo_Bar" aria-labeledby="heading_Foo_Bar" data-parent="#accordion_Foo">
                <ul class="tab-list">
                    <li class="btn tab-link active" data-target="Cat" data-id="button_Foo_Bar" tabindex="0" role="button" aria-expanded="true">
                        <a class="active" href="/Foo/Foo_Bar/Cat" target="_self">Cat</a>
                    </li>
                    <span class="sr-only">(current)</span>
                    <li class="btn tab-link" data-target="Dog" data-id="button_Foo_Bar" tabindex="0" role="button" aria-expanded="true">
                        <a class="" href="/Foo/Foo_Bar/Dog" target="_self">Dog</a>
                    </li>
                    <li class="btn tab-link" data-target="Mouse" data-id="button_Foo_Bar" tabindex="0" role="button" aria-expanded="true">
                        <a class="" href="/Foo/Foo_Bar/Mouse" target="_self">Mouse</a>
                    </li>
                </ul>
            </div>
        </div>
        <div class="card">
            <div class="card-header" id="heading_Foo_Foo">
                <button class="btn btn-acc-tab" type="button" id="button_Foo_Bar" data-toggle="collapse" data-target="#collapse_Foo_Foo" aria-expanded="true" aria-controls="collapse_Foo_Foo">
                    <h4>Foo Foo</h4>
                </button>
            </div>
            <div class="acc-tab collapse" id="collapse_Foo_Foo" aria-labeledby="heading_Foo_Foo" data-parent="#accordion_Foo">
                <ul class="tab-list">
                    <li class="btn tab-link active" data-target="Bird" data-id="button_Foo_Foo" tabindex="0" role="button" aria-expanded="true">
                        <a class="active" href="/Foo/Foo_Foo/Bird" target="_self">Bird</a>
                    </li>
                    <span class="sr-only">(current)</span>
                    <li class="btn tab-link" data-target="Fish" data-id="button_Foo_Foo" tabindex="0" role="button" aria-expanded="true">
                        <a class="" href="/Foo/Foo_Foo/Fish" target="_self">Fish</a>
                    </li>
                    <li class="btn tab-link" data-target="Dinosaur" data-id="button_Foo_Foo" tabindex="0" role="button" aria-expanded="true">
                        <a class="" href="/Foo/Foo_Foo/Dinosaur" target="_self">Dinosaur</a>
                    </li>
                </ul>
            </div>
        </div>
    </div>
</div>

jQuery scripts:

(function ($) {
    $.fn.replaceClass = function (pFromClass, pToClass) {
        return this.removeClass(pFromClass).addClass(pToClass);
    };
}(jQuery));
function clickAndPress(event) {
    if(event.type === 'click'){
        return true;
    }
    else if(event.type === 'keypress'){
        var code = event.charCode || event.keyCode;
        if((code === 32)|| (code === 13)){
            return true;
        }
    }
    else{
        return false;
    }
};

$(".tab-link").on("click keypress", function(){
    if(clickAndPress(event) === true) {
        var id = $(this).data('target')
        var par_id = $(this).data('id');
        $(".tab-content").replaceClass("d-block", "d-none");
        $(".sr-only").remove();
        $(document.getElementById(id)).replaceClass("d-none", "d-block");
        $(".tab-link").removeClass("active");
        if ($(".btn-acc-tab").hasClass("active")) {
            $(".btn-acc-tab").removeClass("active");
        };
        $(this).addClass("active");
        $(document.getElementById(par_id)).addClass("active");
        $('<span class="sr-only">(current)</span>').insertAfter(".active");
    }
});
$(document).ready(function(){
    var active = $(".tab-link.active").data('target');
    $(".acc-tab").addClass("show");
});

Also tried jQuery:

$(this).closest(".btn-acc-tab").addClass("active");

UPDATE The question is long, so, to clear things up... The most important thing is to make btn-acc-tab active when a child <li> is active. At the same time, acc-tab must show other <li>s. When an <li> from a different acc-tab / btn-acc-tab is selected, the new parent acc-tab / btn-acc-tab should get show and active and the old ones should lose the same.


Solution

  • I have simplified my answer based on your update and have only given code to do what you want. You need to adjust it alongside your pre-existing code.

    As you said:

    The most important thing is to make btn-acc-tab active when a child <li> is active. At the same time, acc-tab must show other <li>s. When an <li> from a different acc-tab / btn-acc-tab is selected, the new parent acc-tab / btn-acc-tab should get show and active and the old ones should lose the same.

    sample working snippet:

    $(function() {
      $('.tab-list li.active').each(function() {
        $(this).closest('.acc-tab').addClass('show');
        $(this).closest('.card').find('.btn-acc-tab').addClass('active');
      });
      $('.tab-list li').click(function(e) {
        e.preventDefault();
        $('.tab-list li').removeClass('active');
        $('.tab-list li a').removeClass('active');
        $('.acc-tab').removeClass('show');
        $('.btn-acc-tab').removeClass('active');
        $(this).addClass('active');
        $(this).children('a').addClass('active');
        $(this).closest('.acc-tab').addClass('show');
        $(this).closest('.card').find('.btn-acc-tab').addClass('active');
      });
    
    });
    .show {
      background: grey;
    }
    
    .active {
      color: red;
    }
    
    .active a {
      color: red;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <div class="container">
      <div class="accordion" id="accordion_Foo">
        <div class="card">
          <div class="card-header" id="heading_Foo_Bar">
            <button class="btn btn-acc-tab" type="button" id="button_Foo_Bar" data-toggle="collapse" data-target="#collapse_Foo_Bar" aria-expanded="true" aria-controls="collapse_Foo_Bar">
                        <h4>Foo Bar</h4>
                    </button>
          </div>
          <div class="acc-tab collapse " id="collapse_Foo_Bar" aria-labeledby="heading_Foo_Bar" data-parent="#accordion_Foo">
            <ul class="tab-list">
              <li class="btn tab-link active" data-target="Cat" data-id="button_Foo_Bar" tabindex="0" role="button" aria-expanded="true">
                <a class="active" href="/Foo/Foo_Bar/Cat" target="_self">Cat</a>
              </li>
              <span class="sr-only">(current)</span>
              <li class="btn tab-link" data-target="Dog" data-id="button_Foo_Bar" tabindex="0" role="button" aria-expanded="true">
                <a class="" href="/Foo/Foo_Bar/Dog" target="_self">Dog</a>
              </li>
              <li class="btn tab-link" data-target="Mouse" data-id="button_Foo_Bar" tabindex="0" role="button" aria-expanded="true">
                <a class="" href="/Foo/Foo_Bar/Mouse" target="_self">Mouse</a>
              </li>
            </ul>
          </div>
        </div>
        <div class="card">
          <div class="card-header" id="heading_Foo_Foo">
            <button class="btn btn-acc-tab" type="button" id="button_Foo_Bar" data-toggle="collapse" data-target="#collapse_Foo_Foo" aria-expanded="true" aria-controls="collapse_Foo_Foo">
                        <h4>Foo Foo</h4>
                    </button>
          </div>
          <div class="acc-tab collapse" id="collapse_Foo_Foo" aria-labeledby="heading_Foo_Foo" data-parent="#accordion_Foo">
            <ul class="tab-list">
              <li class="btn tab-link active" data-target="Bird" data-id="button_Foo_Foo" tabindex="0" role="button" aria-expanded="true">
                <a class="active" href="/Foo/Foo_Foo/Bird" target="_self">Bird</a>
              </li>
              <span class="sr-only">(current)</span>
              <li class="btn tab-link" data-target="Fish" data-id="button_Foo_Foo" tabindex="0" role="button" aria-expanded="true">
                <a class="" href="/Foo/Foo_Foo/Fish" target="_self">Fish</a>
              </li>
              <li class="btn tab-link" data-target="Dinosaur" data-id="button_Foo_Foo" tabindex="0" role="button" aria-expanded="true">
                <a class="" href="/Foo/Foo_Foo/Dinosaur" target="_self">Dinosaur</a>
              </li>
            </ul>
          </div>
        </div>
      </div>
    </div>