RepeatingGroup pagination - proof of concept

Hello All,
I discovered Bubble and was about to abandon it just a week later… Other than some minor issues - it’s a big surprise to me, that a tool to build data+events driven applications doesn’t contain basic functionalities:

  • pagination for RepeatingGroup (I’m sorry, but next and previous page, as well as go to page are not a solution); I want [1] [2] [3]… buttons!
  • loops (!)

But I’m also that kind of person, who doesn’t give up without trying, so I gave myself few days to solve pagination problem without using external APIs and/or writing plugins (I’m not there yet).

And I managed. Here you will find the solution (or at least proof of concept) that you can build on. It’s bit messy, some data (states, etc) is redundant, as I was changing the concept during work, but will give you a good base for your projects.

Solution 1 (implemented)

Step 1. Data
I created a new data type called Something, containing just “name” and “number” fields. I filled it with 31 items: random names and numbers 1-31, just to check if all works. It can be any data of yours of course.

Step 2. Repeating group
I created Repeating group for data type Something, added two text fields, set layout style as Fixed number of cells, columns as 1 and rows as 3 (for testing - that would give me 11 pages from 31 records).

In the object inspector - I added the following states for this repeating group:

  • addingPage (number)
  • curPage (number)
  • firstEl (number)
  • lastEl (number)
  • perPage (number)
  • numPages (number)
  • Pages (list of numbers)

The data source I set the following:
Search for Somethings:items from RepeatingGroup Something's **firstEl**:items until RepeatingGroup Something's **lastEl**
so the search is made based on the 2 states of this repeating group.

Step 3. Buttons
I did not find a way to dynamically create buttons. Let me rephrase: I did not find other way, than using another RepeatingGroup! So let’s create a new repeating group, type “number” (and i leave name number for the group) and add to it two custom states:

  • minButton
  • maxButton
    both are “number”. These two we will use to display range of buttons.
    Few more tweaks to this repeating group: rows 1, columns 10, fixed number of cells - we will display maximum 10 pages buttons to the user.
    Now we need to fill in the data source:
    RepeatingGroup Something's Pages:items from #RepeatingGroup number's minButton:items until RepeatingGroup number's maxButton

Last but not least with this repeating group: we add a button to it, the text being dynamic data:
Current cell's number

At this stage we have all visual elements set up and “variables” (states) that we will use to have it working.

Step 4. Worklfows
Before we can continue - we need to set up default states. For that I created the new workflow: When Page is loaded and the following states are set in this workflow one by one:

  • curPage = 1
  • perPage = 3 (this should correspond to your rows in the main repeating group; if you want to show 5 - set both to 5, etc)
  • numPages = Search for Something’s count / RepeatingGroup Something’s perPage:ceiling (simply we divide all Something’s count by how many per page we will display and round it up, so 10.2 will produce 11, etc)
  • firstEl = RepeatingGroup Something’s curPage - 1 * RepeatingGroup Something’s perPage + 1 (be careful when clicking it; in theory - it could be just set to 1 here, but I’m ready for another solution)
  • lastEl = RepeatingGroup Something’s curPage * RepeatingGroup Something’s perPage (as above - could be just perPage here, but…)
  • minButton = 1
  • maxButton = RepeatingGroup Something’s numPages <-min-> 10

The 8th step in this worklfow is to launch actual construction of the buttons

  • trigger custom event BuildPaging.

Remark: Here I had a small issue: no loops! But I needed one, so I decided to use 2 custom events, and trigger one from each other, having a custom state of an element changing, so after reaching certain value - the “loop” would stop. Unfortunately Bubble reports that as an issue and even though you can launch your app - after 1 or 2 passes - the “loop” just stops without any reason. So I decided to trigger a scheduled event with some small delay (0.01 s for example) and surprisingly - it solved the problem!
So now, we will create 3 custom events to build our data for page buttons:

  • BuildPaging (not really needed, but I like all structured and I use it for “reset” of my buttons in other places, not mentioned here)
  • newPage1
  • newPage2

