Custom pagination for Entity Lists in Power Pages can be implemented to improve the user experience, especially when dealing with large datasets. By customizing the pagination, you can control how many records are displayed per page and provide more efficient navigation through the data. Here’s a guide to implement custom pagination for Entity Lists step by step.
1. Understanding Entity Lists in Power Pages
Entity Lists in Power Pages (formerly known as PowerApps Portals) are used to display data from Dataverse entities (tables) in a tabular format. These lists can be customized to display the desired data and allow users to interact with it.
2. Challenges with Default Pagination
The default pagination in Power Pages can sometimes be restrictive in terms of customization. It limits the number of records per page and may not allow you to style or add additional functionality like custom page numbers or next/previous buttons. This is where custom pagination comes in.
3. Custom Pagination Components
Custom pagination generally involves the following components:
- Page Size: Number of records per page.
- Previous/Next Buttons: Allow users to navigate between pages.
- Page Numbers: Show the available pages for navigation.
- Total Records Count: Display the total number of records to help users know the extent of the data.
4. Setting Up Pagination Logic
To create custom pagination for Entity Lists, you’ll need to control how data is queried and displayed in pages. The pagination logic can be achieved through JavaScript, FetchXML, or Power Automate.
Step 1: Define Records per Page
First, define the number of records to display per page. This can be set through JavaScript.
var recordsPerPage = 10; // Define how many records should be shown per page.
Step 2: Calculate Total Pages
Next, you need to calculate how many pages are required based on the total number of records and the records per page. This can be done using FetchXML or directly through the API.
var totalRecords = 100; // Get this from a fetch query or API call.
var totalPages = Math.ceil(totalRecords / recordsPerPage);
Step 3: Fetch Records for the Current Page
You’ll need to modify the FetchXML query to retrieve the appropriate records based on the current page number.
var currentPage = 1; // Start with the first page.
var fetchXml = "<fetch count='" + recordsPerPage + "' page='" + currentPage + "'>" +
"<entity name='your_entity'>" +
"<attribute name='field1'/>" +
"<attribute name='field2'/>" +
"<order attribute='createdon' descending='true'/>" + // Example ordering
"</entity>" +
"</fetch>";
The above FetchXML query fetches only the records for the current page. Adjust the currentPage
variable as needed when navigating through the pages.
Step 4: Handle Next and Previous Buttons
You can use JavaScript to implement the “Previous” and “Next” buttons to control the current page.
function navigateToPage(pageNumber) {
currentPage = pageNumber;
// Execute your fetchXML query here again to fetch records for the current page
fetchRecords(currentPage);
}
function fetchRecords(page) {
var fetchXml = "<fetch count='" + recordsPerPage + "' page='" + page + "'>" +
"<entity name='your_entity'>" +
"<attribute name='field1'/>" +
"<attribute name='field2'/>" +
"</entity>" +
"</fetch>";
// Execute the FetchXML query with a relevant API or library (e.g., Xrm.WebApi.retrieveMultipleRecords).
Xrm.WebApi.retrieveMultipleRecords("your_entity", "?fetchXml=" + encodeURIComponent(fetchXml))
.then(function(response) {
// Handle the fetched data and update the UI accordingly
console.log(response);
renderData(response);
});
}
Step 5: Display Page Numbers
To display page numbers dynamically, create a UI component (e.g., buttons or a dropdown) that corresponds to the number of pages.
function renderPagination(totalPages, currentPage) {
var paginationHtml = "<ul class='pagination'>";
for (var i = 1; i <= totalPages; i++) {
if (i === currentPage) {
paginationHtml += "<li class='active'><span>" + i + "</span></li>";
} else {
paginationHtml += "<li><a href='javascript:navigateToPage(" + i + ")'>" + i + "</a></li>";
}
}
paginationHtml += "</ul>";
document.getElementById('pagination-container').innerHTML = paginationHtml;
}
The function renderPagination
creates a list of page numbers and highlights the current page. It also attaches the navigateToPage
function to each page link.
Step 6: Integrate Pagination with the Entity List
Once you have the basic pagination logic in place, integrate it with the Entity List by using JavaScript to render the data in the table and update the pagination when the page changes.
- Fetch records for the current page.
- Populate the Entity List with the fetched data.
- Update the pagination controls based on the total pages and current page.
function renderData(response) {
var dataHtml = "";
response.entities.forEach(function(entity) {
dataHtml += "<tr><td>" + entity.field1 + "</td><td>" + entity.field2 + "</td></tr>";
});
document.getElementById('entity-list').innerHTML = dataHtml;
}
Step 7: Handling Edge Cases
Ensure that:
- The “Previous” button is disabled on the first page.
- The “Next” button is disabled on the last page.
- Edge cases such as no records or errors in data fetching are handled properly.
5. Customizing Pagination UI
You can customize the pagination controls further with styles and CSS to match the look and feel of your portal. For example, you can add “Next” and “Previous” buttons, and style them accordingly:
.pagination {
display: flex;
list-style-type: none;
padding: 0;
margin: 0;
}
.pagination li {
margin-right: 10px;
}
.pagination li.active span {
font-weight: bold;
}
.pagination a {
text-decoration: none;
color: #0078d4;
}
.pagination a:hover {
color: #005a9e;
}
6. Considerations for Performance
When dealing with large datasets, it’s important to:
- Limit the number of records per page to reduce the load on the server and improve performance.
- Use pagination server-side (via FetchXML or Dataverse API) to only return records relevant to the current page.
- Consider lazy loading for dynamic content if your portal contains an extremely large set of data.