How To Maintain Scroll Position When Paging Or Sorting A WebGrid

4.56 (9 votes)

This snippet is one in a series showing how to use jQuery to enhance the behaviour of a Web Pages WebGrid. This example shows how to maintain scroll position on the page when paging or sorting the WebGrid.

The problem with the default behaviour of the WebGrid is that when you have AJAX paging and sorting enabled, the user is taken to the top of the page when they click a paging or sorting link. That's because the sorting and paging links are generated with an href value of #, which effectively means "this page", and invariably takes the user to the top of the page because there is no fragment identifier after the # sign. While not wanting to get into a debate about the merits of using anchors when there is no destination, the solution in this case is to provide a fragment identifier, and this is relatively easily accomplished using jQuery. A fragment identifier is added to a URL after the # sign and should correspond with an element with a matching name attribute value.

As with other snippets in this series, this example makes use of the SQL CE 4.0 version of the Northwind database. It assumes that you have a layout page that references jQuery and includes a RenderSection call to an optional section named "script":

<!DOCTYPE html>

<html lang="en">
    <head>
        <meta charset="utf-8" />

        <title>@Page.Title</title>
        <script src="@Href("~/scripts/jquery-1.6.2.min.js")" type="text/javascript"></script>

        <link href="@Href("~/styles/site.css")" rel="stylesheet" />
        @RenderSection("script", required: false)
    </head>

    <body>
        @RenderBody()
    </body>
</html>

The sample page gets data from the database, specifies some columns and an AJAX update container. It includes a loop that runs 30 times, and adds an empty paragraphs each time, which pushes the WebGrid below the bottom of most screens. This forces the scroll bar so that the effectiveness of the solution can be tested. Just before the WebGrid itself, a named anchor has been added. It has been given an identifier of "grid-anchor". The last part of the page is the jQuery. This is examined after the code:

@{
    Page.Title = "Maintain scroll position";
    var db = Database.Open("Northwind");
    var query = "SELECT * FROM Customers";
    var data = db.Query(query);
    var columns = new[]{"CustomerID", "CompanyName", "ContactName", "Address", "City", "Country", "Phone"};
    var grid = new WebGrid(data, ajaxUpdateContainerId: "grid", columnNames: columns);
}
<h1>Maintain Scroll Position</h1>
@for(var i = 1; i <= 30; i++){
    <p>&nbsp;</p>
}
<a name="grid-anchor"></a>
<div id="grid">
    @grid.GetHtml(    
        tableStyle : "table",
        alternatingRowStyle : "alternate",
        headerStyle : "header"
    )
</div>
@section script{
<script type="text/javascript">
    $(function(){
        $('th a, tfoot a').live('click', function(){
            $(this).attr('href', '#grid-anchor');
        });
    });
</script>    
}

The sorting and paging links appear in the thead and tfoot elements of the grid. The jQuery targets anchor elements in the thead and tfoot only, and alters their href value to include a fragment identifier - grid-anchor, which ensures that when the links are clicked, the user is navigated back to the named anchor position, thus maintaining scroll position. The click event handler is bound to the links using the live command, which ensures that all future links are affected - essential when the target elements are replaced during an AJAX partial update.

A demo containing the source code is available here.

 

You might also like...

Date Posted:
Last Updated:
Posted by:
Total Views to date: 26051

3 Comments

- reav

timesaver! thx!

- wmeyer

Thanks, exactly what I needed.
To make it so the scroll position doesn't change at all you could lose the "grid-anchor" anchor and change the js line to this: $(this).attr('href', 'javascript:void(0)');

- Mike

@wmeyer

The following also works without named anchors:

$(function(){
$('th a, tfoot a').live('click', function(){
return false;
});
});

Recent Comments

Sivu 19/10/2016 08:21
In response to Entity Framework Core TrackGraph For Disconnected Data
Oh that's very very very nice ! Thanks for the write up Mike, much appreciated for the taking the to...

Mark 12/10/2016 16:42
In response to ASP.NET Web Pages vNext or Razor Pages
Although "Web Pages" was removed from the roadmap, has it just been renamed to "Razor Pages"?...

Satyabrata 12/10/2016 09:20
In response to Entity Framework Core TrackGraph For Disconnected Data
Nice article. Please write more articles featuring ASP.Net web pages. Thank you...

Julian 26/09/2016 14:27
In response to Loading ASP.NET Core MVC Views From A Database Or Other Location
Fantastic, many thanks Mike! Had got half way down this road before finding your article - saved...

Abolfazl Roshanzamir 14/09/2016 05:36
In response to Loading ASP.NET Core MVC Views From A Database Or Other Location
Nice article. Thanke you so much ....

cyrus 02/09/2016 15:12
In response to ASP.NET Web Pages vNext or Razor Pages
I've got some news. As Damian stated in this link: https://github.com/aspnet/Mvc/issues/5208 “We...

Simon 01/09/2016 08:00
In response to Loading ASP.NET Core MVC Views From A Database Or Other Location
Thanks Mike, nice post and exactly what I was looking for. Like you said, I think I'll opt to the...

dave 20/08/2016 14:57
In response to ASP.NET Web Pages vNext or Razor Pages
Do SimplemembershipProvider in viewpages is supported?...

Steven 18/08/2016 04:40
In response to Entity Framework Code First and Stored Procedures
Can you provide the directives (using statements) you're using for EF7 example?...

yousaid 17/08/2016 22:08
In response to ASP.NET Web Pages vNext or Razor Pages
Increasingly, learning a Microsoft tool is no longer worth the return on investment. Too many tools...