Maintain scroll position of a DIV over a callback

Rate It (1)

Last post 06-28-2008 12:23 AM by lenobay. 12 replies.

Sort Posts:

  • Maintain scroll position of a DIV over a callback

    01-26-2007, 10:31 AM
    • Participant
      827 point Participant
    • Hoonius
    • Member since 07-13-2006, 12:21 PM
    • England
    • Posts 192

    Hi Guys

    This scroll position thing is doing my nut to put it frankly.  I can see plenty of methods on the net using allsorts of techniques ; HTC Behavior, cookies, hidden form fields, MaintainScrollPosition etc.  However, none do exactly as i'd like them to

    They all work when a page is loaded for the first time, no problem there at all.  It runs the page load and fires the window.onload function client side no worries and all is well in the world.  This window.onload does not see to fire on a callback though and my scroll position is lost forever :¬(.  MaintainScrollPositionOnPostBack only maintains the scroll on the main browser screen so that's not going to do the trick either

    So, does anyone know how to maintain the scroll position of a div over a callback?  I think i'm nearly there, if only i could fire a client-side method when my UpdatePanel has done it's callback thang.  I found the best looking method using cookies Here  but, as said above, i can't get the onload function to fire when a callback completes.  if i could get the UpdatePanel to do this, i'd be home and dry

    Please help...

     

  • Re: Maintain scroll position of a DIV over a callback

    01-26-2007, 11:44 AM
    • Participant
      827 point Participant
    • Hoonius
    • Member since 07-13-2006, 12:21 PM
    • England
    • Posts 192

    think i've sussed this but will update next week on my findings

     

    I was able to attach to the PageRequestManager's endRequest event and fire my positioning function.  i'll let you know how this all works next time :¬)

  • Re: Maintain scroll position of a DIV over a callback

    01-29-2007, 5:35 AM
    Answer
    • Participant
      827 point Participant
    • Hoonius
    • Member since 07-13-2006, 12:21 PM
    • England
    • Posts 192

    been dying IRL to post this solution so here goes

    I've tried allsorts of methods to maintain scroll position in divs.  I had it licked in traditional ASP.NET when all the normal page events fired.  I could preserve scroll postion using some HTC behavior file and add these saved positions back to their divs when the page reloaded

     
    Then came AJAX.  I lost most of this functionalty due to the new ways in which pages post themselves back to the server.  However, there is a much richer event model to work with now so it should be a bit easier to implement, and there are no amends to make to any existing divs.

     
    I added the following methods to my master page in the <script> section:

        function SaveDivScrollPosition()
    {
    var myDivs = document.getElementsByTagName("div");
    for(var i = 0; i < myDivs.length; i++)
    {
    if(myDivs[i].id.length > 0 && myDivs[i].scrollTop > 0)
    {
    document.cookie = myDivs[i].id + "=" + myDivs[i].scrollTop;
    }
    }
    }
    function SetDivScrollPosition()
    {
    var strCook = document.cookie;
    if(strCook.length > 0)
    {
    var cookies = strCook.split(";");
    for(var i = 0; i < cookies.length; i++)
    {
    var mySplit = cookies[i].split("=");
    try
    {
    document.getElementById(mySplit[0].replace(" ", "")).scrollTop = mySplit[1];
    }
    catch(e)
    {
    }
    }
    }
    }

    Quite simply, the first function gets all divs with an id that have been scrolled and saves the information to the page's cookie collection.  The second function collects the cookie data and cycles through, setting the scroll positions.

    All that remains is to get these events fired at the right time.  Thanks to the PageRequestManager class, this was easier than I thought.  Just underneath the ScriptManager control on my Master page, i added the following lines:

     

    <script type="text/javascript">
    Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(SaveDivScrollPosition);
    Sys.WebForms.PageRequestManager.getInstance().add_endRequest(SetDivScrollPosition);
    </script>

    This just wires my functions so that they fire as soon as the callback is requested and when the page has done it's redrawing. Works for me in IE and FireFox :¬)

    Hope this helps someone
     

  • Re: Maintain scroll position of a DIV over a callback

    02-07-2007, 3:20 AM
    • Member
      8 point Member
    • darkprojekt
    • Member since 02-07-2007, 8:12 AM
    • Posts 6

    Hi. I have two problems on my page with this solution ...

    1) Scroll to top doesn't work
    After a postback with a correctly positioned scroll panel I scroll back to top .. after a postback the scroll panel jumps back to the last scrolled position, not the top position.

     2) Visible jumping
    Is there a way to suppress the visible jumping effect?

    Thanks
    Michael

  • Re: Maintain scroll position of a DIV over a callback

    02-07-2007, 5:08 AM
    • Participant
      827 point Participant
    • Hoonius
    • Member since 07-13-2006, 12:21 PM
    • England
    • Posts 192

    nicely spotted bugs man.  i'll try and fix these today but i can offer these views at this early stage

    1 : This is a bug in my javascript as it only collects the scrollTop if it's greater than zero.  you could remove the check for scrollTop > 0 and this should be fixed

    2 : I noticed the visual scrolling part as well.  maybe moving the event uip the tree a bit would solve this but i haven't had time to investigate.  maybe moving it to the pageLoaded or the pageLoading event would alleviate this problem visually

     However, i saw another solution which doesn't require any javascript at all.  i've not had it work with my development pages but the test page provided by the poster worked fine.  You should also check this solution as it may give you what you need

    http://forums.asp.net/thread/1544928.aspx

    hope this helps :¬)

  • Re: Maintain scroll position of a DIV over a callback

    02-19-2007, 10:25 AM
    • Participant
      827 point Participant
    • Hoonius
    • Member since 07-13-2006, 12:21 PM
    • England
    • Posts 192

    ok, i've amended thwe solution slightly to cope with Micheal's observations

    1 : The code for collecting the scroll postions on the initilizeRequest event was fatally flawed due to it not collecting the postions of a DIV where the user had scrolled to the top. This was due to the clause : 

    myDivs[i].scrollTop > 0
      Initially, i had intended to remove this clause so all scroll positions were collected, even when they were at zero.  This caused a major problem however. My site, with all it's screen sections, UpdatePanels, Panels etc, my pages ended up having 100+ div controls on the client.  Being a cookie n00b, I didn't consider that the cookie collection can only contain 20 values.  ASP.NET uses the first one to store the SessionID and the 21st addition was knocking this sessionID out and i was losing Session Data and Login information as discussed here.  So, i made a simple custom control, based on a regular asp:Panel which added the folling onScroll attribute in the OnLoad function thus:

     

    1    protected override void OnLoad(EventArgs e)
    2 {
    3 //add some javascript to record the scrollTop 4 this.Attributes.Add("onscroll", "document.cookie = this.id + '=' + this.scrollTop;");
    5 base.OnLoad(e);
    6 }
    I was then able to remove the collection function and only have the following JavaScriot on my MasterPage: 
    <script type="text/JavaScript">
    Sys.WebForms.PageRequestManager.getInstance().add_endRequest(SetDivScrollPosition);
    function SetDivScrollPosition()
    {
    var strCook = document.cookie;
    if(strCook.length > 0)
    {
    var cookies = strCook.split(";");
    for(var i = 0; i < cookies.length; i++)
    {
    var mySplit = cookies[i].split("=");
    try
    {
    document.getElementById(mySplit[0].replace(" ", "")).scrollTop = mySplit[1];
    }
    catch(e)
    {
    }
    }
    }
    }

    </script>

    Also, i was unable to supress the visual scrolling. It's only very slight anyway so it wasn't very high on priorities for me

    So, it's a little more robust now but is still limited to 19 positions, and that's provided you don't use cookies for anything else!!

    Hope this helps somone though

    cheers

    Tim

  • Re: Maintain scroll position of a DIV over a callback

    02-19-2007, 6:03 PM
    • Member
      39 point Member
    • klgrube
    • Member since 07-12-2005, 9:51 PM
    • Posts 27

    Please help!!  I'm getting really desperate here, and actually more than a little upset.

     ALL I WANT TO DO (she screams) . . . . .

        Is have gridview with a fixed header where everything below the header scrolls.  I know how to do that using a panel per Paul Kimmel's article  at http://www.developer.com/net/asp/article.php/3585911.   This works fine as long as you don't have an edit button on the gridview.

       BUT I want the header to stay where it is and the scroll position of the rest of the gridview to NOT change its place when a user hits the 'Edit' button!!!   Is that too much to ask?  Gee . .   a fixed header gridview that DOESN'T lose the scroll position of the selected or edited row.  What a concept.  I've found references to each of these ideas separately, but never found a combined solution.

       How do I accomplish that?

       So . . .  right now I have a panel that has the following styles associated with it

    .fixedHeader
    {
       overflow: auto;
       height: 350px;
    }
    table th
    {
       border-width: 4px;
       border-color: Black;
       background-color: Gray;
       position: relative;
       top: expression(this.parentNode.parentNode.
                       parentNode.scrollTop-1);
    }

    and a page that looks kind of like . . .

    <asp:Panel class="fixedheader">
        <asp:UpdatePanel>
            <ContentTemplate>
               <Gridview>
               </Gridview>
            </ContentTemplate>
        </asp:UpdatePanel
    </asp:Panel>

      When I have the fixedHeader Panel on the outside of the UpdatePanel and the user hits the Edit button, the gridview retains its scroll position but the fixed header disappears after postback.  But, when I put the Panel inside of the Update Panel, the scroll returns to the top of the gridview.  I really don't know what to do!!!  I don't know how to tell the Update panel that it's inside of a fixed header panel!!!!

      Please help!  I've literally been struggling with this for DAYS!!!!!

    Karen

     

  • Re: Maintain scroll position of a DIV over a callback

    02-20-2007, 6:56 AM
    • Participant
      827 point Participant
    • Hoonius
    • Member since 07-13-2006, 12:21 PM
    • England
    • Posts 192

    the trick is that you need to attach the css class to the header CELLS rather than the header ROW

    this.parentNode.parentNode.parentNode.scrollTop-1

    translates to

    HeaderCell.HeaderRow.Table.Div.scrollTop - 1

    So, on your Gridview.RowCreated Event do this:

     

    1    protected void KarensGrid_RowCreated(object sender, GridViewRowEventArgs e)
    2 {
    3 switch (e.Row.RowType)
    4 {
    5 case DataControlRowType.Header:
    6 //add the css sttribute for all the cells 7 for (int i = 0; i < e.Row.Cells.Count; i++)
    8 {
    9 e.Row.Cells[i].Attributes.Add("class", "FixedTableHeaderCell");
    10 }
    11 break;
    12 }
    13 }
    And that CSS will also need to change to reflect the FixedTableHeaderCell class so this would be the change
    FixedTableHeaderCell
    {
       border-width: 4px;
    border-color: Black;
    background-color: Gray;
    position: relative;
    top: expression(this.parentNode.parentNode.
    parentNode.scrollTop-1)
    ;
    }
    "table th" is too generic for me as i sometimes want a table to scroll entirely and setting this cause ALL my tables to have fixed headers
    I do have this working my end but the div scroll position is being saved using my JavaScript method, not by enclosing it as stmarti does in that other post you replied to
    Please let me know how you get on and i'll try and fix the footers in the meantime :¬)
    cheers
    Tim 

     

  • Re: Maintain scroll position of a DIV over a callback

    04-11-2007, 11:05 PM

    Man, Tim, you are a genius.  I had all but given up on this.  Then I came back months later (I posted a thread on this back in January), looked up the thread, followed a link and there is the answer, in the form of a slick little javascript function provided by you.

    I modified it slightly, to only look for the one div that is causing me grief (most of us don't have 100 scrolling divs on one page, by the way).  Other than that it's the same as your first post.  I didn't adopt the second one, because the first works just fine for me.

    Thanks again, man.  You really made my day.

    BTW did I understand correctly that we can give each other kudos or points or something on this forum?  How would I go about doing that.  You should get 10000.

    Aaron

  • Re: Maintain scroll position of a DIV over a callback

    04-12-2007, 4:15 AM
    • Participant
      827 point Participant
    • Hoonius
    • Member since 07-13-2006, 12:21 PM
    • England
    • Posts 192

    I'm glad you find it useful.  I did post in the thread you started as well and i did link this thread in it, not to you admittedly, but to klgrube who was getting rather irate with the whole situation.  I never got a reply from her so i guess she took a break from trying to solve it

    The points thing is slightly flawed in this instance becasue i kind of answered my own thread so can no longer be awarded any points for the solution, but not to worry. 

    I'm just pleased you found it useful as well because the whole thing was doing my head right in, to put it mildly :¬)

    cheers

    Tim

     

  • Re: Maintain scroll position of a DIV over a callback

    04-20-2007, 4:19 PM

    I think you could also use this technique to "remember" where a dragPanel is between callbacks.  Currently, if you've got an open dialog box, for example, or anything that the user can drag around, it will jump back to it's original position with every call back.  I understand that you can implement profiling for remember position, but no one seems to know first hand how this works, and it also seems like a bit of overkill for just remembering position between call backs (I think the profiling solution is more for remembering all of a user's preferences between visits to the website).

    I'm going to play around with it and see what I can come up with.  Your solution got past the 20 cookie limit, right?  Are you using one cookie for everything, delimited with some character?  I guess you could also use hidden fields.

    Aaron

  • Re: Maintain scroll position of a DIV over a callback

    04-26-2007, 7:19 AM
    • Participant
      827 point Participant
    • Hoonius
    • Member since 07-13-2006, 12:21 PM
    • England
    • Posts 192

    Hi Aaron

    To my knowledge, there is no solution to the 20 cookie limit as this is enforced by the browser.  As soon as the 21st cookie is entered, it just removed the first one in the list resulting in a list of 20 cookies.

    The collection itself seems to self delimit.  I just add divTimzDiv=200 and it delimits with a semi-colon.  The code

     

    document.cookie = "divTimzDiv=200";

    document.cookie = "divTimzOtherDiv=200";

    Would result in "ASPNETSESSION=kjlhnhjk-987978njm9jhnhnknj;divTimzDiv=200;divTimzOtherDiv=200;"  inside the cookie collection.  The only thing you msut be wary of is losing that first cookie as it contains the SessionID so your app can "remember" who is calling it in realtion to a previous request.

    Not bulletproof by any means. Did you get the dragPanels to save their position?  You could add hidden fields I suppose but i imagine you'd need to store the ID's as they are created so you could iterate through them later or just have one to store all the postions in a delimited fdashion and interogate this string on pageLoad() maybe.  You can attach to all the different events of the PageRequestManager, help is here if you need any info in the object
     


     

  • Re: Maintain scroll position of a DIV over a callback

    06-28-2008, 12:23 AM
    • Member
      14 point Member
    • lenobay
    • Member since 10-03-2007, 12:38 AM
    • Posts 16

     It works great with MasterPage that has contentpages.

    HOWEVER, once there is a TabContainer, it doesnt seem to work as GOOD.

    The scroll Position is quite off, it jumps up quite bit with a TabContainer .

    I read posts that i should put a hidden control to save and restore scrollTop, but i have no idea what to do?

    anyone?

    Success = Preparation + Luck.
    How can we prepare LUCK?
Page 1 of 1 (13 items)