Search code examples
jquerywordpressanchoraccordion

Open Accordion Item Based on #target in URL - Wordpress Menu


I have an accordion that has three content areas. I want to activate the relative accordion when someone clicks on a menu item that has an anchor appended to the url (/expertise#target). The way my accordion is set up, it adds .show to the panel .panel that is clicked on the title element .panelTrigger. I am trying to figure out how to connect the triggering based on the #target on the end of the url. Another issue, is that wordpress is adding a / before the hash.

HTML

<div class="accordion" id="accordion">
<?php if (have_rows('accordion')) {
$count = 0;
while (have_rows('accordion'))  { the_row(); $count++; ?>
        <div class="parentPanel item-<?php echo $count; ?>">
             <a class="panelTrigger" href="#<?php the_sub_field('accordion_title'); ?>"><?php the_sub_field('accordion_title'); ?></a>

                <div class="panel" id="<?php the_sub_field('accordion_title'); ?>">
                    <div class="greenLine"></div>
                    <?php the_sub_field('accordion_content'); ?>

                    <?php if (have_rows('accordion_logos')) {
                        echo ' <h3>CREDENTIALS</h3><div class="logos">';
                        while (have_rows('accordion_logos')) { the_row(); ?>

                            <img src="<?php the_sub_field('logo'); ?>"/>
                  <?php }
                    echo '</div>';
                    } ?>

        </div>

JS

$('.accordion > .parentPanel:last-of-type > .panel').css('display','block');


$('.panelTrigger').click(function(e) {
    e.preventDefault();

    let $this = $(this);

    if ($this.next().hasClass('show')) {
        $this.next().removeClass('show');
        $this.next().slideUp(350);
    } else {
        $this.parent().parent().find('.panel').removeClass('show');
        $this.parent().parent().find('.panel').slideUp(350);
        $this.next().toggleClass('show');
        $this.next().slideToggle(350);
    }
});

$('.panelTrigger').bind('click',function(){
    var self = this;
    setTimeout(function() {
        theOffset = $(self).offset();
        $('body,html').animate({ scrollTop: theOffset.top - 180 });
    }, 310); // ensure the collapse animation is done
});

I know this is possible, just have to figure out how to connect the trigger or add .show to the #target panel. Thanks!


Solution

  • You can get value after hash when your page loads and then using this value simply add show class to panel and toggle same.

    Demo Code :

    $(document).ready(function() {
      //let url = window.location.hash.substr(1)
      //var to_open = "#" + url;
      //this is just for demo...
      let url = "www.someth.com/somehtins#xyz";
      var to_open = "#" + url.split('#')[1];
      $(to_open).prev().addClass('active')
      $(to_open).addClass("show") //add class where id matches
      $(to_open).slideToggle(350); //show that
    })
    .panel {
      display: none
    }
    
    .active {
      color: red
    }
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
    <div class="accordion" id="accordion">
      <div class="parentPanel item-1">
        <a class="panelTrigger" href="#abc">
        Soemthing..
        </a>
    
        <div class="panel" id="abc">
          <div class="greenLine"></div>
          <img src="<?php the_sub_field('logo'); ?>" />
        </div>
    
        <div class="parentPanel item-2">
          <a class="panelTrigger" href="#xyz">
           Soemthings xyz
          </a>
    
          <div class="panel" id="xyz">
            <div class="greenLine"></div>
            xyzz
            <img src="<?php the_sub_field('logo'); ?>" />
          </div>
        </div>