Hi all! Great news!
I managed to create an unofficial (Strictly done by myself: not the responsibility of Softr) tabs feature for Softr. A big thanks to Artur who helped me (at late nightđ) to improve my javascript snippet!
For those who donât know what are tabs, and everybody else, Letâs not spoil it more than it needs. The demo is here: https://test-play.softr.app/hide-show-tabs?recordId=recZV04ZNE3pvMnKM
Everything is made with a CTA block with 3 buttons (you can have as many as you want), a JS snippet and the blocks I wanted to display. Nothing more.
Explanation
1) The Tabs
Made of one CTA block + one custom javascript inside a custom code block. Nothing more.
You can add or retrieve as many buttons as you want in your CTA block, you will just need to adapt the code accordingly.
To display blocks inside tabs, just add them vertically in the Softr studio. Donât worry, they wonât appear one below another in live environment. As an example, here is my setup in the Softr studio (see screenshot at the end of the post).
To activate a part of the JS code you will need to add a âscroll to sectionâ action to all of your CTA buttons. This scroll to section action will be set to scroll to the CTA itself.
The JS snippet is the following one, to be inserted in a custom code block (reduce the padding top and the padding bottom of this block to the almost minimum to make it disappear, visually, from your page)
<script>
// hide blocks
window.addEventListener('DOMContentLoaded', (event) => {
document.getElementById("table1").style.display = "block";
document.getElementById("form1").style.display = "none";
document.getElementById("chart1").style.display = "none"
});
// This is being called when CTA block is rendered
window.addEventListener('block-loaded-cta3', () => {
console.log('CTA Block loaded');
// function for button click handler
const buttonClickHandler = (e) => {
if (e.target.closest('#cta3 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('#cta3 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('#cta3 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>
Here, The first tab is not hidden on load, as it is quite classic from a UX point that the first tab should be visible. Of course if you want everything to be hidden, itâs possible by writing document.getElementById(âtable1â).style.display = ânoneâ instead of âblockâ.
The result will be this: https://test-play.softr.app/tab-features-only
Note that you can also use a JS snippet using Jquery. There will be a slight difference: you will be able to hide and show every block by clicking and re-clicking on the corresponding button + a nice slide effect.
The result will be this: https://test-play.softr.app/jquery-tabs-feature
<script>
// hide blocks
window.addEventListener('DOMContentLoaded', (event) => {
document.getElementById("table2").style.display = "none";
document.getElementById("form2").style.display = "none";
document.getElementById("chart2").style.display = "none";
});
// This is being called when CTA block is rendered
window.addEventListener('block-loaded-cta1', () => {
console.log('CTA Block loaded');
// function for button click handler
const buttonClickHandler = (e) => {
if (e.target.closest('#cta1 a[data-element="button"]:nth-child(1)')) {
console.log('Click Button 1');
$("#table2").toggle("slow");
if ($("#form2:visible").lenght);
$("#form2").hide();
if ($("#chart2:visible").lenght);
$("#chart2").hide();
}
if (e.target.closest('#cta1 a[data-element="button"]:nth-child(2)')) {
console.log('Click Button 2');
$("#form2").toggle("slow");
if ($("#table2:visible").lenght);
$("#table2").hide();
if ($("#chart2:visible").lenght);
$("#chart2").hide();
}
if (e.target.closest('#cta1 a[data-element="button"]:nth-child(3)')) {
console.log('Click Button 3');
$("#chart2").toggle("slow");
if ($("#form2:visible").lenght);
$("#form2").hide();
if ($("#table2:visible").lenght);
$("#table2").hide();
}
};
//
document.body.addEventListener('click', buttonClickHandler);
});
</script>
2) âOne pageâ apps enabled
The page with some fake projects (https://test-play.softr.app/hide-show-tabs?recordId=recZV04ZNE3pvMnKM) should take your attention as the list block and the list details block are inverted.
And everytime you reload the page, the same recordId in the Url parameter appears. This solution was found by David Coletta.
Here is the setup: add a list block of your choice. Below, add a list details block of your choice. In the custom code header of the page add this code:
<script>
if (!window.location.href.includes("/r/rec")) {
const urlParams = new URLSearchParams(window.location.search);
const recordId = urlParams.get('recordId');
if (!recordId) {
urlParams.set('recordId', "recZV04ZNE3pvMnKM")
window.history.replaceState({}, '', `${location.pathname}?${urlParams}`);
}
}
</script>
You will need to change ârecZV04ZNE3pvMnKMâ by the recordId you want to be shown each time a page is reloaded. That way, even if the user would land on the page without any recordId⌠The page would have one!
To find the ID of a record: go to your corresponding table in Airtable and add a formula field. Enter RECORDID() and thatâs it, all the records will have their ID visible.
Another thing: you can see that the blocks displayed in the Tabs have different data according to the project you select. Pretty easy to do: you just have to use the right conditional filters, linked to the list details block! Do just like the tabs feature didnât exist, the Softr pattern still works!
At the end, you will have a full project management with one page in Softr (add the page for data details in a modal, still a one page app from a final user perspective)
3) Leverage button clicks on your Softr app
Beyond giving you the ability to create a tabs feature, now you know how you can handle buttons of a CTA in Softr. So, be imaginative, other use cases can be found.
4) Be imaginative X Javascript = huge possibilities
Talking about being imaginative, all this shows you that even if Softr can be limited some times, some ânot so bigâ workarounds can be found to improve it greatly.
Softr will have more and more long awaited features in the next months. Though, I strongly believe that our use of Softr will become more and more advanced. Javascript will always be needed
You can also use hardcoded buttons inserted in a custom code block.
Here is the thread related to tabs feature + hardcoded buttons: Update to unofficial Tabs feature: Full customizable buttons + Responsive
If something unclear, just ask.