[Resolved] Trying to get a button to “toggle” a div (grid)

Home Forums Support [Resolved] Trying to get a button to “toggle” a div (grid)

Home Forums Support Trying to get a button to “toggle” a div (grid)

Viewing 15 posts - 1 through 15 (of 16 total)
  • Author
    Posts
  • #1596215
    Henry

    What I am trying to achieve is when a button is toggled, then a Grid (div) is opened and closed.

    This has been answered here, but I wasn’t able to get it to work…

    The CSS and the Jquery are 100% there…

    Can anyone spot what is wrong with my logic here?

    This is the Grid (with CSS class applied)

    2020-12-28_12-57-55

    This is the Button – and I added the CSS at the button AND div level just to test it, neither worked…

    2020-12-28_13-00-10

    And here:

    2020-12-28_13-01-14

    Thanks for all your help!

    I am sure it is a simple thing?

    #1596218
    Elvin
    Staff
    Customer Support

    Hi,

    I’ve checked your site and it has script related errors on its console.

    WordPress requires jQuery instead of $. Try replacing all of the $ in your script to jQuery.

    Example: (taken from the post you’re referencing, replaced all of the $ to jQuery ).

    jQuery( '.toggle-heading' ).on( 'click', function( e ) {
        e.preventDefault();
    
        jQuery( '.toggle-text' ).removeClass( 'show-text' );
        jQuery( this ).next( '.toggle-text' ).toggleClass( 'show-text' );
    } );

    A wise man once said:
    "Have you cleared your cache?"

    #1596366
    Henry

    Thanks, @Elvin, however, it’s definitely not quite there. Would you mind taking a look? For some reason, the button toggles the grid (via a “div”) but it arranges the icons in a single column?

    When I remove all the JQuery it reverts to how it is meant to.

    Also, I’d like the button to be Show AND Hide – at the moment it just “shows” and then remains open.

    (PS I understand if this is beyond the scope of this support, I am just curious to see if you have an answer).

    #1596394
    Elvin
    Staff
    Customer Support

    Can I offer a different approach?

    You can keep everything else but let’s use pure vanilla JS so we don’t have to bother about jQuery libraries.

    Try this script instead:

    var toggleBtn = document.querySelector('.toggle-heading');
    var toggleTgt = document.querySelector('.toggle-text');
    
    toggleBtn.addEventListener("click", function() {
      toggleTgt.classList.toggle('show-text');
    });

    Here’s a demo of it in action: https://share.getcloudapp.com/5zudjj7b

    A wise man once said:
    "Have you cleared your cache?"

    #1596461
    Henry

    Works great thanks very much @elvin

    One last thing though – any idea why the HTML/GeneratePress layout goes to the single-column format?

    I arranged the icons in a grid with x6 columns…

    I’ve tried to view the source and use the inspector tool but I can’t seem to find where the issue could be

    #1596466
    Elvin
    Staff
    Customer Support

    Ah that’s because you’re toggling from display: none; to display: block; instead of display: flex;

    That said, change this CSS:

    .toggle-text.show-text {
        display: block;
    }

    to this

    .toggle-text.show-text {
        display: flex;
    }

    It should display as you intended. (2×6)

    A wise man once said:
    "Have you cleared your cache?"

    #1596474
    Henry

    Wow! @Elvin

    Fantastic

    Really amazing stuff…thanks again!

    #1597472
    Elvin
    Staff
    Customer Support

    No problem. Glad it works for you. 😀

    A wise man once said:
    "Have you cleared your cache?"

    #2151034
    CPWeb

    Hello,

    Thank you for that post and that code who helped me a lot!

    The first version of the code (jQuery) allows to have multiple “toggle area” on a page (because of ‘next()’ I think).
    Is that possible with the vanilla JS you gave us here?

    Thank you!

    #2152542
    Tom
    Lead Developer
    Lead Developer

    Hi there,

    It really depends on your HTML structure.

    I like using closest() to find the parent and then search for the toggle content inside.

    <div class="container">
        <button>Toggle</button>
        <div>Content</div>
    </div>
    var toggleBtn = document.querySelector('button');
    
    toggleBtn.addEventListener("click", function( event ) {
      const parent = event.target.closest( 'div' );
      const target = parent.querySelector( 'div' );
      target.classList.toggle('show-text');
    });
    #2153665
    CPWeb

    Hello,

    Thanks for your reply.

    This is the HTML structure (that is present many time in the same page):

    <div class="gb-inside-container">
    	<div class="gb-container toggle-heading">
    		<p class="gb-headline gb-headline-text">Block title</p>
    		<span class="gb-button gb-button-text">More</span>
    	</div>
    
    	<div class="gb-container toggle-content">
    		<p class="gb-headline gb-headline-text">Block content</p>
    	</div>
    </div>

    Here is some CSS:

    .toggle-content {
        display: none;
    }
    .toggle-content.show-content {
        display: flex;
    }

    And the JS (with jQuery):

    jQuery( '.toggle-heading' ).on( 'click', function( e ) {
        e.preventDefault();
    
        jQuery( this ).next( '.toggle-content' ).toggleClass( 'show-content' );
    } );

    For the moment, only that solution works.

    #2154866
    Fernando
    Customer Support

    Hi there,

    With your current structure, going by your logic, using this Vanilla JS code should work as well:

    <script>
    var toggleBtn = document.querySelector('.toggle-heading');
    var toggleTgt = document.querySelector('.toggle-content');
    
    toggleBtn.addEventListener("click", function() {
      toggleTgt.classList.toggle('show-text');
    });
    </script>

    Here is a test of the code working from my Test website: https://share.getcloudapp.com/L1uRz72Q

    Hope this helps! Kindly let us know how it goes. 🙂

    If this doesn’t work, may we know how you’re adding your JS code? From my end, I’m adding it through a Hook Element hooked to wp_footer as such: https://share.getcloudapp.com/xQuq9W5g

    #2154941
    CPWeb

    Hi,
    Yes that code works well, but just for the first occurence of my toggle block.
    My problem is that I have many occurences of that block in my page:

    <div class="gb-inside-container">
    	<div class="gb-container toggle-heading">
    		<p class="gb-headline gb-headline-text">Block title 1</p>
    		<span class="gb-button gb-button-text">More</span>
    	</div>
    
    	<div class="gb-container toggle-content">
    		<p class="gb-headline gb-headline-text">Block content 1</p>
    	</div>
    </div>
    <div class="gb-inside-container">
    	<div class="gb-container toggle-heading">
    		<p class="gb-headline gb-headline-text">Block title 2</p>
    		<span class="gb-button gb-button-text">More</span>
    	</div>
    
    	<div class="gb-container toggle-content">
    		<p class="gb-headline gb-headline-text">Block content 2</p>
    	</div>
    </div>
    <div class="gb-inside-container">
    	<div class="gb-container toggle-heading">
    		<p class="gb-headline gb-headline-text">Block title 3</p>
    		<span class="gb-button gb-button-text">More</span>
    	</div>
    
    	<div class="gb-container toggle-content">
    		<p class="gb-headline gb-headline-text">Block content 3</p>
    	</div>
    </div>

    There, second and third blocks can not be opened when clicking on.

    #2154990
    Fernando
    Customer Support

    If that’s the case, here is a JS you may try:

    <script>
    
    document.querySelectorAll('.toggle-heading').forEach(item => {
      item.addEventListener('click', event => {
    		
    		var placeholder = event.target.closest('div').nextElementSibling;
    
    while (placeholder) {
      if (placeholder.classList.contains('toggle-content')) {
        placeholder.classList.toggle('show-text');
        break;
      }
    
      placeholder = placeholder.nextElementSibling;
    }
      })
    })
    
    </script>

    Hope this helps! 🙂

    #2155081
    CPWeb

    Thank you. I made few modifications to obtain a good result. That works!

    I changed var placeholder = event.target.closest('div').nextElementSibling; to var placeholder = item.nextElementSibling;.

    <script>
    document.querySelectorAll('.toggle-heading').forEach(item => {
      item.addEventListener('click', event => {
        var placeholder = item.nextElementSibling;
        while (placeholder) {
          if (placeholder.classList.contains('toggle-content')) {
            placeholder.classList.toggle('show-content');
            break;
          }
    
          placeholder = placeholder.nextElementSibling;
          }
      })
    })
    </script>

    Thank you very much!

Viewing 15 posts - 1 through 15 (of 16 total)
  • You must be logged in to reply to this topic.