QuickGrid pagination support for SSR #65352
Draft
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
QuickGrid pagination support for SSR
Description
QuickGrid'sPaginatorcomponent currently requires interactivity because it relies on@onclickevent handlers, which are not supported by theStaticHtmlRenderer. Additionally,PaginationStatestores the current page index in memory, so the state cannot be persisted across SSR requests or shared via URL.This PR adds SSR support to the
Paginatorcomponent so that pagination works without interactivity.Problem
There were two main blockers preventing the
Paginatorfrom working in SSR:@onclickis not supported in SSR — TheStaticHtmlRendererdoes not render event handler attributes like@onclick, so the pagination buttons had no effect.PaginationStatestores the current page index in memory, which is lost between SSR requests. Users also cannot share URLs pointing to a specific page.Considered solutions
Session/TempData- Persist page state server-side, keeping public APIs unchanged. Discarded, because still doesn't allow URL sharing between users.?page=Nquery parameter in the URL . This option was chosen, because it provides a familiar UX (?page=2), enables link sharing, and works with both SSR and interactive rendering.Implemented changes
Paginator rendering (
Paginator.razor)RendererInfo.IsInteractiveto branch between interactive and SSR rendering.@onclickhandlers on<button>elements.<form>withmethod="get",data-enhance,@formname, and@onsubmitto handle page navigation via form submission. Each form includes an<AntiforgeryToken />.Paginator logic (
Paginator.razor.cs)QueryNameparameter ([Parameter, DisallowNull], defaults to"page") — specifies the query string key used to persist the current page index in the URL.NavigationManagerinjection — used to read the current URL and navigate with updated query parameters.OnParametersSet→OnParametersSetAsync— changed to async to support reading the query string on first render and setting the initial page index from it.ReadPageIndexFromQueryString()— parses the URL query string usingQueryStringEnumerableto extract the 1-based page number and convert it to a 0-based index.GoToPageAsync()— now also updates the URL viaNavigationManager.GetUriWithQueryParameter()andNavigationManager.NavigateTo()after setting the page index.QueryName(e.g.,Paginator_page_GoFirst) to support multiple paginators on the same page with different query parameter names.Project references (
Microsoft.AspNetCore.Components.QuickGrid.csproj)QueryStringEnumerable.csas a shared source compile include.Microsoft.AspNetCore.Components.Endpoints.Public API changes (
PublicAPI.Unshipped.txt)Breaking change
When multiple
Paginatorcomponents are used on the same page, each one now must have a uniqueQueryNamevalue. SinceQueryNamedefaults to"page", having two or more paginators without explicitly setting differentQueryNamevalues will cause them to share the same query parameter and interfere with each other. This applies to both SSR and interactive rendering.Before (worked implicitly):
After (requires unique
QueryNameper paginator):Usage example
Fixes #51249 (partially)