Link to home
Start Free TrialLog in
Avatar of baijajusav
baijajusav

asked on

positioning the scroll bar of a given div in Firefox and I.E


I'm working on an ASP .NET Ajax chatroom. It's pretty much up and running out side of a few issues. The biggest is that chat messages get written to a div on the form called divMessages. When enough chat messages are present, the scroll bar appears.

This being a chatroom, a timer control is linked to my UpdatePanel. The problem is that every time the timer fires, the scroll bar shoot back to the top of the div. I need the scrollbar to be positioned at the bottom most portion of the div at the very least. Best case scenerio would be for it to stay wherever it was after being scrolled.

I am using the javascript function below and calling it in the onload and onresize events of the div. It still does not seem to work. I open for suggestions or work arounds.

Thanks for your time, experts!

Also, no javascript errors are being thrown.
function SetScrollPosition() {            
            var div = document.getElementById('divMessages');
            div.scrollTop = 100000000000;
        }

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of JohnSixkiller
JohnSixkiller
Flag of Czechia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of baijajusav
baijajusav

ASKER


Okay, I'm working on a project based on the article here:

http://www.codeproject.com/KB/ajax/PersistDIVScrollPosition.aspx

I didn't see a download for code so I setup a new one. I'm getting an error saying that scrollPos is defined twice. Specifically it says:

Error      1      The type '_Default' already contains a definition for 'scrollPos'      C:\DivScrollSaving\Default.aspx.cs      14      27      C:\DivScrollSaving\


See my code below.
////////////////////Default.aspx.cs
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text;
 
public partial class _Default : System.Web.UI.Page 
{
     public static string scrollPos = String.Empty;
 
    protected void Page_Load(object sender, EventArgs e)
    {
         String line = " THIS IS JUST A LINE OF TEXT MEANT TO TAKE UP A LINE. ";
         StringBuilder sb = new StringBuilder();
         for (int i = 0; i < 30; i++)
              sb.Append(line);
 
         lit.Text = sb.ToString();
 
         scrollPos = ((HtmlInputHidden)scrollPos).ClientID.ToString();
 
    }
}
 
///////////Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
     <script type="text/javascript" language="javascript">
          Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
          function EndRequestHandler(sender, args) {
              setScrollPos();
          } 
          function saveScrollPos(){
              document.getElementById("<%=scrollPos%>").value = 
                          document.getElementById("divScroll").scrollTop;
          }
          function setScrollPos(){
              document.getElementById("divScroll").scrollTop = 
                          document.getElementById("<%=scrollPos%>").value;
          }
     </script> 
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server" />
        <input type="hidden" id="scrollPos" name="scrollPos" value="0" runat="server"/>        
       <asp:UpdatePanel runat="server" ID="up1" UpdateMode="Always">
        <ContentTemplate>
        <div id="divScroll" onscroll="saveScrollPos();" 
            style="height: 200px; overflow:auto; overflow-x:hidden; overflow-y:scroll;" >
             <asp:Literal ID="lit" runat="server"></asp:Literal>
        </div>
       </ContentTemplate> 
       </asp:UpdatePanel> 
    </form>
</body>
</html>

Open in new window


The below code is a bit closer to what I'm trying to use this in. I've incorporated a timer that fires the updatepanel every time the timer's tick event fires.
//////Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
     <script type="text/javascript" language="javascript">
          Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
          function EndRequestHandler(sender, args) {
              setScrollPos();
          }
          function saveScrollPos() {
               document.getElementById("<%=scrollPos%>").value = 1000000;
                          //document.getElementById("divScroll").scrollTop;
          }
          function setScrollPos(){
               document.getElementById("divScroll").scrollTop = 1000000;
                          //document.getElementById("<%=scrollPos%>").value;
          }
     </script> 
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server" />
        <input type="hidden" id="scrollPos" name="scrollPos" value="0" runat="server"/>        
       <asp:UpdatePanel runat="server" ID="up1">
        <ContentTemplate>
        <div id="divScroll" onscroll="saveScrollPos();"
            style="height: 200px; overflow:auto; overflow-x:hidden; overflow-y:scroll;" >
             <asp:Literal ID="lit" runat="server" ></asp:Literal>
        </div>
       </ContentTemplate> 
            <Triggers>
                 <asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" />
            </Triggers>
       </asp:UpdatePanel> 
        <asp:Timer ID="Timer1" runat="server" Interval="2000" ontick="Timer1_Tick">
        </asp:Timer>
    </form>
</body>
</html>
 
 
//////default.aspx.cs
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text;
 
public partial class _Default : System.Web.UI.Page 
{
     //public static string scrollPos = String.Empty;
 
    protected void Page_Load(object sender, EventArgs e)
    {
         String line = " THIS IS JUST A LINE OF TEXT MEANT TO TAKE UP A LINE. \n ";
         StringBuilder sb = new StringBuilder();
         for (int i = 0; i < 30; i++)
              sb.Append(line);
 
         lit.Text = sb.ToString();
 
         //scrollPos = ((HtmlInputHidden)scrollPos).ClientID.ToString();
 
    }
    protected void Timer1_Tick(object sender, EventArgs e) {
         grow();
    }
 
    private void grow() {
         String line = " THIS IS JUST A LINE OF TEXT MEANT TO TAKE UP A LINE. \n ";
         StringBuilder sb = new StringBuilder();
         for (int i = 0; i < 30; i++)
              sb.Append(line);
 
         lit.Text = sb.ToString();
 
 
    }
}

Open in new window


I added an alert to the setScrollPos function so I could tell when it's being called and it never seems to be called. Any ideas?
both the following lines are creating an object with the same ID
remove the input if you want to take the <%=scrollPos%> approach

<input type="hidden" id="scrollPos" name="scrollPos" value="0" runat="server"/>  
public static string scrollPos = String.Empty;

I'll be sure to make that change ragi, thanks!

Any ideas on why setScrollPos() is not being called? This is the first I've seen of the syntax used to set up the call for it: Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);

I'll start by investigation that this evening.

Okay, I have the code below as my javascript. scrollPosb is a static string on the _default class that contains the name of the scrollPos control on the user's side. scrollPos contains the actual value of what the scroll bar's scrollTop property is.

I don't see much difference in what I'm doing here and the example here at msdn that explains the PageRequestManager/add_endRequest event.

http://msdn.microsoft.com/en-us/library/bb383810.aspx
     <script type="text/javascript" language="javascript">
          Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
          function EndRequestHandler(sender, args) {
               alert('EndRequestHandler');
              setScrollPos();
          }
          function saveScrollPos() {
               alert(document.getElementById("<%=scrollPosb%>").value);
               document.getElementById("<%=scrollPosb%>").value = 
                          document.getElementById("divScroll").scrollTop;
          }
          function setScrollPos() {
               alert('setting scroll pos');
               document.getElementById("divScroll").scrollTop =
                          document.getElementById("<%=scrollPosb%>").value;
          }
     </script> 

Open in new window


Also, the alert boxes never pop up in the setScrollPos() and EndRequestHandler() functions

Any one have any further thoughts on this? This still doesn't work for me.

Never really got this one solved. Expert involvement seemed to wane, but I still appreciate the support I did get.