Update to unofficial Tabs feature: Full customizable buttons + Responsive

Hi,

Can you show the script you use?
Thanks

Yes. I don’t know anything about coding and only a little HTML and CSS, but I tried to follow the logic of your code and expand on that. Here is the code for the top buttons:

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

        .buttonx1 {
            background-color: #C2C2C2;
            color: white;
            font-family: 'Inter', sans-serif;
            font-size: 1rem; 
            padding: 10px 20px; 
            margin-right: 15px;
            padding-top: 8px;
            padding-bottom: 8px;
            border-radius: 0.5rem;
            border: none;
            cursor: pointer;
        }
        
        .buttonx1:hover {
        background-color: #FFA500;
        color: white;
       }
        
        .buttonx1:focus {
        outline: none;
       }

        .buttonx1:active, .active {
            background-color: #FFA500;
            color: white;
            outline: none;
        }

        @media (max-width: 480px) {
            .buttonx1-group {
                display: flex;
                flex-direction: column;
                align-items: flex-start;
            }

            .buttonx1 {
                display: none;
            }

            .dropdownx1 {
                display: block;
                width: 100%;
                margin-top: 10px;
                padding: 10px 20px; 
                border-radius: 0.5rem;
                border: none;
                background-color: #C2C2C2;
                color: white;
                font-family: 'Inter', sans-serif;
                font-size: 1rem;
                cursor: pointer;
            }
        }

        @media (min-width: 481px) {
            .buttonx1-group {
                display: flex;
                justify-content: center;
            }

            .dropdownx1 {
                display: none;
            }
        }
    </style>
</head>
<body>
    <div class="buttonx1-group">
        <buttonx1 class="buttonx1 active" onclick="runButtonX11Script()">Details</buttonx1>
        <buttonx1 class="buttonx1" onclick="runButtonX12Script()">Preparation</buttonx1>
        <buttonx1 class="buttonx1" onclick="runButtonX13Script()">Resources</buttonx1>
        <buttonx1 class="buttonx1" onclick="runButtonX14Script()">Tags</buttonx1>
        <select class="dropdownx1" onchange="runDropdownX1Script(this.value)">
            <option value="buttonx11">Details</option>
            <option value="buttonx12">Preparation</option>
            <option value="buttonx13">Resources</option>
            <option value="buttonx14">Tags</option>
        </select>
    </div>
    <script>
        const buttonx1s = document.querySelectorAll('.buttonx1');
        buttonx1s.forEach(buttonx1 => {
            buttonx1.addEventListener('click', function() {
                buttonx1s.forEach(b => b.classList.remove('active'));
                this.classList.add('active');
            });
        });

        function runDropdownX1Script(value) {
            switch(value) {
                case 'buttonx11':
                    runButtonX11Script();
                    break;
                case 'buttonx12':
                    runButtonX12Script();
                    break;
                case 'buttonx13':
                    runButtonX13Script();
                    break;
                case 'buttonx14':
                    runButtonX14Script();
                    break;
                default:
                    break;
            }
        }
    </script>
</body>
</html>

<script>
    // hide blocks 
    window.addEventListener('DOMContentLoaded', (event) => {
        document.getElementById("details").style.display = "block";
        document.getElementById("preparation").style.display = "none";
        document.getElementById("menu2").style.display = "none";
        document.getElementById("linked-tags").style.display = "none"
    });

    function runButtonX11Script() {
        document.getElementById("details").style.display = "block";
        document.getElementById("preparation").style.display = "none";
        document.getElementById("menu2").style.display = "none";
        document.getElementById("linked-tags").style.display = "none";
        console.log("Details clicked"); 
    }

         function runButtonX12Script() {
        document.getElementById("preparation").style.display = "block";
        document.getElementById("details").style.display = "none";
        document.getElementById("menu2").style.display = "none";
        document.getElementById("linked-tags").style.display = "none";
        console.log("Preparation clicked");
    }
          function runButtonX13Script() {
        document.getElementById("menu2").style.display = "block";
        document.getElementById("details").style.display = "none";
        document.getElementById("preparation").style.display = "none";
        document.getElementById("linked-tags").style.display = "none";
        console.log("menu2 clicked");
    }
          function runButtonX14Script() {
        document.getElementById("linked-tags").style.display = "block";
        document.getElementById("details").style.display = "none";
        document.getElementById("preparation").style.display = "none";
        document.getElementById("menu2").style.display = "none";
        console.log("linked-tags clicked");
    }

</script>
</html>

And this is the code for the code block called “menu2”:

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

        .buttonx2 {
            background-color: white;
            color: grey;
            font-family: 'Inter', sans-serif;
            font-size: 0.6rem; 
            padding: 10px 20px; 
            margin-right: 15px;
            padding-top: 8px;
            padding-bottom: 8px;
            border-radius: 0.5rem;
            border: 1px solid grey;
            cursor: pointer;
        }
        
        .buttonx2:hover {
        background-color: grey;
        color: white;
       }
        
        .buttonx2:focus {
        outline: none;
       }

        .buttonx2:active {
            background-color: grey !important;
            color: white;
            outline: none;
        }

        @media (max-width: 480px) {
            .buttonx2-group {
                display: flex;
                flex-direction: column;
                align-items: flex-start;
            }

            .buttonx2 {
                display: none;
            }

            .dropdownx2 {
                display: block;
                width: 100%;
                margin-top: 10px;
                padding: 10px 20px; 
                border-radius: 0.5rem;
                border: none;
                background-color: #C2C2C2;
                color: white;
                font-family: 'Inter', sans-serif;
                font-size: 1rem;
                cursor: pointer;
            }
        }

        @media (min-width: 481px) {
            .buttonx2-group {
                display: flex;
                justify-content: center;
            }

            .dropdownx2 {
                display: none;
            }
        }
    </style>