Custom Event: BuildPaging: 3 steps

  • set State addingPage = 0
  • set State pages = leave Value blank (my reset thing)
  • trigger newPage1

Custom Event: newPage1: 4 steps

  • set State addingPage = addingPage + 1
  • set State pages = pages:plus item addingPage (so here we add in the “loop” new numbers to our pages state)
  • Terminate this worklflow - only when addingPage >= numPages
  • Schedule newPage2 after 0.01 seconds

Custom Event: newPage2: 4 steps

  • set State addingPage = addingPage + 1
  • set State pages = pages:plus item addingPage (so here we add in the “loop” new numbers to our pages state)
  • Terminate this worklflow - only when addingPage >= numPages
  • Trigger newPage1

At this stage if you did all OK - you can launch your project and you will see buttons filling in depending on the number of entries in your database.

The last but not least…

Step 5. Making buttons working
Now, we click on the buttons in our repeating group, but nothing happens. So let’s go to the workflow editor of our button and add one more custom event and then some steps on click:

Custom event: displayPageButtons - type of thing for this event: number (we will pass this value from outside): 2 steps

  • set State minButton = Current workflow’s number - 5 <-max-> 1
  • set State maxButton = Current workflow’s number + 5 <-max-> numPages

Event: When Current Cell’s number is clicked: 4 steps

  • set State curPage = current cell’s number
  • firstEl = current cell’s number - 1 * RepeatingGroup Something’s perPage + 1 (be careful when clicking it)
  • lastEl = current cell’s number * RepeatingGroup Something’s perPage
  • Trigger displayPageButtons - workflow thing: current cell’s number

Et voila - you just built your paging solution! Attention: the buttons will update only on page reload in this approach, so when adding/removing content - you may want to trigger rebuilding buttons as well or refreshing page, etc.

Solution 2 (not implemented - just concept)
This all could probably be done by passing page parameters, so on each page reload different content would be visible.
Another change possible is to create data type Page or Settings and put some info there (perPage, pages) and add/remove new number to the list of pages when new item is created (recalculating pages on adding/removing content). Then second repeating group (numbers) would be just connected to that content and no delays on creating buttons needed.

Unfortunately none of these approaches is “the best and only” but at least they give some idea, I hope.

Working sample here:

https://jpagingok.bubbleapps.io/version-test

3 Likes

Hey @jakubdab, check out this tutorial for RG pagination too. It works with custom states as well, but a bit more simplified:

18 Likes

I don’t know all the plugins yet, so thanks for sharing!
The idea is almost the same, just thanks to the toolbox plugin creation of the list of numbers is simplified.

You’re up way too early Gaby.

OP I may play with your solution. I have an interesting pagination issue I’m working out.

2 Likes

This topic is very recurring.
I still don’t understand why Bubble team (@emmanuel) doesn’t add more properties to the Repeating Group element like : total results count, current first cell’s index, current last cell’s index, current pagination (when the RG has a fixed width).
It would help saving our time.

4 Likes

This video made my night! @romanmg

2 Likes

Hi @romanmg,

Am planning to create pagination using your video tutorial. Thanks for providing this.

One question:

I have a repeating group with a header row in the first row which only shows on the first row (index 1). How should is show this header row on each first record of each page of the repeating group?

Should I use a modulo function?

Put the header elements inside a group of their own. That group goes inside the repeating group cell with the rest of the contents.

The header group should not be visible on page load and it should “collapse when hidden”

Add a condition to the header group: When current cell’s index is 1 > show group.

In other words, your header group and the content for all rows will both be inside the cell. It’s just that the header group will only show when index = 1.

Even when you go to the next page of an RG, the first row’s index will still = 1.


Cheers,
Gaby

Coaching No Code Apps
Join our Facebook group for insider access to no-code development
Get professional development services
Enroll in expert-led courses and products

@romanmg Thanks. Very cool that it is just that plain simple.

Hi @romanmg

Just another question. Does this setup for pagination also work when I want to have a grid/card layout with for example 3 cards on each row and a maximum of 4 rows?

Does anyone know a solution to this problem with pagination?