ASP.NET AJAX Maintain Scroll Position from a Partial Page Update

How to Maintain Scroll Position from a Partial Page Update - Using Ajax.

On and off for a while now I have worked with the new ajax technology trying to gain as much of an understanding of one of the coolest features in web development today. If it makes a sh#$ in my personal opinion I find ajax to be one of the most powerful new tools available to developers today. To be able to request and display, on the client, a document from a server once; and then request parts of that document in Subsequencial request to the server is powerful in my book. Any one who has a slight understanding of the DOM should see the beauty of ajax.

So here was my dilemma; I needed to make a picture viewer / navigator so that resent project pictures could be viewed on a webform. There is nothing fancy about this viewer, just a leftBar column for the selection (A treeView), and a viewer on the right (iframe) PICTURE of VIEWER. Since the pictures that needed to be viewed are rather large in size, the first thing that came to my mind was ajax. So I wrapped my little picture viewer with the updated panel and fired up VS to test this bad boy out. Everything worked great! My selector(treeView) and the pictureViewer(iframe) all responded correctly. 1. Choose a thumbNail on the left  .... 2. ImageControl displays the larger image on the right. Ajax made it very obivous that using it;s updatePanel to do a parcel update was the right choice. After over coming this excitment, and calling the president for an emergency meeting to discuss my new findings I noticed one little thing. That when every parcel update was complete that I had lost my scroll position with-in the selector; therefore, after every selection from the selector I had to rescroll to my previous selection back into view. Obviously this would not work in a production enviroment.

After searching the internet for a solution for a month or so I found my answer here THE AJAX SITE. Apparently when the updatePanel updates it's contents and rebuilds that portion of the DOM the brower is unaware of this and there is no way to get notifications from any part of an update panel after an update has occurred. Thats where the  client-script libraries that MS distributes comes into play. With-in this library there are two big players for my scenario... 1.Sys.WebForms.PageRequestManager beginRequest Event -- 2. Sys.WebForms.PageRequestManager endRequest Event, and of course the ScriptManager that has to be on every page that a UpdatePanel is on (Or if you are using a masterpage you may use a ScriptManagerProxy). One important thing to keep in mind is that all of the magic is handled by the ScriptManager. The ScriptManager is the link between the client and the server. So by registering for the beginRequest and the endRequest events that are exposed by the ScriptManger I am able to be notified before my UpdatePanel goes back to the server and I am once again notified when the response returns back to the client. “Just in case you need to know the endRequest is the last event that is available during this parcel request lifecycle, if you would like to be notified BEFORE the new parcel content is rendered you can register with the Sys.WebForms.PageRequestManager.pageLoading or the Sys.WebForms.PageRequestManager.pageLoaded events.

---Here is the complete JavaScript code that is used in my scenario---

<script type="text/javascript">

var scrollTop;

Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(BeginRequestHandler);

Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);

 

function BeginRequestHandler(sender, args)

{

var elem = document.getElementById('leftBar');

scrollTop=elem.scrollTop;

var status = document.getElementById('serverStatus');

status.style.visibility='visible';

}

 

function EndRequestHandler(sender, args)

{

var elem = document.getElementById('leftBar');

elem.scrollTop = scrollTop;

var status = document.getElementById('serverStatus');

status.style.visibility='hidden';

}

</script>

--------------------------
If you are thinking to yourself, "WOW that looks alot like the Page Model in .net." Well, my dear Watson you would be correct. I am not going to get into the many different methods that are available with-in this client-script libraries; but from my point of view it is worth your time to check this baby out.

So, now with the code above I am able to get the scrollTop position of my selector(treeView) before the parcel update occurs. And when the update returns I am once again notified and i can set the selector (newly rebuilt treeView) back to it's original position for viewing pleasure.

----------The Selector (treeView)--------------------

<%------------The TreeView--------------%>
  
    <div id="PicChMain">
        <div style="overflow-y: scroll" id="leftBar">
           
            <asp:TreeView ID="tvProjects"    runat="server" OnSelectedNodeChanged="tvProjects_SelectedNodeChanged"
                NodeIndent="30">
                <Nodes>
                    <asp:TreeNode Text="-Project List" Value="Project List" ImageUrl="~/Imgs/openfolderHS.png"
                        Selected="True"></asp:TreeNode>
                </Nodes>
            </asp:TreeView>
           
 <%------------The TreeView--------------%>

-----------------------------------------------------

----------The Viewer(iframe)--------

   </div>
        <div id="PicViewer">
            <asp:Panel ID="panPicViewer" runat="server" Width="583px" Height="50px">
                <iframe id="projectViewer" height="400" width="576" scrolling="no" runat="server"
                    frameborder="0" src="Projects/Project[00]/SmallPic/100_2293 (Small).jpg"></iframe>
            </asp:Panel>
        </div>
    </div>

-----------------------------------------------------------------------

I have attached a project with this article that demonstrates this same need but with a gridView and a treeview.

Working Example: http://www.eggheadcafe.com/fileupload/215296388_UpdatePanel-EndRequest.zip

Ever wonder where ajax and parcel page updates fit into the page lifecycle?
Check this out
--- http://techblog.muthuka.com/wp-content/uploads/2006/12/beantown_ajax.ppt#302,17,ASP.NET Page Life Cycle

By Erik Little   Popularity  (33623 Views)