What's the recommended way to paginate content?

Let’s say I have a Streamlit app where I want to show the user a lot of images (1k+). Obviously, I wouldn’t want to display these all at once - I need some sort of pagination.

I tried creating a “Next page” and “Previous page” button, but because the button just returns if the button was clicked on the last run of the app it gets stuck in an infinite loop advancing to the next page.

I also tried using a select box, but this had similar issues.

eg.

next_action = st.selectbox(
    'How would you like to proceed?',
    ('Stay', 'Next page', 'Previous page')
)

if next_action == 'Stay':
    pass
elif next_action == 'Next page':
    page -= 1
    show_images(page=page)
elif next_action == 'Previous page':
    page += 1
    show_images(page=page)

What’s the recommended way to handle this case?

2 Likes

I was able to figure out a solution storing the page value using the SessionState as discussed in this thread. I’ll post a self-contained example later today.

I am working on exactly the same thing where I have filter files from dataframe but the images are around 1000 I want to say display them 10 at a time. Is your use case somewhat similar ?

Hey @jeremyjordan!

Here’s a gist showing how to get a simple paginator in Streamlit which works like this:

fruit_list = [
   'Kiwifruit', 'Honeydew', 'Cherry', 'Honeyberry', 'Pear',
   'Apple', 'Nectarine', 'Soursop', 'Pineapple', 'Satsuma',
   'Fig', 'Huckleberry', 'Coconut', 'Plantain', 'Jujube',
   'Guava', 'Clementine', 'Grape', 'Tayberry', 'Salak',
   'Raspberry', 'Loquat', 'Nance', 'Peach', 'Akee'
]
for i, fruit in paginator("Select a fruit page", fruit_list):
   st.write('%s. **%s**' % (i, fruit))

To use it, just-copy-paste the definition of paginator from the gist into your code. You can also try it out right now by running:

streamlit run https://gist.githubusercontent.com/treuille/2ce0acb6697f205e44e3e0f576e810b7/raw/98716c7442c26fa1ba7129d50a4a9fdc33ba20ce/pagination.py

You will see this:

image


image


image

Thanks @Adrien_Treuille! This was the quick and dirty solution I came up with this morning. I just pulled down your Gist and played around with it; it works quite nice for small lists, my only complaint is that the selectbox can get quite crowded for large lists :slight_smile:

That’s an awesome solution too!