IT/.NET

AJAX Maintain Scroll Position from a Partial Page Update

SJ.. 2011. 10. 28. 00:15

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



Biography - erik little
Have worked in the building industry for 23+ years.
My day to day job role is:
CEO of AFCC Inc., Custom Home Builder, .Net Developer, Sql Server Developer

afccinc.com Storefront Doors 
There’s my side and there’s your opinion




Didn't Find The Answer You Were Looking For?

EggHeadCafe has experts online right now that may know the answer to your question.  We pay them a bonus for answering as many questions as they can.  So, why not help them and yourself by becoming a member (free) and ask them your question right now?
Ask Question In Live Forum

Article Discussion: Shows how to Maintain Scroll Position from a Partial Page Update - Using Ajax
erik little posted at Saturday, February 03, 2007 12:45 PM
Original Article
 

Maintain scroll Position
raj ron replied to erik little at Friday, February 16, 2007 8:16 AM

Thanks the article is great....one question is ..

1. I wanted to use the smae stuff in a web page which is part of the master page, so I added the script under content provider. Second I removed of the serverstatus as it was not required in my case still I am not able to get the required functionality...any thing I am missing..

 

One place to look is to make sure that you have the all
erik little replied to raj ron at Friday, February 16, 2007 10:01 AM

java script that works with the script manager at the bottom of the page.

If you already have this, please post you relevant code..

 

Erik

 

Scroll Position and Multiple Updates
Joe Reynolds replied to erik little at Tuesday, February 27, 2007 9:58 PM

I have an aspx page that contrains multiple asp panels and within an ajax update panel. All works ok with ajax except a scroll position problem.

Let's say the user begins with Panel1 visible and is scrolling through a page. Then user clicks a link and Panel 1 is hidden and Panel 2 becomes visible. User then clicks on link that hides Panel 2 and makes Panel 1 visible again.

What I need to accomplish is to have Panel 1 return to the same scroll position it was in when the user originally clicked and hid it.

I use Strength Controls ScrollLock control for this in a non-ajax version of the page, but this control fails with ajax.

 

BeginRequestHandler blocking code behind event execution
Scott Bean replied to erik little at Wednesday, June 27, 2007 9:04 AM

Erik -

Great solution. I've been trying to find an elegant solution to the maintain scroll position across ajax partial page updates for a while. But, in my case, it's not exactly working. Thought maybe you could tell me what I'm doing wrong.

I have a panel with a vertical scroll bar containing a radiobuttonlist. That is the panel that I need to maintain scroll position. That panel is contained in an ajax UpdatePanel which is contained in a Content page under a Master page. Since I don't have an <html> section in my content page, I placed the javascript at the end of the page just before the </asp:Content> tag. If I try to place the javascript after that tag, the compiler generates an error.

The problem that I am having is that the BeginRequestHandler is preventing my code behind events from be triggered. If I comment out the ...add_beginRequest... line of code, then my code behind events trigger. Do you know why and what I need to do the fix this?

Thanks!

Scott 

 

asp:panel tag vs. html tag
Scott Bean replied to erik little at Wednesday, June 27, 2007 12:54 PM
I found that my problem is that the javascript cannot find my asp:panel control using document.getElementById. Does anyone know to implement this javascript solution using the asp:panel control for scrolling?
 

Works Like a Charm
Breaker Morant replied to erik little at Saturday, July 14, 2007 11:58 AM

I had been scouring the Internet trying to find a non-complicated way to maintain scroll for several div/asp:panel elements on a page (i.e., without writing out pages of javascript).  Your solution was the only one that worked!  Thanks a bunch.

 

Glad that i could help
erik little replied to Breaker Morant at Saturday, July 14, 2007 12:14 PM
Erik
 

My Solution with an ASP.NET Panel Control
Breaker Morant replied to erik little at Saturday, July 14, 2007 12:23 PM

This is how I made mine work, with only a little bit of javascript generated from a vb.net code-behind page.  My pages have multiple panel controls, and it kept irking me that they would always scroll back to their respective tops after a postback.  This is a modification of the solution presented earlier.  All credit due to Mr. Little.

Private Shared csm As ClientScriptManager

