{"id":27308447,"url":"https://github.com/rijwanansari/dynamicpagination","last_synced_at":"2026-01-22T18:43:03.047Z","repository":{"id":254331740,"uuid":"846064803","full_name":"rijwanansari/DynamicPagination","owner":"rijwanansari","description":"To implement a simple and reusable client-side pagination solution in Blazor Server, you can create a generic pagination component that can be reused across different data lists.","archived":false,"fork":false,"pushed_at":"2024-08-22T18:55:01.000Z","size":118,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-12T04:59:24.084Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rijwanansari.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-08-22T13:15:06.000Z","updated_at":"2025-03-18T22:11:22.000Z","dependencies_parsed_at":"2024-08-22T21:08:34.939Z","dependency_job_id":"0cf6c080-41b0-4936-a943-a76718c1068d","html_url":"https://github.com/rijwanansari/DynamicPagination","commit_stats":null,"previous_names":["rijwanansari/dynamicpagination"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rijwanansari/DynamicPagination","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rijwanansari%2FDynamicPagination","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rijwanansari%2FDynamicPagination/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rijwanansari%2FDynamicPagination/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rijwanansari%2FDynamicPagination/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rijwanansari","download_url":"https://codeload.github.com/rijwanansari/DynamicPagination/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rijwanansari%2FDynamicPagination/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28668264,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-22T17:07:18.858Z","status":"ssl_error","status_checked_at":"2026-01-22T17:05:02.040Z","response_time":144,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-04-12T04:59:23.311Z","updated_at":"2026-01-22T18:43:03.026Z","avatar_url":"https://github.com/rijwanansari.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# How to Build and Reuse a Dynamic Pagination Component in Blazor\nIn web applications that deal with large amounts of data, pagination is a common feature. This enables you to split your data into pages, so that users can browse more easily without overwhelming them with lengthy lists. Correct pagination improves the user experience because it improves performance, reduces page loading time, and makes data easier to digest.\n\nYou can implement both client-side and server-side pagination approaches in Blazor. In this article, our focus will be on the creation of a reusable client-side pagination component that can be easily integrated into any Blazor application.\n![image](https://github.com/user-attachments/assets/a4583966-3e98-4e57-b28a-40cbd0e87f03)\n\n## Creating a Reusable Dynamic Pagination Component\nLet’s walk through the process of building a reusable pagination component in Blazor that supports dynamic page size selection and navigation.\n\nCreate a Blazor Web App project template using Visual Studio or VS Code and give a name.\nYou can choose any .NET Core framework. However, for this article, I have used .NET 8.\n\n## Defining the Pagination Component\n\nCreate a Blazor component in a shared folder or any folder of your choice where you can share across the project easily.\n\nThe first step is to define the PaginationComponent. This component will handle the pagination logic and display the necessary controls, such as page numbers and page size options.\n\nPaginationComponent.razor\n\n```\n@typeparam TItem\n\n\u003cdiv\u003e\n    \u003ctable class=\"table\"\u003e\n        \u003cthead\u003e\n            @ChildContentHeader\n        \u003c/thead\u003e\n        \u003ctbody\u003e\n            @foreach (var item in PaginatedData)\n            {\n                @ChildContentRow(item)\n            }\n        \u003c/tbody\u003e\n    \u003c/table\u003e\n\n    \u003cdiv class=\"pagination-controls\"\u003e\n        \u003c!-- Page Size Dropdown --\u003e\n        \u003clabel for=\"pageSize\"\u003ePage Size: \u003c/label\u003e\n        \u003cselect @bind=\"PageSize\" id=\"pageSize\"\u003e\n            @foreach (var size in PageSizes)\n            {\n                \u003coption value=\"@size\"\u003e@size\u003c/option\u003e\n            }\n        \u003c/select\u003e\n\n        \u003c!-- Previous Page Button --\u003e\n        \u003cbutton @onclick=\"PreviousPage\" disabled=\"@IsPreviousDisabled\"\u003ePrevious\u003c/button\u003e\n\n        \u003c!-- Page Number Buttons --\u003e\n        @foreach (var pageNumber in Enumerable.Range(1, TotalPages))\n        {\n            \u003cbutton @onclick=\"() =\u003e GoToPage(pageNumber)\" class=\"@(CurrentPage == pageNumber ? \"active\" : \"\")\"\u003e\n                @pageNumber\n            \u003c/button\u003e\n        }\n\n        \u003c!-- Next Page Button --\u003e\n        \u003cbutton @onclick=\"NextPage\" disabled=\"@IsNextDisabled\"\u003eNext\u003c/button\u003e\n    \u003c/div\u003e\n\u003c/div\u003e\n\n@code {\n    [Parameter] public IEnumerable\u003cTItem\u003e Items { get; set; }\n    [Parameter] public int DefaultPageSize { get; set; } = 10;\n    [Parameter] public RenderFragment ChildContentHeader { get; set; }\n    [Parameter] public RenderFragment\u003cTItem\u003e ChildContentRow { get; set; }\n\n    private int PageSize { get; set; }\n    private List\u003cTItem\u003e PaginatedData =\u003e Items.Skip((CurrentPage - 1) * PageSize).Take(PageSize).ToList();\n    private int CurrentPage { get; set; } = 1;\n\n    private readonly int[] PageSizes = new[] { 5, 10, 20, 50 };\n\n    protected override void OnInitialized()\n    {\n        PageSize = DefaultPageSize;\n    }\n\n    private void NextPage()\n    {\n        if (CurrentPage \u003c TotalPages)\n        {\n            CurrentPage++;\n        }\n    }\n\n    private void PreviousPage()\n    {\n        if (CurrentPage \u003e 1)\n        {\n            CurrentPage--;\n        }\n    }\n\n    private void GoToPage(int pageNumber)\n    {\n        CurrentPage = pageNumber;\n    }\n\n    private int TotalPages =\u003e (int)Math.Ceiling(Items.Count() / (double)PageSize);\n\n    private bool IsPreviousDisabled =\u003e CurrentPage == 1;\n    private bool IsNextDisabled =\u003e CurrentPage == TotalPages;\n}\n```\nIn this component, we have the following items.\n\n@typeparam TItem: This allows the component to be generic, meaning it can work with any data type (TItem). It makes the component flexible and reusable with different types of data, such as Product, Employee, etc.\n\nItems, ChildContentHeader, and ChildContentRow Parameters:\u003cbr\u003e\n\nItems: This is a collection of data (IEnumerable\u003cTItem\u003e) passed into the component. The component uses this data to display paginated content.\u003cbr\u003e\nChildContentHeader: This is a render fragment for the table header. It allows the parent component to define how the header should be rendered.\u003cbr\u003e\nChildContentRow: This is a render fragment for each row of data. It takes a TItem and allows the parent component to define how each item should be displayed.\u003cbr\u003e\nPagination Logic: The component calculates which items to display based on the current page and page size.\u003cbr\u003e\n\nPaginatedData: This property uses LINQ to skip items and take only those that should be displayed on the current page.\u003cbr\u003e\nPageSize and PageSizes: PageSize controls how many items are displayed per page, and PageSizes defines the available options for page size.\u003cbr\u003e\nNextPage, PreviousPage, and GoToPage: These methods handle navigation between pages.\u003cbr\u003e\nPagination Controls: The component includes buttons for navigating between pages (Next and Previous) and buttons for selecting specific pages. There’s also a dropdown for selecting the page size.\u003cbr\u003e\u003cbr\u003e\n\nWe will CSS file for this component as shown to add style for the controls like page, page buttons, previous and next buttons and below pagination sections.\u003cbr\u003e\n\n\nCSS for this pagination controls is shared below.\n```\n.pagination-controls\n{\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    margin-top: 20px;\n}\n\n.pagination-controls button {\n    background-color: #f8f9fa;\n    border: 1px solid #dee2e6;\n    color: #007bff;\n    padding: 5px 10px;\n    margin: 0 5px;\n    border-radius: 4px;\n    cursor: pointer;\n    transition: background-color 0.3s ease, color 0.3s ease;\n}\n\n    .pagination-controls button:hover {\n        background-color: #007bff;\n        color: white;\n    }\n\n    .pagination-controls button.active {\n        background-color: #007bff;\n        color: white;\n        font-weight: bold;\n    }\n\n    .pagination-controls button:disabled {\n        background-color: #e9ecef;\n        color: #6c757d;\n        cursor: not-allowed;\n        border-color: #ced4da;\n    }\n\n.pagination-controls select {\n    margin-right: 15px;\n    padding: 5px;\n    border-radius: 4px;\n    border: 1px solid #dee2e6;\n}\n\n.pagination-controls label {\n    margin-right: 5px;\n    font-weight: bold;\n}\n```\nThis CSS ensures that the pagination controls have a clean, modern look with smooth transitions when users interact with them.\n\n## Using the Pagination Component\nOnce the PaginationComponent is defined, you can easily integrate it into your Blazor pages or components. Here’s an example of how to use it with a list of products.\n```\npublic class Product\n{\n    public int Id { get; set; }\n    public string Name { get; set; }\n    public decimal Price { get; set; }\n}\n\n//sample dummy data\npublic class ProductService\n{\n    public List\u003cProduct\u003e GetProducts()\n    {\n        // Sample data\n        return Enumerable.Range(1, 100).Select(i =\u003e new Product\n        {\n            Id = i,\n            Name = $\"Product {i}\",\n            Price = i * 10\n        }).ToList();\n    }\n}\n```\nWe can use the pagination component as illustrated.\n```\n@page \"/\"\n@using DynamicPagination.Components.Shared\n@using DynamicPagination.Model\n@inject ProductService ProductService\n@rendermode RenderMode.InteractiveServer\n\n\u003ch3\u003eProduct List\u003c/h3\u003e\n\n\u003cPaginationComponent TItem=\"Product\" Items=\"Products\" DefaultPageSize=\"10\"\u003e\n    \u003cChildContentHeader\u003e\n        \u003ctr\u003e\n            \u003cth\u003eId\u003c/th\u003e\n            \u003cth\u003eName\u003c/th\u003e\n            \u003cth\u003ePrice\u003c/th\u003e\n        \u003c/tr\u003e\n    \u003c/ChildContentHeader\u003e\n    \u003cChildContentRow Context=\"product\"\u003e\n        \u003ctr\u003e\n            \u003ctd\u003e@product.Id\u003c/td\u003e\n            \u003ctd\u003e@product.Name\u003c/td\u003e\n            \u003ctd\u003e@product.Price\u003c/td\u003e\n        \u003c/tr\u003e\n    \u003c/ChildContentRow\u003e\n\u003c/PaginationComponent\u003e\n\n@code {\n    private List\u003cProduct\u003e Products;\n\n    protected override void OnInitialized()\n    {\n        Products = ProductService.GetProducts();\n    }\n}\n```\n## How It Works\nIn the above sample, the PaginationComponent takes in a list of products and renders a paginated table. The ChildContentHeader defines the table’s headers, while ChildContentRow specifies how each row of data should be rendered. The component handles the pagination logic, allowing users to navigate through pages and change the number of items displayed per page.\n\nOutput:\n![image](https://github.com/user-attachments/assets/4ba7682f-bb6e-4049-ad85-892ccca28bde)\n\n## Benefits of a Reusable Pagination Component\nConsistency: Once the component is defined, it can be reused across multiple pages, ensuring a consistent pagination experience throughout the application.\u003cbr\u003e\nCustomization: The component can be easily customized to fit different use cases by modifying parameters such as page size, styling, or behavior.\u003cbr\u003e\nMaintenance: Any changes to the pagination logic or design need to be made only once within the component, reducing maintenance overhead.\u003cbr\u003e\nComplete Source Code: https://github.com/rijwanansari/DynamicPagination\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frijwanansari%2Fdynamicpagination","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frijwanansari%2Fdynamicpagination","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frijwanansari%2Fdynamicpagination/lists"}