Easily maintaining scroll position in GridView using jQuery

Sometimes when working with small record sets. especially when they tend not to grow much, paging GridView, while an attractive option, isn’t very helpful to end-users. My typical solution to this is to enclose the GridView in a scrollable container and let the user scroll through the rendered record set.

This solution will suffice, but say you have a link for each row on the grid which when clicked would cause a post-back and open up a modal popup to edit a record in the grid. The obvious problem here is that the GridView control simply won’t maintain the scroll position and will throw the user back to the first record as soon as the post-back completes.

I will show the easiest way to fix this in a non-Ajaxian setup. Here’s everything you’ll need.

<script type="text/javascript" language="javascript">  
    var scroll = {
        Y: '#<%= hfScrollPosition.ClientID %>'
    };

    $(document).ready(function () {
        $("#scrollable-container").scrollTop($(scroll.Y).val());
    });
</script>

<style type="text/css">  
.scrollable-container {
    height: 460px;
    width: 100%;
    overflow: auto;
    border: 0;
}
</style>

<div id="scrollable-container" class="scrollable-container" onscroll="$(scroll.Y).val(this.scrollTop);">  
    <asp:GridView ID="gvLineDisplay" runat="server"></asp:GridView>
    <asp:HiddenField ID="hfScrollPosition" runat="server" Value="0" />
</div>  

So, how does this work? The main part here is the server-side HiddenField control called hfScrollPosition, which as the name suggests contains the scroll position of our GridView. Using a server-side control here takes care of carrying our scroll position between postbacks as it will simply be submitted in the post.

What we’re looking to do is save the scroll position into this hidden field as it changes. We do this by hooking into the client-side onscroll event of the scrollable div container.

The rest of this is simple jQuery scripting. We resolve the HiddenField control’s client ID into scroll.Y javascript variable. This simple trick allows us to access a rendered server-side control on the client side without actually knowing its dynamic ID. (This is obviously not an issue in ASP.NET 4.0 with introduction of ClientIDMode control attribute).

We then use this short-hand javascript “notation” to write the scroll position into the HiddenField in the onscroll event of the div container. When the page containing our GridView posts back, the value of the HiddenField control is carried through and then applied back to the scrollable div container in jQuery’s ready() event, which fires when DOM finishes loading.

Finito!