Custom Code for Headings on List Details

Hi there, I’d like to know if you can use custom code to provide a drop-down or pop-up definition for each list item field heading.

I have a list overview page with several metrics and I want to be able to make it easier for the user to understand the definition of the metric they are looking at.

To make this easier to understand, i’ve attached examples from another platform where they have done this.

Example of drop-down more information provided when the (i) button is clicked:
Screen Shot 2023-07-05 at 5.56.57 pm

Hope someone has an answer to this!

Hi,

This can be done with tooltips.

Check this example page I made, all headers of the table blocks have a tooltip. Text can be changed of course.

https://test-play.softr.app/tooltip

The first table => tooltip on hover
The second table => tooltip on click

Exactly the same for list details => https://test-play.softr.app/tooltip-listdetails

This would be amazing! Can you please let me know how to set up tooltips?

I inserted info about what to change in the first script here (gray text is information about what to change)

For Table block
1. If you want information to displaying when hovering:

<script src="https://unpkg.com/@popperjs/core@2"></script>
<script src="https://unpkg.com/tippy.js@6"></script>

<script>
window.addEventListener('load', function() {

    setTimeout(function() {
        var table1 = document.querySelector("#table1"); /* change #table1 by the name of your block with #just before it */
        var headerCells = table1.querySelectorAll(".ag-header-cell");

        headerCells.forEach(function(cell, index) {
            var nthChild = index + 1;
            var tooltipContent = getTooltipContent(nthChild);
            tippy(cell, { content: tooltipContent, placement: 'bottom' }); /*You can change the placement by changing 'bottom' by 'top' for example */
        });
    }, 1200); 

    function getTooltipContent(nthChild) {
        switch (nthChild) {
            case 1:
                return 'Tooltip for first element'; /* Add as many use cases as headers/labels you have + change 'Tooltip for first/second/third/etc element' by the exact text you want to display*/
            case 2:
                return 'Tooltip for second element';
            case 3:
                return 'Tooltip for third element';
            case 4:
                return 'Tooltip for fourth element';

        }
    }

});
</script>

2. If you want the information to be displayed when clicking

<script>
window.addEventListener('load', function() {

    setTimeout(function() {
        var table2 = document.querySelector("#table2");
        var headerCells = table2.querySelectorAll(".ag-header-cell");

        headerCells.forEach(function(cell, index) {
            var nthChild = index + 1;
            var tooltipContent = getTooltipContent(nthChild);

            cell.addEventListener('click', function() {
                tippy(cell, { content: tooltipContent, placement: 'bottom' }).show();
            });
        });
    }, 1200);

    function getTooltipContent(nthChild) {
        switch (nthChild) {
            case 1:
                return 'Tooltip for first element';
            case 2:
                return 'Tooltip for second element';
            case 3:
                return 'Tooltip for third element';
            case 4:
                return 'Tooltip for fourth element';

        }
    }

});
</script>

For list details block
1. if you want the information to be displayed when hovering

<script src="https://unpkg.com/@popperjs/core@2"></script>
<script src="https://unpkg.com/tippy.js@6"></script>

<script>
window.addEventListener('load', function() {
    setTimeout(function() {
        var listdetails1 = document.querySelector("#list-details1");
        var headerCells1 = listdetails1.querySelectorAll(".label-wrapper.vertical .css-0");

        headerCells1.forEach(function(cell, index) {
            var nthChild = index + 1;
            var tooltipContent = getTooltipContent(nthChild);
            tippy(cell, { content: tooltipContent, placement: 'bottom' });
        });

        function getTooltipContent(nthChild) {
            switch (nthChild) {
                case 1:
                    return 'Tooltip for first element';
                case 2:
                    return 'Tooltip for second element';
                case 3:
                    return 'Tooltip for third element';
                case 4:
                    return 'Tooltip for fourth element';
            }
        }
    }, 1200);
});
</script>

2. If you want the information to be displayed when clicking

<script src="https://unpkg.com/@popperjs/core@2"></script>
<script src="https://unpkg.com/tippy.js@6"></script>

<script>
window.addEventListener('load', function() {
    setTimeout(function() {
        var listdetails1 = document.querySelector("#list-details1");
        var headerCells1 = listdetails1.querySelectorAll(".label-wrapper.vertical .css-0");

        headerCells1.forEach(function(cell, index) {
            var nthChild = index + 1;
            var tooltipContent = getTooltipContent(nthChild);

            cell.addEventListener('click', function() {
                tippy(cell, { content: tooltipContent, placement: 'bottom' }).show();
            });
        });

        function getTooltipContent(nthChild) {
            switch (nthChild) {
                case 1:
                    return 'Tooltip for first element';
                case 2:
                    return 'Tooltip for second element';
                case 3:
                    return 'Tooltip for third element';
                case 4:
                    return 'Tooltip for fourth element';
            }
        }
    }, 1200);
});
</script>

