Create subgroups in list repeater

Hello All!
I want to create subgroups in a list repeater on a dynamic page. In other words I want to group items from a database based on a category. I would like to achieve a structure like this on one dynamic page (example countries):

Group Title 1 (e.g. Europe)
Repeater cell 1 (eg. Denmark)
Repeater cell 2 (e.g. Italy)
Repeater cell 3 (e.g. Greece)

Group Title 2 (e.g. South America)
Repeater cell 1 (eg. Brasil)
Repeater cell 2 (e.g. Chile)
Repeater cell 3 (e.g. Peru)

and so on.

So the structure of the cells is the same, I just want to add some kind of grouping of the elements based on a category.

How can I achieve this? Has anybody any suggestions?

Thank you in advance!

Hi there …

I’m sure I’d come up with a solution if I understand what exactly you’re trying to do, why not just sort the items array before assigning it to the repeater’s data property?

Having a lot of repeaters increases the complexity of your code, to add more elements to the repeaters, and only show the relevant ones based on each item’s data.

Hi Ahmad, thank you for your answer. Sorting the items wouldn’t really solve my problem. I’ll try to show what I was thinking of with a screenshot.

A list repeater looks like this: (Row after Row):

What I would need instead would be something like this:
Category Title - dynamic number of items - Category Title - dynamic number… and so on

I am not sticking to the list repeaters if there is a better solution for it.

Thanks again!

As I said before, you need to sort the items array before assigning it to the rapeater’s data, here’s an example of the array:

const items = [
    {
        _id: <the item ID>,
        class: 'cat',
        main: false
    },
    {
        _id: <the item ID>,
        class: 'dog',
        main: false
    }
];

Now you need to filter the items by their types:

const cats_arr = items.filter(items => items.class === 'cat');
const dogs_arr = items.filter(items => items.class === 'dog');

const cats = [{ _id: '1', main: true, label: 'Cats' }, ...cats_arr];
const dogs = [{ _id: '1', main: true, label: 'Dogs' }, ...dogs_arr];

Now combine all the types into one array.

const newArr = [...cats, ...dogs];

Bind the right data: To do that, we set two collapsed boxes in the repeater’s container, the first one “labelBox” will only have a text element for the title, and the second one will include the childeren elements you want to show (e.g., image, title, etc…)

$w('#rep').onItemReady(($item, data) => {
    if (data.main) {
        $item('#mainTitle').text = data.label;
        $item('#labelBox').expand();
    }
    
    /* The data item isn't a label, so we need to bin the data now, then expand
    the data section. */
    
    // Bind the data here ...
    
    // Expand the data section
    $item('#dataBox').expand();
})

@ahmadnasriya Thanks for the approach!

@berhardak you’re welcome :blush: