-
Notifications
You must be signed in to change notification settings - Fork 802
Grid Mixin Custom grid pager without counting total records
Jin edited this page Apr 3, 2022
·
2 revisions
!!! Note: Check version 2 here: https://github.com/serenity-is/Serenity/wiki/Custom-pager-with-only-next-previous-mode-(version-2)
site.less
.slick-pg-in{
width: 100% !important;
}
MyBaseListRequest.cs
public interface IPagingRequest
{
bool EnableOnlyNextPreviousMode { get; set; }
}
public class MyBaseListRequest : ListRequest, IPagingRequest
{
public bool EnableOnlyNextPreviousMode { get; set; }
}
CustomPagerWithOnlyNextPreviousMixin.ts
namespace [YOUR_NAME_SPACE].Common {
export class CustomPagerWithOnlyNextPreviousMixin<TItem> {
private options: CustomPagerWithOnlyNextPreviousMixinOptions<TItem>;
private dataGrid: Serenity.DataGrid<TItem, any>;
private _customPagerCurrentPage: number = 1;
private _customPager: JQuery = null;
private _originalPager = null;
private _pagingMode: ('full' | 'next-previous-only');
private _btnSwitch: JQuery = null;
constructor(options: CustomPagerWithOnlyNextPreviousMixinOptions<TItem>) {
var self = this;
this.options = options;
var dg = this.dataGrid = options.grid;
this._pagingMode = options.pagingMode = options.pagingMode || 'next-previous-only';
if (this._originalPager == null) {
this._originalPager = this.options.grid.element.find(".s-SlickPager");
}
this.options.grid.element.find(".slick-pg-in").hide();
if (this._customPager == null) {
this._customPager = $("<span class='next-previous-pager'><button class='custompager-pre'><strong>«</strong> Previous</button><span style='padding: 0 2px;'></span><button class='custompager-next'>Next <strong>»</strong></button><span style='padding: 0 2px;'></span><b>Page</b> <span class='custompager-curpage'>1</span></span>");
this._originalPager.find(".slick-pg-in").append(this._customPager);
}
if (this._btnSwitch == null) {
this._btnSwitch = $(`<input type="checkbox" title="Full Pager" class="paging-mode-switch pull-right" style="margin-right: 5px; cursor: pointer" ${(options.pagingMode == "full" ? ' checked' : '')}>`);
this._btnSwitch.appendTo(dg.element.find(".slick-pg-in"));
this._btnSwitch.change((evt) => {
var isFullMode: boolean = $(evt.target).is(":checked");
// update current page number
if (!isFullMode) {
this._customPagerCurrentPage = parseInt(this.options.grid.element.find(".slick-pg-current").val());
this._originalPager.find(".custompager-curpage").text(this.options.grid.element.find(".slick-pg-current").val());
}
this.switchView(isFullMode ? 'full' : 'next-previous-only');
});
}
this._originalPager.find(".custompager-pre").click(e => {
if (this._customPagerCurrentPage > 1) {
this._customPagerCurrentPage--;
this.dataGrid.view.seekToPage = this._customPagerCurrentPage;
this.dataGrid.refresh();
this._originalPager.find(".custompager-curpage").text(this._customPagerCurrentPage);
}
return;
});
this._originalPager.find(".custompager-next").click(e => {
this._customPagerCurrentPage++;
this.dataGrid.view.seekToPage = this._customPagerCurrentPage;
this.dataGrid.refresh();
this._originalPager.find(".custompager-curpage").text(this._customPagerCurrentPage);
return;
});
dg.view.onDataChanged.subscribe(() => {
this.updatePageControls(!$(this._btnSwitch).is(":checked"));
});
// save setting
var oldCurrentSettings = (dg as any).getCurrentSettings;
(dg as any).getCurrentSettings = function (flag) {
var settings = oldCurrentSettings.apply(dg, [flag]);
settings['customPagerMode'] = $(self._btnSwitch).is(":checked") ? 'full' : 'next-previous-only';
return settings;
};
var oldRestoreSettings = (dg as any).restoreSettings;
(dg as any).restoreSettings = function (settings, flags) {
oldRestoreSettings.apply(dg, [settings, flags]);
if (settings == null) {
var storage = this.getPersistanceStorage();
if (storage == null) {
self.switchView(self._pagingMode);
return;
}
var json = Q.trimToNull(storage.getItem(this.getPersistanceKey()));
if (!json) {
self.switchView(self._pagingMode);
return;
}
settings = JSON.parse(json);
}
var viewPagerMode = settings.customPagerMode || self._pagingMode;
var currentViewPagerMode = $(self._btnSwitch).is(":checked") ? 'full' : 'next-previous-only';
if (viewPagerMode != currentViewPagerMode) {
$(self._btnSwitch).click();
}
};
}
public updateNextButton(nbrOfRecords: number, nbrOfRowsPerPage: number): void {
if (this.options.pagingMode === 'full') {
return;
}
if (nbrOfRecords == 0 || nbrOfRecords < nbrOfRowsPerPage) {
this._originalPager.find(".custompager-next").prop("disabled", true);
this._originalPager.find(".custompager-next").css("opacity", 0.5);
}
else {
this._originalPager.find(".custompager-next").prop("disabled", false);
this._originalPager.find(".custompager-next").css("opacity", 1);
}
}
private switchView(pMode: ('full' | 'next-previous-only')): void {
this.updatePageControls(pMode == "next-previous-only");
this.dataGrid.refresh();
(this.dataGrid as any).persistSettings();
}
private updatePageControls(isNextPreviousOnlyMode: boolean) {
if (isNextPreviousOnlyMode) {
this._originalPager.find(".next-previous-pager").show();
this._originalPager.find(".slick-pg-grp").hide();
this._originalPager.find(".slick-pg-sep").hide();
this._originalPager.find(".slick-pg-grp:first").show();
}
else {
this._originalPager.find(".next-previous-pager").hide();
this._originalPager.find(".slick-pg-grp").show();
this._originalPager.find(".slick-pg-sep").show();
}
this.options.grid.element.find(".slick-pg-in").show();
}
public getCurrentPagerMode(): ('full' | 'next-previous-only') {
return $(this._btnSwitch).is(":checked") ? 'full' : 'next-previous-only';
}
}
export class CustomPagerWithOnlyNextPreviousMixinOptions<TItem> {
grid: Serenity.DataGrid<TItem, any>;
rowPerPage: number;
pagingMode?: ('full' | 'next-previous-only');
}
}
Endpoint.cs
public ListResponse<MyRow> List(IDbConnection connection, Common.MyBaseListRequest request)
{
return new MyRepository().List(connection, request);
}
Repository.cs
public ListResponse<MyRow> List(IDbConnection connection, Common.MyBaseListRequest request)
{
return new MyListHandler().Process(connection, request);
}
private class MyListHandler : CustomListRequestHandle<MyRow> { }
public class CustomListRequestHandle<TRow> : ListRequestHandler<TRow> where TRow : Row, new()
{
protected override void ApplyFilters(SqlQuery query)
{
base.ApplyFilters(query);
if (Request is Common.MyBaseListRequest customRequest)
{
if (customRequest.EnableOnlyNextPreviousMode)
{
query.ApplySkipTakeAndCount(this.Request.Skip, this.Request.Take, this.Request.ExcludeTotalCount || DistinctFields != null);
// Setting CountRecords to false stops the count(*) query from running
query.CountRecords = false;
}
}
}
}
Grid.ts
/// <reference path="../../Common/Mixin/CustomPagerWithOnlyNextPreviousMixin.ts" />
private _pagerMixin: Common.CustomPagerWithOnlyNextPreviousMixin<Your_Row>;
protected onViewProcessData(response: Serenity.ListResponse<Your_Row>): Serenity.ListResponse<Your_Row> {
var lr = super.onViewProcessData(response);
this._pagerMixin.updateNextButton(lr.Entities.length, response.Take);
return lr;
}
protected getViewOptions() {
var opt = super.getViewOptions();
opt.rowsPerPage = 20;
return opt;
}
protected createToolbarExtensions(): void {
super.createToolbarExtensions();
var self = this;
this._pagerMixin = new Rydell.Web.Common.CustomPagerWithOnlyNextPreviousMixin({
grid: this,
rowPerPage: this.getPagerOptions().rowsPerPage
});
}
protected onViewSubmit() {
if (!super.onViewSubmit()) {
return false;
}
var request = this.view.params as Common.MyBaseListRequest;
request.EnableOnlyNextPreviousMode = this._pagerMixin.getCurrentPagerMode() == 'next-previous-only';
return true;
}
protected getPersistanceStorage(): Serenity.SettingStorage {
return new Common.UserPreferenceStorage();
}
- This post relates to issue at here https://github.com/volkanceylan/Serenity/issues/4458
- Feel free to ask any question 💖
Credits: @minhhungit
Copyright © Serenity Platform 2017-present. All rights reserved.
Documentation | Serene Template | Live Demo | Premium Support | Issues | Discussions