2 Likes

If you want to display the text of the labels/headers of your list details, dynamically, without having to write all the use cases in the script =>

When clicking

<script>
window.addEventListener('load', function() {
    setTimeout(function() {
        var listdetails1 = document.querySelector("#list-details1");
        var headerCells1 = listdetails1.querySelectorAll(".label-wrapper.vertical .css-0");

        headerCells1.forEach(function(cell) {
            cell.addEventListener('click', function() {
                var tooltipContent = cell.innerText;
                tippy(cell, { content: tooltipContent, placement: 'bottom' }).show();
            });
        });
    }, 1200);
});
</script>

When hovering

<script>
window.addEventListener('load', function() {
    setTimeout(function() {
        var listdetails1 = document.querySelector("#list-details1");
        var headerCells1 = listdetails1.querySelectorAll(".label-wrapper.vertical .css-0");

        headerCells1.forEach(function(cell) {
            var tooltipContent = cell.innerText;

            cell.addEventListener('mouseenter', function() {
                tippy(cell, { content: tooltipContent, placement: 'bottom' }).show();
            });
        });
    }, 1200);
});
</script>

This is so helpful! I’ve got it working on my list now. Thank you so much :slight_smile:

Does anyone know how to adapt this code to the items of a form? I need help explaining how to answer different questions with better readability than just using placeholders. Any suggestions are welcome!

Thanks :flower_playing_cards:

Hi Matthieu - I’m trying to redo this code now that i have created multiple list blocks on the one page. Can you please advise which how to stack this code correctly from “list-block1” to “list-block2” to “list-block3”? I’ve tried to just repeat this block of code for each block but its not working.

If it’s a list block the selectors are different from a list-details block. What is the type of list block you use?

I have some list details page with 3 column view and some list details with video on the same page.

So the code would be, for three list-details, for example:

<script src="https://unpkg.com/@popperjs/core@2"></script>
<script src="https://unpkg.com/tippy.js@6"></script>

<script>
window.addEventListener('load', function() {
    setTimeout(function() {
        var listdetails1 = document.querySelector("#list-details1");
        var headerCells1 = listdetails1.querySelectorAll(".label-wrapper.vertical .css-0");
        var tooltipTexts1 = ["first text", "second text", "third text"];

        headerCells1.forEach(function(cell, index) {
            var tooltipContent = tooltipTexts1[index];

            cell.addEventListener('mouseenter', function() {
                tippy(cell, { content: tooltipContent, placement: 'bottom' }).show();
            });
        });

        var listdetails2 = document.querySelector("#list-details2");
        var headerCells2 = listdetails2.querySelectorAll(".label-wrapper.vertical .css-0");
        var tooltipTexts2 = ["fourth text", "fifth text", "sixth text"];

        headerCells2.forEach(function(cell, index) {
            var tooltipContent = tooltipTexts2[index];

            cell.addEventListener('mouseenter', function() {
                tippy(cell, { content: tooltipContent, placement: 'bottom' }).show();
            });
        });

        var listdetails3 = document.querySelector("#list-details3");
        var headerCells3 = listdetails3.querySelectorAll(".label-wrapper.vertical .css-0");
        var tooltipTexts3 = ["seventh text", "eighth text", "ninth text"];

        headerCells3.forEach(function(cell, index) {
            var tooltipContent = tooltipTexts3[index];

            cell.addEventListener('mouseenter', function() {
                tippy(cell, { content: tooltipContent, placement: 'bottom' }).show();
            });
        });
    }, 1200);
});
</script>

Note that the selector “.label-wrapper.vertical .css-0” is not very precise, so it might not fit with what you want. Softr is not made for this, and doesn’t have clear selectors for this specific use case. And as most of the use cases are very precise I gave up on doing it.

Just note that having tooltips on labels is, in 99% of the case, totally useless and a poor user experience (everything popups all the time => you just make clear to the users that your app is hard to understand => red flag).
If you want to give your users a better understanding of what is going on => Videos, Help Text in a specific page, onboarding process inside the Softr app etc.

Sorry to aks this silly question but…
In order to setup this on my project i should put a custom code block in the same page as the list right ?

Hi,

In the header custom code of the page settings.

Though these scripts might not be up to date and not perfectly running. It’s been a long time I haven’t touched it (And I won’t touch it for some time, it would take too much time for me to update it by the next weeks).