Public Shared Sub load_scroll(ByVal p As Page, ByVal pnl As Panel)

csm = p.ClientScript

Dim sb As New StringBuilder

sb.AppendFormat("var scroll_top_{0};", pnl.ClientID)

sb.AppendLine()

sb.AppendFormat("var scroll_left_{0};", pnl.ClientID)

sb.AppendLine()

sb.AppendLine()

sb.AppendFormat("Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(BeginRequestHandler_{0});", pnl.ClientID)

sb.AppendLine()

sb.AppendFormat("Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler_{0});", pnl.ClientID)

sb.AppendLine()

sb.AppendLine()

sb.AppendFormat("function BeginRequestHandler_{0}(sender, args)", pnl.ClientID)

sb.AppendLine()

sb.AppendLine("{")

sb.AppendFormat("var elem = document.getElementById('{0}');", pnl.ClientID)

sb.AppendLine()

sb.AppendFormat("scroll_top_{0} = elem.scrollTop;", pnl.ClientID)

sb.AppendLine()

sb.AppendFormat("scroll_left_{0} = elem.scrollLeft;", pnl.ClientID)

sb.AppendLine()

sb.AppendLine("}")

sb.AppendLine()

sb.AppendLine()

sb.AppendFormat("function EndRequestHandler_{0}(sender, args)", pnl.ClientID)

sb.AppendLine()

sb.AppendLine("{")

sb.AppendFormat("var elem = document.getElementById('{0}');", pnl.ClientID)

sb.AppendLine()

sb.AppendFormat("elem.scrollTop = scroll_top_{0};", pnl.ClientID)

sb.AppendLine()

sb.AppendFormat("elem.scrollLeft = scroll_left_{0};", pnl.ClientID)

sb.AppendLine()

sb.AppendLine("}")

sb.AppendLine()

If Not csm.IsStartupScriptRegistered(pnl.ClientID) Then

csm.RegisterStartupScript(p.GetType, pnl.ClientID, sb.ToString, True)

End If

End Sub

 

Please let me know if there any bugs with this.

 

Everything looks great line for line
erik little replied to Breaker Morant at Saturday, July 14, 2007 12:32 PM
I am assuming that the java is getting appended to the bottom of the page, because you said it works....


i am going to add your code behind to my library....

Happy Coding!

Erik
 

TreeView with AJAX
Harish Chintapalli replied to erik little at Friday, October 05, 2007 10:13 AM

Hi,

This article is great and is just what I am looking for.

I am trying to customize it so the TreeView has different expand and collapse images for the root as well for all the parent folders by using "OnTreeNodeExpanded" and "OnTreeNodeCollapsed" events. When I remove the "UpdatePanel" the TreeView works great. But when I add it "OnTreeNodeCollapsed" event fires even when I expand the root folder there by never showing full tree. Why does it behave so? What is that I am missing? Here is the code:

 

ASPX

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<%@ Register Assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" Namespace="System.Web.UI" TagPrefix="asp" %>

<html>

<head>

<title>Populating TreeView Nodes On Demand Using Page Titles</title>

<link rel="stylesheet" href="/aspxtreme/shared/netdemos.css">

</head>

<body>

<div class="header"><h3>Populating TreeView Nodes On Demand Using Page Titles</h3></div>

<form id="Form1" runat="server">

<p id="msg">This example demonstrates using the TreeView <i>PopulateOnDemand</i> feature to programmatically create TreeNodes from the file system of the application that contains this sample. Here the TreeNodes display page titles instead of file names. </p>

<asp:ScriptManager runat="server"></asp:ScriptManager>

<asp:UpdatePanel runat="server">

<ContentTemplate>

<asp:treeview id="Treeview1" runat="server"

imageset="XPFileExplorer"

nodestyle-horizontalpadding=3

showlines="false"

expanddepth=1

onTreeNodePopulate="PopulateNode" OnTreeNodeExpanded="ExpandTreeNode" OnTreeNodeCollapsed="CollapseTreeNode">

<nodes>

<asp:treenode text="ASPXtreme" value="~/" populateondemand="true" />

</nodes>

</asp:treeview>

</ContentTemplate>

</asp:UpdatePanel>

