New - unofficial - feature: TABS - Hide/Show multiple blocks horizontally

Hi,

This works fine with 2 custom code blocks with embedded content in it (it works with 2 airtable embedded forms, for example).

The ‘html + css + javascript’ is inserted in a first custom code block. So at the end you will have 3 custom code blocks in your page.

Then I named the custom blocks with the two airtable forms => block1 and block2. Everything works fine.

Anything I should know in addition?

Interesting, that’s exactly what I have but it’s not actually functioning.

There must be a mistake on your side, a letter missing, a conflict with another code, something. It can come from a little detail that you missed, unfortunately.

Before I get tucked into this, does it work with list details blocks?

:joy:, yes, as always, it works with all blocks. Just be careful with your conditional filters+ if you have different visibility settings = one tab feature (one tab custom code) by user group.

1 Like

Having trouble with getting it to make columns…in the header code, it says “table” - does this part need to be changed to the blocks I am applying it to?

image

Or maybe something here. It would be helpful to have all the areas that would need to be changed for different blocks highlighted on the page :slight_smile:

This is not the right thread => Lateral tabs feature - "On Start" Tabs - With 2 design versions

To display blocks in the right column => the code inside the footer (page settings)

I’d already changed those, of course. But then again, I don’t have much coding experience. Maybe this isn’t the place for me to learn after all!

You were right :upside_down_face:

I was calling the same block for both buttons. Fixed and it works great again!

Thanks for the code!

PSA: I’ve been using this tutorial as the foundation of TONS of versions on my site now. USE CODEPEN TO PLAY WITH CONFIGS :slight_smile: It’s been a real gamechanger for figuring out how to get it to do tons of different stuff! codepen + chatgpt… the possibilities are endless! I have multiple on one page and figuring out the styling and functionality would have been impossible without codepen :slight_smile: I even figured out how to have it change buttons on one page with several blocks so it’s like an onboarding process! I love this and thank you again @matthieu_chateau <3 !!!

https://codepen.io/danyalamribencr/pen/bGQqpWd ← link to example button block that takes user through onboarding (all blocks live on ONE page! I’m proud of myself heh)
2023-07-05_11-01-38

1 Like

I can see you’re becoming a professional low-coder ! :smirk:
I can see you enjoy it!

Great piece of code :ok_hand: Is it possible to show multiple blocks on button click?

I got quite a few blocks I want to hide and show and for button 3 I want to show multiple blocks:

From your question, I am doing an assumption, you want the click on the "Topics" button to both hide other blocks and show the "topics-list". If that's the case, you can modify the `runButton3Script()` function to make the block with id "topics-list" display as well. Here is the modification:

