UX Collective

We believe designers are thinkers as much as they are makers. https://linktr.ee/uxc

Follow publication

How to implement user-friendly pagination for your application

Jas Haria
UX Collective
Published in
6 min readAug 9, 2020

Image taken from here

Pagination is often an afterthought for most of us developing an application from scratch. We go about designing and developing the application until the data becomes to large to display on a single page or table and that is when we plan to integrate some form of pagination. This is often haphazardly done and not taking into consideration the actual use case in mind.

There are many ways to implement pagination and they differ not only at the server level but also at the presentation level. Each type has its advantages and disadvantages and there is no one-size-fits-all approach. The best approach is the approach that works for your application, for every application has its own goal and its own set of circumstances under which it operates.

Another mistake that most of us who come from a development background make is that we think of it only from an implementation point-of-view and not a user experience one. The point of pagination is to make it simpler for the user to navigate data, so implement it such that it optimizes the user’s experience.

I’ve shared some points that I feel are often overlooked before settling for an approach of pagination, especially to make it more user friendly. I’ve used the project I’m currently working on as an example.

Disclaimer: I’m not a UI/UX expert, I’m just speaking from my limited experience.

1. How often is your data updated?

There are two common implementations of pagination: offset based and cursor-based.

Assume you are on page 9 of page size 20 records, and you want to navigate to page 10.

In an offset-based approach, the server would simply run an SQL query, where it would skip the first 9*20 records and return the next set of 20 records.

In the cursor-based approach, the server would take the last record of page 9 and return the 20 records after it.

So, isn’t it like eating with your left hand vs your right? You’re getting fed, that’s all that matters, right?

Wrong!

Imagine a scenario: you are surfing page 9 and at that same moment, the server adds 20 records to the top of the table. What do you think will happen when you go to page 10?

In an offset based-approach, the server would skip the first 9*20 records and return the next set of 20 records. Which would… err… be the same records you saw on page 9. You’re getting where I am going at, aren’t you?

In the cursor-based approach, the server would be returning you 20 records after the last record of page 9. It doesn’t matter how many records were added to the table before this server call.

Okay, calm down. Don’t jump on the cursor bandwagon. There are a few trade-offs with respect to performance and difficulty of implementation. As a matter of fact, in the project I’m currently working on, I used the offset based approach, for the data would be periodically refreshed in an organised manner.

query is a python SQL Alchemy Query. count(), offset(), limit() and all() are predefined functions provided by SQL Alchemy. totalLength and content are the only two fields being passed to the front end.

A proper comparison needs to be done for the two approaches and their effect on your particular application before coming to a decision. Their detailed advantages and disadvantages are a new tab and a few Google searches away.

2. Would the user want to share the page they are looking at? (And can they?)

Imagine another scenario. A user is on page 125 and she notices an anomaly on two adjacent records. She wants to share this with her colleague. As a developer, you need to answer 2 questions. Is she allowed to? How can she share it?

If (she isn’t allowed to): Do nothing. Continue to point 3.

Else: Read below.

The easiest way for her to share it with her colleague would be to share the URL of the page. This would mean that all your pagination parameters need to be present in the URL.

Pagination parameters also displayed in the URL

Consider the parameters in the URL and the controls on the screen. page is the page number (editable from the input field and arrow keys at the bottom of the page), size is the size of each page (editable from the button at the bottom left), divisions are all the divisions selected (the button group on the top left where all are selected), evaluated is a boolean property linked to the toggle at top right and timePeriod is the selected time period that is displayed in the middle of the divisions and evaluated fields.

There is no search functionality in the application in question, but you could sure integrate it and it would be just another parameter in the URL.

There are many ways to achieve this display in the URL, of course. I’ll share mine.

The code is written in Angular 8. If you do not understand it, I am providing a simple logical explanation to it.

Basically, whenever any of the pagination parameters are updated, instead of directly hitting the backend server, I chose to navigate to the new URL with the updated parameters. The refreshPage() function is called on change of parameters from the screen. The routeListner() function is triggered every time the URL is changed (call it from ngOnInit() so that it is triggered even when you navigate to the page for the first time). The function checks if all parameters are present and contains valid properties (if not, it sets the parameters to their default values and refreshes the page via refreshPage()). The valid parameters are then sent to the server to load the required data via the refreshDataSource() function. We get the totalLength and content that was sent by the python server.

You can do this in your way. But triggering the server call on URL change made perfect sense to me. It also handled the condition of navigating to the page for the first time and having no URL parameters and the condition of having intentional or unintentional extra characters in the URL.

3. Will scrolling ruin your design?

If the answer is no, your job is easier. Any controls, especially the page number and size ones, can be made sticky, as they shouldn’t be hidden from the user in the initial screen before scrolling.

Pagination controls are sticky and so visible even if the table is too long

If the answer is yes and you want to disable the scrolling option, it’s a little more tricky. Using some lines of code, you can set the page size equal to ((Available Vertical Space) / (Height of One Record)) number of records. Some things to consider while doing this are:

1- Is every record going to be of the same height? If not, can you make it? (for example, by truncating the text)

2- Where will the users access the application? (Having multiple Operating Systems or Browsers to cater to will be more cumbersome for there could be minute differences in their rendering of the table)

That’s all I wanted to say. Just to reiterate, I think implementing pagination proactively is a better option. It gives you time to consider all scenarios for your application and will mostly be much easier than implementing it on top of your code and APIs.

Find the above code and the code for the rest of the project on my GitHub. You can also connect with me on my LinkedIn.

If you liked my article, kindly leave a clap, or a few. Not too many, else I’ll have to paginate them.

Check out some of my other articles:

How to Scrape Your Statistics from Quora using Python 3

The UX Collective donates US$1 for each article published in our platform. This story contributed to UX Para Minas Pretas (UX For Black Women), a Brazilian organization focused on promoting equity of Black women in the tech industry through initiatives of action, empowerment, and knowledge sharing. Silence against systemic racism is not an option. Build the design community you believe in.

Sign up to discover human stories that deepen your understanding of the world.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

No responses yet

Write a response