</form>

</body>

</html>

Code behind:

using System;

using System.Web.UI.WebControls;

using System.IO;

using System.Text.RegularExpressions;

public partial class _Default : System.Web.UI.Page

{

protected void PopulateNode(Object source, TreeNodeEventArgs e)

{

TreeNode node = e.Node;

string fullPath = Request.MapPath(node.Value, Request.ApplicationPath, false);

// enumerate directories

string[] dirs = Directory.GetDirectories(fullPath);

foreach (string dir in dirs)

{

string virtualDir = node.Value.TrimEnd('/') + "/" + Path.GetFileName(dir);

if (virtualDir.IndexOf("admin") == -1)

{

TreeNode newNode = new TreeNode(Path.GetFileName(dir), virtualDir);

if (Directory.GetFiles(dir, "*.asp?").Length > 0 || Directory.GetDirectories(dir).Length > 0)

{

newNode.PopulateOnDemand = true;

node.ChildNodes.Add(newNode);

}

}

}

// enumerate files

string[] files = Directory.GetFiles(fullPath, "*.asp?");

foreach (string file in files)

{

if (file.IndexOf(".aspx.") == -1)

{

// open web page

System.Net.WebRequest request = System.Net.WebRequest.Create(file);

System.Net.WebResponse response = request.GetResponse();

StreamReader reader = new StreamReader(response.GetResponseStream());

string page = reader.ReadToEnd();

reader.Close();

response.Close();

// get page title

string title = Regex.Match(page, "<title>(?<title>[^<]+)</title>",

RegexOptions.IgnoreCase).Groups["title"].Value;

if (title != "")

{

TreeNode newNode = new TreeNode(title, Path.GetFileName(file));

newNode.NavigateUrl = "~/" + file.Substring(Request.PhysicalApplicationPath.Length);

node.ChildNodes.Add(newNode);

}

}

}

}

protected void ExpandTreeNode(object sender, TreeNodeEventArgs e)

{

if (e.Node.Parent == null)

e.Node.ImageUrl = "~/Images/RootFolderOpened.gif";

else

e.Node.ImageUrl = "~/Images/ParentFolderOpened.gif";

}

protected void CollapseTreeNode(object sender, TreeNodeEventArgs e)

{

if (e.Node.Parent == null)

e.Node.ImageUrl = "~/Images/RootFolderClosed.gif";

else

e.Node.ImageUrl = "~/Images/ParentFolderClosed.gif";

}

}

 

Appreciate your help and thanks,

Harish.

 

You do not need my solution for your situation
erik little replied to Harish Chintapalli at Sunday, October 07, 2007 8:52 PM
All you need is just the updatepanel and the scriptmanager. I think you need to add some attributes to the scriptmanager for it to work.

Erik
 

Ajax + TreeView = Wrong Scroll position
Manuel Arbulú replied to erik little at Wednesday, October 17, 2007 1:32 PM

Hi Erick, i've used your code inside an aspx page with an UpdatePanel and a Treeview, but the scroll position after postbacks with SelectedNode event is wrong.

Here is my code

aspx page:


<asp:UpdatePanel id="trvPanel" runat="server" UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="mnuPrincipal" EventName="MenuItemClick" />
</Triggers>
<contenttemplate>
<asp:Panel ID="EmpresasPanel" runat="server" Height="650px" ScrollBars="Auto" BorderColor="#E0E0E0" BorderStyle="Solid" BorderWidth="1px">
<asp:TreeView id="trvEmpresas" runat="server" Width="376px" Height="600px" ShowLines="True" AutoGenerateDataBindings="False"OnSelectedNodeChanged="trvEmpresas_SelectedNodeChanged" NodeWrap="True">
<LevelStyles>
<asp:TreeNodeStyle Font-Underline="False" ImageUrl="~/images/empresa.gif" />
<asp:TreeNodeStyle Font-Underline="False" ImageUrl="~/images/grupo.gif" />
<asp:TreeNodeStyle Font-Underline="False" ImageUrl="~/images/user.gif" />
</LevelStyles> 
<SelectedNodeStyle Font-Bold="True" /> 
<HoverNodeStyle BackColor="#E0E0E0" /> 
</asp:TreeView> 
</asp:Panel> 
</contenttemplate>
</asp:UpdatePanel>

