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: 25476

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

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...

jared 12/08/2016 05:54
In response to ASP.NET Web Pages vNext or Razor Pages
hi mike, just for clarification, is viewpages something different from webpages? is webpages still...

Jocke 08/08/2016 20:37
In response to Loading ASP.NET Core MVC Views From A Database Or Other Location
Good post! If this was to be implemented in a CMS where users can change the view files, how would I...

cyrus 05/08/2016 19:49
In response to ASP.NET Web Pages vNext or Razor Pages
I think adding these features to webpages make it complicated. msft forget webpages goal so we move...

Curt Smith 27/07/2016 20:38
In response to ASP.NET Web Pages vNext or Razor Pages
I am only slightly disappointed to hear that WebMatrix is officially dead, because I suspected this...

Darshan Raj L G 27/07/2016 13:20
In response to Implementing SQL Server Full-Text Search In An ASP.NET MVC Web Application With Entity Framework
I though it would be more helpful for somebody who wants to work with Entity Framework... please EF...

Satyabrata 25/07/2016 08:09
In response to Loading ASP.NET Core MVC Views From A Database Or Other Location
Very Interesting!!...

Jerrie Pelser 23/07/2016 05:08
In response to Loading ASP.NET Core MVC Views From A Database Or Other Location
Very cool concept Mike!...