ASP.net Postback - Scroll to Specific Position

Viewed 99370

I have an ASP.net WebForms page that has a lot of content on the top of the screen. It has a link button that will post back to the page and show another section of the page. When the page refreshes, I would like to set focus and scroll down to this section of the page.

I tried doing

txtField.Focus()

in my code behind and it will set focus and try to scroll there, but then scrolls right back to the top. The focus is still on my text box but the position of the screen is at the very top. The Link is at the top of the screen which is causing the postback. I want to scroll to the very bottom of the screen. It does this briefly and then scrolls right back to the top.

I have tried setting

Page.MaintainScrollPositionOnPostback = false;

but that doesn't seem to help either.

Is there some way I can force it to go to a specific position? Is it possible to add an anchor tag to the URL when I postback using a button or link button?

9 Answers

You can use the code below if you have an anchor for the location:

Page.ClientScript.RegisterStartupScript(this.GetType(), "hash", "location.hash = '#MOVEHERE';", true);

try this

protected void Page_Load(object sender, EventArgs e)
    {
        if (Page.IsPostBack) {
            string targetId = Page.Request.Params.Get("__EVENTTARGET");
            Page.ClientScript.RegisterStartupScript(this.GetType(), "focusthis", "document.getElementById('" + targetId + "').focus()", true);

        }
    }

While not elegant for your situation, it is also possible to use dummy Custom Validators, set the one you want to scroll to as invalid then do

DummyCustomValidator.SetFocusOnError = true;

In my case, I am actually using page Validators with async postbacks and multiple programmatically shown/hidden panels on a long vertical form. Since some fields are only required if MyLogicalParent.Visible = true and if specific answers are given in other controls, such as a RequiredFieldValidator on a TextBox when "Other" is selected in a CheckBoxList, I have a LOT of logic to process page validation. Setting scroll positions was painful in all of the normal methods.

I also use RegisterStartupScript to handle maintaining the current scroll position when async postbacks alter the page's vertical dimension.

    <script type="text/javascript">
        $(document).ready(function () {
            var windowHeight = $(document)[0].documentElement.clientHeight;    /*This is the height of the viewable browser area.*/
            var scrolledPosition = $(window)[0].scrollY;                       /*This is the number of Pixels the Window is currently scrolled to.*/
            var scroll = windowHeight + scrolledPosition;                       /*This should be the same as $(window).scrollTop() */
            /*If the amount scrolled + the height of the window is Less than or equal to the total height of the page (past the viewable client window)*/
            if ($(window).scrollTop() + getWindowSize()[1] <= getDocHeight()) {
                /*Move the morescroll div to the bottom of the page... -34 is the height of the div plus a small bottom margin.*/
                $("#morescroll").offset({ top: windowHeight - 34 });
            }
        })

        /*This is the total height of the document including the area past the viewable client window.*/
        function getDocHeight() {
            var D = document;
            /*The Largest of these six numbers is the total doc height. */
            return Math.max(
                D.body.scrollHeight, D.documentElement.scrollHeight,
                D.body.offsetHeight, D.documentElement.offsetHeight,
                D.body.clientHeight, D.documentElement.clientHeight
            );
        }

        /*This is the width and height of the Viewable Browser area.*/
        function getWindowSize() {
            var myWidth = 0, myHeight = 0;
            if (typeof (window.innerWidth) == 'number') {
                //Non-IE
                myWidth = window.innerWidth;
                myHeight = window.innerHeight;
            } else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
                //IE 6+ in 'standards compliant mode'
                myWidth = document.documentElement.clientWidth;
                myHeight = document.documentElement.clientHeight;
            } else if (document.body && (document.body.clientWidth || document.body.clientHeight)) {
                //IE 4 compatible
                myWidth = document.body.clientWidth;
                myHeight = document.body.clientHeight;
            }
            return [myWidth, myHeight];
        }

        //This sets a transparent div <div id="morescroll" class="scrollMinder"> with the text "Scroll down for more." to the bottom of the viewable page. 
        $(window).scroll(
            function () {
                var windowHeight = $(document)[0].documentElement.clientHeight;
                var scrolledPosition = $(window)[0].scrollY;
                var scrll = windowHeight + scrolledPosition;
                document.getElementById('<%= HF_LastScrolled.ClientID %>').value = scrolledPosition;
                var docHeight = $(document)[0].documentElement.scrollHeight;
                /*if we are scrolled to within 60 pixels from the bottom of the document, hide the indicator so it doesn't cover the footer.*/
                if ($(window).scrollTop() + $(window).height() >= $(document).height() - 60) {
                    $("#morescroll").hide();
                }
                /*if we scroll back above 60 pixels from the bottom of the document, show the indicator and set the top of the div to -34 pixels.*/
                else if ($(window).scrollTop() + getWindowSize()[1] <= getDocHeight()) {
                    $("#morescroll").show();
                    $("#morescroll").offset({ top: scrll - 34 });
                }
            });
