1

The Goal: To have each menu listed under foreach to be expandable using slideToggle

The Problem: I am able to load my each of my custom taxonomies and custom post type titles (and links), but I do not have a predefined class or id that distinguishes each so when I click on any h4 all li items expand.

Bonus: It would be great if the parent of the .active class (li a.active) would remain open while the rest are closed.

The Question: How do I easily and seamlessly amend the php and/or php script to either allow for custom IDs or classes to make opening and close the toggle better? Or, alternatively, is there a better way to do this?

The PHP

wp_reset_postdata();
$orig_post_id = get_the_ID();
$custom_terms = get_terms('CUSTOM-TAX');

foreach($custom_terms as $custom_term) {
    wp_reset_query();
    $args = array('post_type' => 'CUSTOM-POST-TYPE',
        'tax_query' => array(
            array(
                'taxonomy' => 'CUSTOM-TAX',
                'field' => 'slug',
                'terms' => $custom_term->slug,
            ),
        ),
    ); ?>

    <div class="CUSTOM-NAV-CLASS">
    <?php 
    $loop = new WP_Query($args);
        if($loop->have_posts()) {
            echo '<h4>'.$custom_term->name.'</h4>';
            ?>
            <ol>

            <?php
            while($loop->have_posts()) : $loop->the_post();
                $class = "";
                if ($orig_post_id == get_the_ID()){
                    $class = "active";
                }
                echo '<li><a href="'.get_permalink().'" class="' . $class . '">'.get_the_title().'</a></li>';
            endwhile;
            ?>
            </ol>
            <?php
    }
    ?>
    </div>
    <?php
}
wp_reset_postdata();

The jQuery

$(document).ready(function () {
    $(".CUSTOM-NAV-CLASS li").hide();
    $(".CUSTOM-NAV-CLASS h4").click(function(){
    $(".CUSTOM-NAV-CLASS li").slideToggle();
});

Thank you for your help!

mdnash
  • 81
  • 9

1 Answers1

0

This is a simple example but, basically you'd do something like this in your JQuery:

$(document).ready(function() {

  //*** hiding the panels that you dont want to show until clicked
  $(".container").hide();

  $(".js-hook").click(function() {

    //*** you now want to toggle the panels to slide up/down
    $(this).children(".container").slideToggle();

  });

});

Give all of your parent containers that wrap your h4 and panels a class of something that you can target (js-hook). Then give all of your panels a classname (I used container). Now, when the page loads, you're going to hide() all of the containers and run a click event listener on the js-hook. The key is to use the $(this) target to slideToggle().

Here's a DEMO: http://jsbin.com/tuhayuyoje/edit?html,js,output

In your example, I believe if you changed your JQuery to look like this, you would get what you want:

$(document).ready(function () {
    $(".CUSTOM-NAV-CLASS li").hide();
    $(".CUSTOM-NAV-CLASS h4").click(function(){
    $(this).slideToggle();
});
Brandon
  • 3,074
  • 3
  • 27
  • 44
  • Is it bad practice to target each `ol` rather than create a new `.container`? – mdnash Mar 08 '17 at 22:55
  • I don't understand. It looks like you only have 1 ```
      ```
    – Brandon Mar 08 '17 at 23:05
  • The PHP outputs more than one list based off the number of Wordpress taxonomies I have and more than one list item based off of posts in each tax. Here's a sample I mocked up based off your submission: [http://jsbin.com/cigizebebe/edit?html,js,output](http://jsbin.com/cigizebebe/edit?html,js,output) – mdnash Mar 08 '17 at 23:18
  • 1
    Oh, I think I see what you're saying. I added a wrapper of ```.container``` because you can't click on the ```
      ``` when it's collapsed. So, you wrap your ```h4``` and ```ol``` in a div and put the click event on those. I've altered the JQuery for your example: http://jsbin.com/nezumefagi/edit?html,js,output
    – Brandon Mar 08 '17 at 23:23
  • Thank you! Do you know how to do the second part? I also want any `.collapsable` to remain visible if a child (`li`) has the class `.active` – mdnash Mar 09 '17 at 15:14
  • @mdnash looks like you can use JQuery's ```not``` selector. Something like this should work ```$(".collapsable").not(".active").slideToggle();```. Now, you would have to tweak the examples above to make sure you add that class if you toggle open. See this for more: http://stackoverflow.com/questions/3015103/jquery-exclude-elements-with-certain-class-in-selector – Brandon Mar 09 '17 at 16:38
  • I just figured it out! I added `display:none` to `.collapsable` and then added the following to JS `$('.active').closest('.collapsable').show();`. Does it matter which I use? Is one way better than the other? – mdnash Mar 09 '17 at 16:41
  • @mdnash I would be careful using ```closest()``` because if you were to ever alter your HTML in a way in which you have multiple ```.collapsable```, you're ```closest()``` element could be altered. – Brandon Mar 09 '17 at 17:04