
This is based on the concept — of passing page numbers and sorting columns and sorting order using query string parameters. Based on the concept — if you modify the query string/URL and assign — window. location = modifiedurl, it will hit the server with the modified URL. We alter page numbers and sort columns in URL using JavaScript and JQuery.
You can copy the large JavaScript code here to a new JS file and refer to it.
//For paging use below dummy class in <style> tag
<style>
.Paging{}
</style>
<tr>
<th width="100px" style="background-color: #337ab7; color: #fff; border-color: #2e6da4;">NoSortCol1</th>
<th width="100px" style="background-color: #337ab7; color: #fff; border-color: #2e6da4;">NoSortCol2</th>
//instead of looping over month, it is up to you how you use sort expressions sent by controller
@foreach (string month in @ViewBag.ListMonths)
{
string sortExp = @"/ReportController/RevActionMethod?PAGE2=1&SORTDIR2=DESC&SORTCOL2=" + month;
<th width="100px" style="background-color: #337ab7; color: #fff; border-color: #2e6da4;">
<a style="color:#fff" href="@sortExp">@month</a>
</th>
}
</tr>
//iterate data here.. above is just header
<tr><td colspan="6" class="Paging"></td></tr>
// Here Paging buttons will be inserted in the above <tr> using Paging class
window.onload = function () {
appendPaging2('@ViewBag.TotalPages');
// appendSorting2('Q1FY22');
appendSorting2('@ViewBag.AllColumns');
};
// Here AllColumns is a ';' separated string of all columns.
// They are the same as all sort expressions in the hyperlink.
// There should not be any space in the sort expression.
// These sort expressions are the sort columns that are passed
// to the server each time we click.
Put the below in a separate JavaScript file.
If $.urlParam = function (name) in the below code is not working, put this function code in the named function.
function appendPaging2(totPages) {
TotalPages = totPages;
var pageLink = $('.Paging');
var curPage = $.urlParam("PAGE2");
if (curPage == '') curPage = 1;
pageLink.empty();
pageLink.append();
var disable5 = "", disableLast = "", disableNext = "";
var disableDecr5 = "", disablePrev = "", disableFirst = "";
if (TotalPages < 5) disable5 = "disabled";
if (curPage == TotalPages) {
disableLast = "disabled";
disableNext = "disabled";
disable5 = "disabled";
}
if (curPage == 1) {
disableDecr5 = "disabled";
disablePrev = "disabled";
disableFirst = "disabled";
}
pageLink.append('<input type="submit" name="FIRST" onclick="page(event);" style="margin-left:4px;" class="page-link" value="<<"' + disableFirst + ' />');
pageLink.append('<input type="submit" name="PREV1" onclick="page(event);" style="margin-left:4px;" class="page-link" value="<"' + disablePrev + ' />');
pageLink.append('<input type="submit" name="PREV5" onclick="page(event);" style="margin-left:4px;" class="page-link" value="<5"' + disableDecr5 + ' />');
pageLink.append('<input type="submit" name="NEXT5" onclick="page(event);" style="margin-left:4px;" class="page-link" value="5>"' + disable5 + ' />');
pageLink.append('<input type="submit" name="NEXT1" onclick="page(event);" style="margin-left:4px;" class="page-link" value=">"' + disableNext + ' />');
pageLink.append('<input type="submit" name="LAST" onclick="page(event);" style="margin-left:4px;" class="page-link" value=">>"' + disableLast + ' />');
pageLink.append('<input type="submit" class="page-link" style="background-color:#ccc; margin-left:4px;" value="1" disabled />');
pageLink.append('<input type="submit" class="page-link" style="background-color:#ccc; margin-left:4px;" value="' + TotalPages + '" disabled />');
pageLink.children().eq(6).val(curPage);
}
function appendSorting2(liColumns) {
var allColAry = liColumns.split(";");
for (let i = 0; i < allColAry.length; i++) {
$('tr > th > a[href*="SORTCOL2=' + allColAry[i].toString().replace(" ", "") + '"]').attr("onclick", 'setSort2(this);');
}
var sortCol = $.urlParam("SORTCOL2");
var sortDir = $.urlParam("SORTDIR2");
if (sortDir != "") {
if (sortDir == "DESC") {
var txt = $('tr > th > a[href*="SORTCOL2=' + sortCol + '"]').attr('href').toString();
txt = txt.replace("SORTDIR2=DESC", "SORTDIR2=ASC");
$('tr > th > a[href*="SORTCOL2=' + sortCol + '"]').attr('href', txt);
$('tr > th > a[href*="SORTCOL2=' + sortCol + '"]').parent().append("▼");
} else {
var txt = $('tr > th > a[href*="SORTCOL2=' + sortCol + '"]').attr('href').toString();
txt = txt.replace("SORTDIR2=ASC", "SORTDIR2=DESC");
$('tr > th > a[href*="SORTCOL2=' + sortCol + '"]').attr('href', txt);
$('tr > th > a[href*="SORTCOL2=' + sortCol + '"]').parent().append("▲");
}
}
}
function page(event) {
var txt = window.location.toString();
switch (event.target.name.toString()) {
case 'PREV1':
// Logic for previous page
break;
case 'NEXT1':
// Logic for next page
break;
case 'PREV5':
// Logic for previous 5 pages
break;
case 'NEXT5':
// Logic for next 5 pages
break;
case 'LAST':
// Logic for last page
break;
case 'FIRST':
// Logic for first page
break;
default:
// Default case
}
}
function setSort2(e) {
var type = e.text.toString().replace(" ", "").replace("%", "").replace("(", "").replace(")", "");
var txtHref = $('tr > th > a[href*="SORTCOL2=' + type + '"]').attr('href').toString();
txtHref = setURLParams(txtHref);
txtHref = updateQueryStringParameter(txtHref, 'PAGE2', 1);
$('tr > th > a[href*="SORTCOL2=' + type + '"]').attr('href', txtHref);
}
function setURLParams(txtHref) {
var urlTxt = window.location.toString();
var urlAry = urlTxt.split("?");
if (urlAry.length > 1) {
urlTxt = urlAry[1];
const searchParams = new URLSearchParams(urlTxt);
for (const key of searchParams.keys()) {
if (key != "SORTCOL2" && key != "SORTDIR2" && key != "PAGE2") {
var val = $.urlParam(key);
txtHref = updateQueryStringParameter(txtHref, key, val);
}
}
}
return txtHref;
}
function updateQueryStringParameter(uri, key, value) {
var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
var separator = uri.indexOf('?') !== -1 ? "&" : "?";
if (uri.match(re)) {
return uri.replace(re, '$1' + key + "=" + value + '$2');
} else {
return uri + separator + key + "=" + value;
}
}
$.urlParam = function (name) {
var results = new RegExp('[?&]' + name + '=([^&#]*)').exec(window.location.search);
return results !== null ? results[1] || 0 : false;
};
// we have to use bootstrap and styling of paging is automatically taken care
//add this extra property in bootstrap .page-link
//I copied all styling related to paging in separate file from bootstrap (cut paste)
.page-link {
float: left;
}