</script>

     <%-- This stores the Y scroll location.--%>
        <asp:HiddenField ID="HF_LastScrolled" runat="server" />
        <div id="morescroll" class="scrollMinder">
            <span class="spanMinder">Scroll down for more.</span>
        </div>





 private string LastScrolled = "";

    protected void Page_PreRender (object sender, EventArgs e)
            {
                if (string.IsNullOrEmpty(LastScrolled))
                {
                    LastScrolled = "0";
                }
                if (string.IsNullOrEmpty(scrollPosition))
                {
                    sb.Clear();
                    sb.AppendLine("Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);");
                    sb.AppendLine("function EndRequestHandler(sender, args) {");
                    sb.Append("scrollTo(0, ").Append(LastScrolled).Append(");");
                    sb.AppendLine("}");
                    sb.AppendLine("function load() {");
                    sb.AppendLine("Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);");
                    sb.AppendLine("}");
                    cs.RegisterStartupScript(GetType(), "ScrollToLastPosition", sb.ToString(), true);
                    scrollPosition = "ScrollToLastPosition";
                }
                if (!string.IsNullOrEmpty(scrollPosition))
                {
                    ScriptManager.RegisterStartupScript(this, GetType(), scrollPosition, sb.ToString(), true);
                }
            }

    protected void Page_Load (object sender, EventArgs e)
            {
              LastScrolled = HF_LastScrolled.Value;
              Page.MaintainScrollPositionOnPostBack = false;
            }

   protected void SetScrollToLastPosition ()
            {
                sb.Clear();
                sb.AppendLine("Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);");
                sb.AppendLine("function EndRequestHandler(sender, args) {");
                sb.Append("scrollTo(0, ").Append(LastScrolled).AppendLine(");");
                sb.AppendLine("}");
                sb.AppendLine("function load() {");
                sb.AppendLine("Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);");
                sb.AppendLine("}");
                cs.RegisterStartupScript(GetType(), "ScrollToLastPosition", sb.ToString(), true);
                scrollPosition = "ScrollToLastPosition";
                string tempstring = sb.ToString();
                ScriptManager.RegisterStartupScript(this, GetType(), scrollPosition, sb.ToString(), true);
            }

protected void SetScrolltoPositionY (int y)
            {
                sb.Clear();
                sb.AppendLine("Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);");
                sb.AppendLine("function EndRequestHandler(sender, args) {");
                sb.Append("scrollTo(0, ").Append(y).AppendLine(");");
                sb.AppendLine("}");
                sb.AppendLine("function load() {");
                sb.AppendLine("Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);");
                sb.AppendLine("}");
                cs.RegisterStartupScript(GetType(), "ScrollTo-0-" + y.ToString(), sb.ToString(), true);
                scrollPosition = "ScrollTo - 0-" + y.ToString();
                string tempstring = sb.ToString();
                ScriptManager.RegisterStartupScript(this, GetType(), scrollPosition, sb.ToString(), true);
            }
Related