How to: Expanding / collapsing repeater text that doesn't leave blank spaces

Hi Guys

Here is a quick how to on expanding/collapsing repeater texts. Feel free to add to it!

Collapsed:

Expanded:

The logic is quite simple. The first thing I did was to set the text value to blank when the page loads like here. I used .html instead of .text as my database field is rich text

$w.onReady(function () {
    $w("#dynamicDataset").onReady(() => {
        $w("#repeater1").onItemReady(() => {
            $w("#textDescription").html = "";
        })
    })
});

Then when my open arrow is clicked, I have the following code:

export function arrowOpen_click(event) {
 let $item = $w.at(event.context);
     $item("#arrowOpen").hide();
     $item("#arrowClose").show();
 
 let selectedItem = $item("#dynamicDataset").getCurrentItem();
 let description = selectedItem.description;
     $item("#textDescription").html = description;
}

And when my closed arrow gets click, the following code runs:

export function arrowClose_click(event) {
 let $item = $w.at(event.context);
     $item("#arrowClose").hide();
     $item("#arrowOpen").show();
 
 let selectedItem = $item("#dynamicDataset").getCurrentItem();
 let description = selectedItem.description;
     $item("#textDescription").html = "";
}

That’s it. Good luck!
Tiaan

3 Likes

Hi Tiaan

This is great. Another idea is to use collapse() and expand() instead of show and hide. This way you might not need to keep adding and removing the text.

Try it out?

Cheers

Hi Steve

That was my first plan of action but for some reason it doesn’t collpase the repeater accordingly when used inside the repeater, it just leaves a massive empty space where the text/element used to be. It behaves more like a hide()/show() behaves rather than actually collapsing anything.

Go ahead, try it for yourself.

Tiaan

Hey there Tiaan,

I just tried it on my end with some repeaters as well (was going to do the same thing as you on my portfolio item pages). I was having the same issues as you but what I found is that what’s likely happening is that there’s too much space between the boundaries of your repeater and the text. This page has more info on it: Velo: How Page Layout Is Affected When Elements Change Size | Help Center | Wix.com.

If you want to keep the text where it is but still have it collapse you can put in some vector images with 0 opacity into the empty space between the boundaries and the text and make those collapse as well. You can also use this between your text and the button to have the repeater collapse snugly around your button like so (just imagine the green vector images as opacity 0, I just made them green to make it clear for showing):

I hope this helps you out.

With kind regards,

Dennis van der Harst

Hi Dennis

Thank you for the addition to this post, I think we will probably need all the creativity we can get…

Tiaan

This is amazing! thanks! exactly what I wanted.
The only problem, is that the code changes my text’s design. I used the code as is…
Any suggestion?
Thanks again,
Dan

Hi all, circling back to this fix - it’s driving me nuts because it should be working! Anyone who can take a look would be super helpful. The item box in the repeater won’t collapse. Thanks!!

Here’s the test page: https://js-productions.wixstudio.io/rachel-klein/in-development

Here’s my code:

let fadeOptions = {
  "duration":   500,
};

$w.onReady(function () {
    $w('#collapseButton').onClick(async (event) => {
        const $item = $w.at(event.context);

        if ($item('#minusSign').hidden) {
                $item('#collapsibleBox').expand(); 
               await $item('#collapsibleBox').show('fade', fadeOptions);
                $item('#plusSign').hide();
                $item('#minusSign').show();
            } else {
               await $item('#collapsibleBox').hide('fade', fadeOptions); 
                $item('#collapsibleBox').collapse();
                $item('#plusSign').show();
                $item('#minusSign').hide();
            }
    } );


});

Why are you using .hidden? If you are basing it off the elements visibility state, then hidden is not correct in velo. Hidden applies to if the opacity is 0. In this case you should change your code to .collapsed. I assume you are going for an animation effect but to use hide and collapse is not necessary in this context.

Here’s the code to try:

let fadeOptions = {
  "duration":   500,
};

$w.onReady(function () {
    $w('#collapseButton').onClick((event) => {
        const $item = $w.at(event.context);

        if ($item('#minusSign').collapsed) { // change your code here away from hidden
                $item('#collapsibleBox').expand(); 
               await $item('#collapsibleBox').show('fade', fadeOptions);
                $item('#plusSign').hide();
                $item('#minusSign').show();
            } else {
               $item('#collapsibleBox').hide('fade', fadeOptions); // this does not need to be async => you are not doing a promise....
                $item('#collapsibleBox').collapse();
                $item('#plusSign').show();
                $item('#minusSign').hide();
            }
    } );


});

Hi, thanks! Yeah the ‘async’ is to get the collapsible box to show/hide before it runs the fade animation. And the hidden call actually does correspond to an element I’m NOT trying to collapse → the “minus sign,” not the “collapsible box.”

But either way it’s not addressing the issue I’m having - finding whatever is standing in the way of the item container actually collapsing on load. Thanks!!

Gotcha, that helps- is the minus sign button inside of a repeater or outside? If it’s outside then the $w.at(event.context) won’t do much. Can you include a screenshot so I can see what it looks like?

You can also try and wrap your event handle with the onItemReady reference to get the $item as well.