Rama DabburiPosted Apr 26, 2026, 9:42 AM
When you click sorting hyperlink or paging button, the javascript code calculates and crates URL with query string parameters.. the query string params contain sotcolumn, sortdirection and pagenumber... server will extract info from query string parameters using model binding
Rama DabburiPosted Jan 30, 2026, 7:57 AM
When you click a paging button or sorting url, it will hit the server with specified action method in the href.. it will have signature (int PAGE2, string SORTCOL2, string SORTDIR2.. n other search parameters.. values from query string are automatically passed to these parameter...you need to sort entire dataset by sort col n asp per sort dir.. apply paging code and then return the dataset
Rama DabburiPosted Jan 9, 2026, 7:44 AM
I want to share sth - get data into datatable - convert only particular page into list - for i= 40; i < 49 => convert only 10 rows into list .. that will have some performance instead of ORM..
Rama DabburiPosted Dec 17, 2025, 7:59 AM
This code is rendering grids in two to four seconds.. insanely fast.. you can have your own paging buttons and write your own code based on this idea.. its fast because, javascript took some load from razor
Rama DabburiPosted Nov 22, 2024, 10:08 AM
Code for paging shown in diagram .. case 'PREV1': var pageIndex = $(event.target).parent().children().eq(6).val(); var intIndex = parseInt(pageIndex); if (intIndex == 1) { $(event.target).parent().children().eq(1).prop('disabled', true); break; } var intIndex2 = ((intIndex - 1) >= 1 ? intIndex - 1 : 1); $(event.target).parent().children().eq(6).val(intIndex2); txt = updateQueryStringParameter(txt, 'PAGE2', intIndex2); window.location = txt; break; case 'NEXT1': var pageIndex = $(event.target).parent().children().eq(6).val(); var intIndex = parseInt(pageIndex); if (intIndex == TotalPages) { $(event.target).parent().children().eq(4).prop('disabled', true); break; } var intIndex2 = ((intIndex + 1) <= TotalPages ? intIndex + 1 : TotalPages); $(event.target).parent().children().eq(6).val(intIndex2); txt = updateQueryStringParameter(txt, 'PAGE2', intIndex2); window.location = txt; break; case 'PREV5': var pageIndex = $(event.target).parent().children().eq(6).val(); var intIndex = parseInt(pageIndex); if (intIndex == 1) { $(event.target).parent().children().eq(2).prop('disabled', true); break; } var intIndex2 = ((intIndex - 5) >= 1 ? intIndex - 5 : 1); $(event.target).parent().children().eq(6).val(intIndex2); if (intIndex2 == 1) { $(event.target).parent().children().eq(6).attr('disabled', 'disabled'); } txt = updateQueryStringParameter(txt, 'PAGE2', intIndex2); window.location = txt; break; case 'NEXT5': var pageIndex = $(event.target).parent().children().eq(6).val(); var intIndex = parseInt(pageIndex.trim()); if (intIndex == TotalPages) { $(event.target).parent().children().eq(3).prop('disabled', true); break; } var intIndex2 = ((intIndex + 5 < TotalPages) ? intIndex + 5 : TotalPages); $(event.target).parent().children().eq(6).val(intIndex2); txt = updateQueryStringParameter(txt, 'PAGE2', intIndex2); window.location = txt; break; case 'LAST': var pageIndex = $(event.target).parent().children().eq(6).val(); var intIndex = parseInt(pageIndex.trim()); if (intIndex == TotalPages) { $(event.target).parent().children().eq(5).prop('disabled', true); $(event.target).parent().children().eq(6).val(TotalPages); break; } txt = updateQueryStringParameter(txt, 'PAGE2', TotalPages); window.location = txt; break; case 'FIRST': var pageIndex = $(event.target).parent().children().eq(6).val(); var intIndex = parseInt(pageIndex.trim()); if (intIndex == 1) { $(event.target).parent().children().eq(0).prop('disabled', true); $(event.target).parent().children().eq(6).val(1); break; } txt = updateQueryStringParameter(txt, 'PAGE2', 1); window.location = txt; break; default:
Rama DabburiPosted Nov 21, 2024, 11:37 AM
Case 'PREV1': // Logic for previous page break; -- you have to calculate PageNUmber , alter query string text, assign text to window.url.. i will try to post that logic