And this is my codebehind method that puts the startup script

private void AddScrollScript()
{
string tvScript = "TreeViewScript";
Type cstype = this.GetType();
ClientScriptManager cs = Page.ClientScript;
if (!cs.IsStartupScriptRegistered(cstype, tvScript))
{
   StringBuilder cstext = new StringBuilder();
   cstext.AppendFormat(
"var scroll_top_{0};", trvPanel.ClientID);
   cstext.AppendLine();
   cstext.AppendFormat(
"var scroll_left_{0};", trvPanel.ClientID);
   cstext.AppendLine();
   cstext.AppendFormat(
"Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(BeginRequestHandler_{0});", trvPanel.ClientID);
   cstext.AppendLine();
   cstext.AppendFormat(
"Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler_{0});", trvPanel.ClientID);
   cstext.AppendLine();
   cstext.AppendFormat(
"function BeginRequestHandler_{0}(sender, args)", trvPanel.ClientID);
   cstext.AppendLine(
"{");
   cstext.AppendFormat(
" var elem = document.getElementById('{0}');", trvPanel.ClientID);
   cstext.AppendLine();
   cstext.AppendFormat(
" scroll_top_{0} = elem.scrollTop;", trvPanel.ClientID);
   cstext.AppendLine();
   cstext.AppendFormat(
" scroll_left_{0} = elem.scrollLeft;", trvPanel.ClientID);
   cstext.AppendLine();
   cstext.AppendLine(
"}");
   cstext.AppendFormat(
"function EndRequestHandler_{0}(sender, args)", trvPanel.ClientID);
   cstext.AppendLine(
"{");
   cstext.AppendFormat(
" var elem = document.getElementById('{0}');", trvPanel.ClientID);
   cstext.AppendLine();
   cstext.AppendFormat(
" elem.scrollTop = scroll_top_{0};", trvPanel.ClientID);
   cstext.AppendLine();
   cstext.AppendFormat(
" elem.scrollLeft = scroll_left_{0};", trvPanel.ClientID);
   cstext.AppendLine();
   cstext.AppendLine(
"}");
   cstext.AppendLine();
   cs.RegisterStartupScript(cstype, tvScript, cstext.ToString(), 
true);
}
}

And in the generated page the startup script is well placed and well generated as the code i show you here

<script type="text/javascript">
<!--
var scroll_top_trvPanel;
var scroll_left_trvPanel;
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(BeginRequestHandler_trvPanel);
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler_trvPanel);
function BeginRequestHandler_trvPanel(sender, args){
   var elem = document.getElementById('trvPanel');
   scroll_top_trvPanel = elem.scrollTop;
   scroll_left_trvPanel = elem.scrollLeft;
}
function EndRequestHandler_trvPanel(sender, args){
   var elem = document.getElementById('trvPanel');
   elem.scrollTop = scroll_top_trvPanel;
   elem.scrollLeft = scroll_left_trvPanel;
}

WebForm_InitCallback();var trvEmpresas_Data = new Object();
trvEmpresas_Data.images = trvEmpresas_ImageArray;
trvEmpresas_Data.collapseToolTip = "Collapse {0}";
trvEmpresas_Data.expandToolTip = "Expand {0}";
trvEmpresas_Data.expandState = theForm.elements['trvEmpresas_ExpandState'];
trvEmpresas_Data.selectedNodeID = theForm.elements['trvEmpresas_SelectedNode'];
trvEmpresas_Data.hoverClass = 'trvEmpresas_9';
trvEmpresas_Data.hoverHyperLinkClass = '';
for (var i=0;i<19;i++) {
var preLoad = new Image();
if (trvEmpresas_ImageArray[i].length > 0)
preLoad.src = trvEmpresas_ImageArray[i];
}
trvEmpresas_Data.lastIndex = 17;
trvEmpresas_Data.populateLog = theForm.elements['trvEmpresas_PopulateLog'];
trvEmpresas_Data.treeViewID = 'trvEmpresas';
trvEmpresas_Data.name = 'trvEmpresas_Data';