</head>
<body>
    <div class="buttonx2-group">
        <buttonx2 class="buttonx2 active" onclick="runButtonX21Script()">Linked Resources</buttonx2>
        <buttonx2 class="buttonx2" onclick="runButtonX22Script()">Associated Resources</buttonx2>
        <buttonx2 class="buttonx2" onclick="runButtonX23Script()">Resource Library</buttonx2>
        <select class="dropdownx2" onchange="runDropdownX2Script(this.value)">
            <option value="buttonx21">Linked Resources</option>
            <option value="buttonx22">Associated Resources</option>
            <option value="buttonx23">Resource Library</option>
        </select>
    </div>
    <script>
        const buttonx2s = document.querySelectorAll('.buttonx2');
        buttonx2s.forEach(buttonx2 => {
            buttonx2.addEventListener('click', function() {
                buttonx2s.forEach(b => b.classList.remove('active'));
                this.classList.add('active');
            });
        });

        function runDropdownX2Script(value) {
            switch(value) {
                case 'buttonx21':
                    runButtonX21Script();
                    break;
                case 'buttonx22':
                    runButtonX22Script();
                    break;
                case 'buttonx23':
                    runButtonX23Script();
                    break;
                default:
                    break;
            }
        }
    </script>
</body>
</html>

<script>
    // hide blocks 
    window.addEventListener('DOMContentLoaded', (event) => {
        document.getElementById("linked-resources").style.display = "none";
        document.getElementById("associated-resources").style.display = "none";
        document.getElementById("resource-library").style.display = "none"
    });

    function runButtonX21Script() {
        document.getElementById("linked-resources").style.display = "block";
        document.getElementById("associated-resources").style.display = "none";
        document.getElementById("resource-library").style.display = "none";
        console.log("Linked Resources clicked"); 
    }

         function runButtonX22Script() {
        document.getElementById("associated-resources").style.display = "block";
        document.getElementById("linked-resources").style.display = "none";
        document.getElementById("resource-library").style.display = "none";
        console.log("Associated Resources clicked");
    }
          function runButtonX23Script() {
        document.getElementById("resource-library").style.display = "block";
        document.getElementById("linked-resources").style.display = "none";
        document.getElementById("associated-resources").style.display = "none";
        console.log("Resource Library clicked");
    }

</script>
</html>

Thank you!

There could be a better way to write the whole code (everything in one script), but it will get the job done => Replace the last script of your first custom code block (top buttons) by:

<script>
    // hide blocks 
    window.addEventListener('DOMContentLoaded', (event) => {
        document.getElementById("details").style.display = "block";
        document.getElementById("preparation").style.display = "none";
        document.getElementById("menu2").style.display = "none";
        document.getElementById("linked-tags").style.display = "none";
        document.getElementById("linked-resources").style.display = "none";
        document.getElementById("associated-resources").style.display = "none";
        document.getElementById("resource-library").style.display = "none"
    });

    function runButtonX11Script() {
        document.getElementById("details").style.display = "block";
        document.getElementById("preparation").style.display = "none";
        document.getElementById("menu2").style.display = "none";
        document.getElementById("linked-tags").style.display = "none";
        document.getElementById("linked-resources").style.display = "none";
        document.getElementById("associated-resources").style.display = "none";
        document.getElementById("resource-library").style.display = "none";
        console.log("Details clicked"); 
    }

         function runButtonX12Script() {
        document.getElementById("preparation").style.display = "block";
        document.getElementById("details").style.display = "none";
        document.getElementById("menu2").style.display = "none";
        document.getElementById("linked-tags").style.display = "none";
        document.getElementById("linked-resources").style.display = "none";
        document.getElementById("associated-resources").style.display = "none";
        document.getElementById("resource-library").style.display = "none";
        console.log("Preparation clicked");
    }
          function runButtonX13Script() {
        document.getElementById("menu2").style.display = "block";
        document.getElementById("details").style.display = "none";
        document.getElementById("preparation").style.display = "none";
        document.getElementById("linked-tags").style.display = "none";
        document.getElementById("linked-resources").style.display = "none";
        document.getElementById("associated-resources").style.display = "none";
        document.getElementById("resource-library").style.display = "none";
        console.log("menu2 clicked");
    }
          function runButtonX14Script() {
        document.getElementById("linked-tags").style.display = "block";
        document.getElementById("details").style.display = "none";
        document.getElementById("preparation").style.display = "none";
        document.getElementById("menu2").style.display = "none";
        document.getElementById("linked-resources").style.display = "none";
        document.getElementById("associated-resources").style.display = "none";
        document.getElementById("resource-library").style.display = "none";
        console.log("linked-tags clicked");
    }

</script>

Wow, that works like a charm! Thanks so much for your speedy help, I really appreciate it!

1 Like

Important update

This is true for the tab feature as well as for any other custom code using javascript.

From now on, as blocks load faster than the footer code is being executed, all javascript codes should be inside the header custom code of the page level (same for app level by the way), unless a third party tool tells you to insert a code in the footer.

There might be some exceptions but as soon as you use window.addEventListener('block-loaded-BLOCKID', () => { in a code => header.
As soon as you use javascript that should be run on page load => header.

Otherwise the script might work 50 to 70% of the time… Which is not ideal.

1 Like

That’s good to know, thanks so much!

That’s informative read!! Great job :+1:

I just started seeing this issue so glad I came across this, good info.