Tabs and Conditional Logic

  • Hi team,

    I am using GenerateBlocks Pro and utilizing a Tabs Block alongside Advanced Display Conditions to create a dynamic size guide pop-up for WooCommerce products.

    My Setup:

    I have one Tabs Block with 3 tabs: Tab 1 (Full Size), Tab 2 (Mini), and Tab 3 (Lunch Bag).

    I have applied Display Conditions to the individual Tab Menu Items and Tab Items so they only show if the current product has the matching category/tag.

    The Issue:
    When a user visits a standalone “Lunch Bag” product, the conditions correctly hide Tabs 1 and 2. Only the Tab 3 button is visible.

    However, because the Tabs block requires a strict “Default Opened Tab” setting (currently set to Tab 1), the content area is completely blank on page load. The system tries to open Tab 1, sees it is hidden, and stops. The customer has to manually click the single Tab 3 button to make the table appear.

    https://postimg.cc/gallery/0JHhf46

    My Question:
    Is there a recommended way (perhaps a PHP snippet or filter) to dynamically set the “Default Opened Tab” to be the first actually visible tab?

    I know I can force Tab 3 open using CSS (display: block !important), or separate the standalone products into a completely different block, but I am wondering if there is a cleaner programmatic way to make the GB Tabs script adapt to conditionally hidden tabs.

    Thanks in advance for the help!

  • Hi S3ratin,

    You’ve diagnosed it correctly. The “Default Opened Tab” setting stores a fixed index, and when display conditions remove that tab server-side, nothing falls back to the first remaining tab — so the content area stays blank until manually clicked. There’s no published PHP filter to override the default opened tab based on display conditions, so a server-side fix isn’t available here.

    The cleanest approach is a small client-side script that runs when the overlay opens, checks whether a tab is already active, and if not, activates the first visible one. Because your tabs live inside an overlay panel, the key detail is that it needs to evaluate after the panel is visible, not on page load — so it uses an IntersectionObserver to wait for the panel to open:

    <script>
    document.addEventListener('DOMContentLoaded', function () {
      const tabs = document.querySelector('.gb-tabs'); // adjust to your block's wrapper class
      if (!tabs) return;
    
      const obs = new IntersectionObserver(function (entries) {
        entries.forEach(function (e) {
          if (!e.isIntersecting) return;
          const active = tabs.querySelector('[role="tab"][aria-selected="true"]');
          if (active && active.offsetParent !== null) return; // a tab is already active, leave it
          const firstVisible = [...tabs.querySelectorAll('[role="tab"]')]
            .find(b => b.offsetParent !== null);
          if (firstVisible) firstVisible.click();
        });
      }, { threshold: 0.01 });
    
      obs.observe(tabs);
    });
    </script>

    This leaves your normal multi-tab pages untouched — it only acts when no tab is active, which is exactly the single-visible-tab case.

    To add it via a GP Hook Element:

    1. Go to Appearance → Elements → Add New Element and choose Hook as the type.
    2. Paste the script (including the <script> tags) into the content area.
    3. Under Settings, set the Hook to wp_footer. This ensures the script loads after the tabs markup is in the page.
    4. Under Display Rules, set the Location to the products (or product category) where the size guide appears, so it only loads where needed.
    5. Publish.
  • Thanks, George. I really appreciate it! I just made a small change to make this script truly scalable in the future, including if I ever add a second Tabs block further down the product page (for example, a separate tab block for “Features” or “Shipping”). The script will no longer ignore it. I changed it to look for all instances of .gb-tabs in case someone else needs it for the same issue

    <script>
    document.addEventListener('DOMContentLoaded', function () {
      // Select ALL tab blocks on the page instead of just the first one
      const allTabsBlocks = document.querySelectorAll('.gb-tabs'); 
      if (allTabsBlocks.length === 0) return;
    
      const obs = new IntersectionObserver(function (entries) {
        entries.forEach(function (e) {
          if (!e.isIntersecting) return;
          
          const tabsWrapper = e.target;
          const active = tabsWrapper.querySelector('[role="tab"][aria-selected="true"]');
          
          // If a tab is already active and visible, do nothing
          if (active && active.offsetParent !== null) return; 
          
          // Find the first visible tab
          const firstVisible = [...tabsWrapper.querySelectorAll('[role="tab"]')]
            .find(b => b.offsetParent !== null);
            
          // Click it to force the content open
          if (firstVisible) firstVisible.click();
        });
      }, { threshold: 0.01 });
    
      // Attach the observer to every tab block found
      allTabsBlocks.forEach(function(tabs) {
          obs.observe(tabs);
      });
    });
    </script>
  • That’s great, you are welcome!

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