theForm.oldSubmit = theForm.submit;
theForm.submit = WebForm_SaveScrollPositionSubmit;

theForm.oldOnSubmit = theForm.onsubmit;
theForm.onsubmit = WebForm_SaveScrollPositionOnSubmit;
Sys.Application.initialize();
// -->
</script>

The question is, What am i missing or what am I doing wrong?

Regards.

Manolo Arbulu

 

A quick question
Joe Fro replied to erik little at Sunday, October 21, 2007 8:50 PM
Excellent solution, works great.  I had to use

var elem = document.getElementById('<%= this.gvPanel.ClientID %>');

elem.scrollTop = scrollTop;

to get access to my scrollable panel, I have a gridview within the panel so the gridview is scrollable.  My problem is that I dont want the scroll position maintained on every post back, for example when i rebind my grid with new data, i want the scroll position to return to the top, you would think this would be as simple as adding this to my code behind:

StringBuilder sb = new StringBuilder();

sb.Append("<script language='javascript'>");

sb.Append("var thePanel = document.getElementById('<%= this.gvPanel.ClientID %>');");

sb.Append("thePanel.scrollTop = 0;");

sb.Append("</script>");

Type t = this.GetType();

if (!Page.ClientScript.IsClientScriptBlockRegistered(t, "ResetScroll"))

Page.ClientScript.RegisterClientScriptBlock(t, "ResetScroll", sb.ToString());

But for some reason there is a javascript error saying that thePanel is null, even though this same exact code works in the html.  Is there an easier way of reseting the scroll position, or do you have any pointers?  It would be much appreciated, cant figure this out.  Thank you!

 

The script manager that
erik little replied to Joe Fro at Tuesday, October 23, 2007 12:39 PM
is in your document is what maintains your ajax object model (Only the ScriptManager know where ALL the element's are located at all time's). So what you are trying to do here is introduce new java that your document can not process. When you return back from the server with this new javascript your document has no idea what is going on. As far as it know's nothing even happened.
That is why i used the add_beginRequest(BeginRequestHandler); What this statement is saying is "Hey ScriptManager, please let me know when you have received the beginning of a new request to the server" The programming model is not the same when using ajax. You must communicate directly when the ScriptManager from any area inside the update panel.

-----Your resources are all Here
http://ajax.asp.net/docs/ClientReference/Sys.WebForms/PageRequestManagerClass/default.aspx 
****You can receive parameter's back from a request. I would recommend that you pass a Flag to the begin request so that when you receive that end request you can unpack the parameter and check if you need to reset the scroll position or not.


Look at this example:
http://asp.net/AJAX/Documentation/Live/ViewSample.aspx?sref=Sys.WebForms.PageRequestManager.endRequest/cs/default.aspx 
You will noticed that in the part where the author is setting the endrequest that they are passing a String parameter.
    <script type="text/javascript" language="javascript">