```html
<!DOCTYPE html>
<html>
<head>
    <style>
        @import url('https://fonts.googleapis.com/css2?family=Inter&display=swap');
        .button-group {
            display: flex;
            justify-content: center;
        }

        .button {
            background-color: #182939;
            color: white;
            font-family: 'Roboto', sans-serif;
            font-size: 16px; 
            padding: 10px 20px; 
            margin-right: 30px;
            padding-top: 9px;
            padding-bottom: 9px;
            border-radius: 14px;
            border: none;
            cursor: pointer;
        }

        .button:active, .active {
            background-color: #0000ff;
            color: #ffff;
            outline: none;
        }
    </style>
</head>
<body>
    <div class="button-group">
        <button class="button active" onclick="runButton1Script()">AI Context</button>
        <button class="button" onclick="runButton2Script()">Personas</button>
        <button class="button" onclick="runButton3Script()">Topics</button>
        <button class="button" onclick="runButton4Script()">Channels & Formats</button>
        <button class="button" onclick="runButton5Script()">Content Ideas</button>
        <button class="button" onclick="runButton6Script()">Content Inbox</button>
    </div>
    <script>
        const buttons = document.querySelectorAll('.button');
        buttons.forEach(button => {
            button.addEventListener('click', function() {
                buttons.forEach(b => b.classList.remove('active'));
                this.classList.add('active');
            });
        });
    </script>
</body>
<script>
    // hide blocks 
    window.addEventListener('DOMContentLoaded', (event) => {
        hideAllExcept("ai-context");
    });

    function hideAllExcept(showId) {
        const allIds = ["ai-context", "personas", "topics", "channels-formats", "content-ideas", "content-inbox"];
        allIds.forEach(id => {
            const elem = document.getElementById(id);
            elem.style.display = id === showId? "block" : "none";
        });
    }

    function runButton1Script() {
        hideAllExcept("ai-context");
        console.log("AI Context clicked");
    }

    function runButton2Script() {
        hideAllExcept("personas");
        console.log("Personas clicked");
    }

    function runButton3Script() {
        hideAllExcept("topics");
        // Additional code to display "topics-list".
        document.getElementById("topics-list").style.display = 'block';
        console.log("Topics clicked");
    }

    function runButton4Script() {
        hideAllExcept("channels-formats");
        console.log("Channels & Formats clicked");
    }

    function runButton5Script() {
        hideAllExcept("content-ideas");
        console.log("Content Ideas clicked");
    }

    function runButton6Script() {
        hideAllExcept("content-inbox");
        console.log("Content Inbox clicked");
    }

</script>
</html>

Just remember to add the “topics-list” div in the HTML structure.

Hi,
Yes this is possible to show or hide mutliple blocks when clicking one button or another

It worked and looked great initially but upon changing things in the Softr builder, it often breaks the code.
There seems to be some bug here since I didn’t change the naming of any block, but simply removing one block suddenly breaks the code, meaning that when I load the page, blocks that should be hidden are displayed. Am I the only one it happens to?

Hi!
There might be an error on your end, somewhere. It still works fine. All my blocks are updated and everything is fine with it, same for all the apps of my clients.

A clear understading of the code is necessary if changes are made in the page (block removal, Block ID changes or anything else). Careful with it. Maintaining a code is part of the jobs to be done but this one is mostly free of it (unless you use some cssXXXX selectors somewhere).

Please re-check carefully, if there are some changes to do. If you can’t find it => DM me.

1 Like

I will just mention in case anyone experiences this: I have this implemented across several pages. When I went onsite to start rolling out to my users, a handful of people (limited time from them, so I was unable to do troubleshooting to diagnose) were experiencing the breaking of this block in a similar way to what ob95 reported.

I had the same URL on my laptop → display perfectly fine. Sitting next to another colleague’s laptop, same browser, same URL, button block completely broken (all blocks displayed on page simeltaneously). We refreshed multiple times with same result. I just walked away thinking WTF, hope not too many random other users have this bug… 'Cause I have no clue why it would not work for some and not others! With all my other bugs, I’m cool leaving this mystery unsolved for now :sweat_smile:

First of all, thank you very much. This is such an interesting approach.

I would like to know, if it is possible to do this with the Header buttons?

Thank you very much.

Hi!

Yes this is possible => https://test-play.softr.app/tabs-with-header

Note that I use the element “buttons” in the header in the Softr studio, not the element “links”, the first being easier to select in the code.

The code to insert in the header (page settings - custom code)

<style>
  #header1 a[data-element="button"] {
    background-color: #f5f5f5;
    color: #333;
  }

  #header1 a[data-element="button"].active,
  #header1 a[data-element="button"]:hover,
  #header1 a[data-element="button"].active:hover {
    background-color: #ff0000;
    color: #fff;
  }
</style>

The code to be inserted in the footer (page settings - custom code):

<script>
  window.addEventListener('DOMContentLoaded', (event) => {
    document.getElementById("table1").style.display = "block";
    document.getElementById("form1").style.display = "none";
    document.getElementById("chart1").style.display = "none";
    document.querySelector('#header1 a[data-element="button"]:nth-child(1)').classList.add('active');
  });

  window.addEventListener('block-loaded-header1', () => {
    console.log('Header1 Block loaded');

    const buttonClickHandler = (e) => {
      const button = e.target.closest('#header1 a[data-element="button"]');
      if (button) {
        e.preventDefault();
        const activeButton = document.querySelector('#header1 a[data-element="button"].active');
        if (button !== activeButton) {
          activeButton.classList.remove('active');
          button.classList.add('active');
          const buttonIndex = Array.from(button.parentNode.children).indexOf(button) + 1;
          if (buttonIndex === 1) {
            document.getElementById("table1").style.display = "block";
            document.getElementById("form1").style.display = "none";
            document.getElementById("chart1").style.display = "none";
          } else if (buttonIndex === 2) {
            document.getElementById("form1").style.display = "block";
            document.getElementById("table1").style.display = "none";
            document.getElementById("chart1").style.display = "none";
          } else if (buttonIndex === 3) {
            document.getElementById("chart1").style.display = "block";
            document.getElementById("form1").style.display = "none";
            document.getElementById("table1").style.display = "none";
          }
        }
      }
    };

    document.body.addEventListener('click', buttonClickHandler);
  });
</script>

If you want something without the hover and active states for buttons, just insert this code in the footer (page settings - custom code):

<script>
    window.addEventListener('DOMContentLoaded', (event) => {
        document.getElementById("table1").style.display = "block";
        document.getElementById("form1").style.display = "none";
        document.getElementById("chart1").style.display = "none"
    });

    window.addEventListener('block-loaded-header1', () => {
        console.log('Header1 Block loaded');

        const buttonClickHandler = (e) => {
            if (e.target.closest('#header1 a[data-element="button"]:nth-child(1)')) {
                console.log('Click Button 1');
                document.getElementById("table1").style.display = "block";
                document.getElementById("form1").style.display = "none";
                document.getElementById("chart1").style.display = "none";
            }
            if (e.target.closest('#header1 a[data-element="button"]:nth-child(2)')) {
                console.log('Click Button 2');
                document.getElementById("form1").style.display = "block";
                document.getElementById("table1").style.display = "none";
                document.getElementById("chart1").style.display = "none";
            }
            if (e.target.closest('#header1 a[data-element="button"]:nth-child(3)')) {
                console.log('Click Button 3');
                document.getElementById("chart1").style.display = "block";
                document.getElementById("form1").style.display = "none";
                document.getElementById("table1").style.display = "none";
            }
        };
        
        document.body.addEventListener('click', buttonClickHandler);
    });

</script>

Hi @matthieu_chateau , thanks a lot for the code, I have used it into my app and it is great!!! I used a summary card in the third one instead of the chart.

1 Like