-
S3ratin
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!
-
George
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:
- Go to Appearance → Elements → Add New Element and choose Hook as the type.
- Paste the script (including the
<script>tags) into the content area. - Under Settings, set the Hook to
wp_footer. This ensures the script loads after the tabs markup is in the page. - Under Display Rules, set the Location to the products (or product category) where the size guide appears, so it only loads where needed.
- Publish.
-
S3ratin
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> -
George
That’s great, you are welcome!
- You must be logged in to reply to this topic.