var divElem = 'AlertDiv';
var messageElem = 'AlertMessage';
var bodyTag = 'bodytag';
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
function ToggleAlertDiv(visString)
{
i

Your almost there .... you just need a Flag....

Just remember when you working with update panels that you can not directly program to any other part of the DOM after your first request to the server, because , your document has no idea about the NEW HTML.

****Ajax is tricky .... will have to code slow...
 

thank you
Joe Fro replied to erik little at Tuesday, October 23, 2007 12:18 PM

Thank you for the quick reply, what you said makes sense and i will have a look at those links.  And i completely agree, asp.net programming alone is fairly simple, when you add AJAX, it is a different thought process.  Thanks!

 

Joe

 

Scroll Maintain Updated for .NET 3.5 (VB.NET)
Breaker Morant replied to erik little at Saturday, January 26, 2008 4:37 PM

I modified my original code to use an shared function (returns string) and a .NET 3.5 extension method which extends an ASP.NET Panel control to maintain scroll position between postbacks.  Make sure that the extension method is enclosed within a public-scoped Module for VB or public static class for C#. Once again, much respect due to Mr. Little.

Protected Sub Page_Load(ByVal sender As ObjectByVal e As EventArgs) Handles Me.Load

pnlProducts.LoadScroll(Me)

' or

ScriptManager.RegisterStartupScript(MeMe.GetType, "scrollLoad", LoadScroll(pnlProducts), True)

End Sub

Public Module JavaScript

Public Function LoadScroll(ByVal panel As Panel) As String

Dim sb As New StringBuilder

sb.AppendFormat("var scrollTop{0};", panel.ClientID)

sb.AppendFormat("var scrollLeft{0};", panel.ClientID)

sb.AppendFormat("Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(BeginRequestHandler{0});", panel.ClientID)

sb.AppendFormat("Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler{0});", panel.ClientID)

sb.AppendFormat("function BeginRequestHandler{0}(sender, args)", panel.ClientID)

sb.Append("{")

sb.AppendFormat("var elem=document.getElementById('{0}');", panel.ClientID)

sb.AppendFormat("scrollTop{0}=elem.scrollTop;", panel.ClientID)

sb.AppendFormat("scrollLeft{0}=elem.scrollLeft;", panel.ClientID)

sb.AppendLine("}")

sb.AppendFormat("function EndRequestHandler{0}(sender, args)", panel.ClientID)

sb.AppendLine("{")

sb.AppendFormat("var elem=document.getElementById('{0}');", panel.ClientID)

sb.AppendFormat("elem.scrollTop=scrollTop{0};", panel.ClientID)

sb.AppendFormat("elem.scrollLeft=scrollLeft{0};", panel.ClientID)

sb.AppendLine("}")

Return sb.ToString

End Function

   <Extension()>

   Public Sub LoadScroll(ByVal panel As Panel, ByVal page As Page)

      Dim s As String = LoadScroll(panel)

      If Not page.ClientScript.IsStartupScriptRegistered(panel.ClientID) Then

page.ClientScript.RegisterStartupScript(page.GetType, panel.ClientID, s, True)

   End If

   End Sub

End Module

 

 

Master pages
Kin Regtur replied to Breaker Morant at Thursday, July 31, 2008 5:52 AM
Hello All,

I have used the next code in my content page.

<input id="scrollPos" type="hidden" />
    <script type="text/javascript" language="javascript">
        Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
        function EndRequestHandler(sender, args) {
            var ScrollTopValue=document.getElementById("scrollPos").value;
            document.getElementById('leftBar').scrollTop=ScrollTopValue;
        }
        function saveScrollPos(){
            var elem = document.getElementById('leftBar');
            scrollTop=elem.scrollTop;
            document.getElementById("scrollPos").value= scrollTop;
        }
    </script>
</asp:Content>

this works in combination with masterpages.
Regards Bart
PS: don't forget <div id="leftBar" onscroll="saveScrollPos();"   class="DV_ProductMenu">
 

help?
Eric Hunter replied to Breaker Morant at Tuesday, October 07, 2008 11:52 AM
How do I get my asp:panel to reference your codebehind?  I've been beating my head against my monitor for DAYS trying to find a solution for this. 
 

Error?
Eric Hunter replied to Breaker Morant at Tuesday, October 07, 2008 4:51 PM

Breaker, This is working great! Thank you so much!  The only problem I'm getting now is that when I scroll one of my panels an error comes up in the status bar that says:

Line: 74

Char: 1

Error: Object expected

Code:0

URL: ~my page's url

I check the source and on line 74 it has:

<script src="/Audit/ScriptResource.axd?d=8tHd7lmodXBiFUj-lZM0qNIZbCsI0VoojanxW7SE5MVD4jeaeiKTtcPqdDmacV5qVsBqS22-fVSBmFjlN5Ashw5LKopBiVdL8__WlepFViQ1&amp;t=ffffffffcb92c336" type="text/javascript"></script>

any clues?

 

NEVER MIND...
Eric Hunter replied to Eric Hunter at Tuesday, October 07, 2008 5:06 PM
I had  a left over "onscroll=" in my tag for the panel.  All is well.
 

Maintain position for multiple gridviews
Colin Kennedy replied to erik little at Thursday, October 09, 2008 10:35 AM
Eric,

This code works perfectly in my situation but I have a couple of pages with more than one gridview on the page. Each gridview has a div wrapper with a unique id. How can I apply your code to all of the gridviews on the page?

Colin Kennedy