Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET: Scroll to control

I've got a particularly large form in an page. When the form is validated and a field is invalid, I want to scroll the window to that control. Calling the control's Focus() doesn't seem to do this. I've found a JavaScript workaround to scroll the window to the control, but is there anything built into ASP.NET?

like image 870
core Avatar asked Apr 14 '09 02:04

core


4 Answers

Page.MaintainScrollPositionOnPostBack = False
Page.SetFocus(txtManagerName)
like image 111
Lead1000 Avatar answered Oct 24 '22 18:10

Lead1000


Are you using a Validation Summary on your page?

If so, ASP.NET renders some javascript to automatically scroll to the top of the page which may well override the automatic behaviour of the client side validation to focus the last invalid control.

Also, have you turned client side validation off?

If you take a look at the javascript generated by the client side validation you should see methods like this:

function ValidatorValidate(val, validationGroup, event) {
  val.isvalid = true;
  if ((typeof(val.enabled) == "undefined" || val.enabled != false) && 
      IsValidationGroupMatch(val, validationGroup)) {
    if (typeof(val.evaluationfunction) == "function") {
      val.isvalid = val.evaluationfunction(val);
      if (!val.isvalid && Page_InvalidControlToBeFocused == null &&
          typeof(val.focusOnError) == "string" && val.focusOnError == "t") {
        ValidatorSetFocus(val, event);
      }
    }
  }
  ValidatorUpdateDisplay(val);
}

Note the call to ValidatorSetFocus, which is a rather long method that attempts to set the focus to the control in question, or if you have multiple errors, to the last control that was validated, using (eventually) the following lines:

if (typeof(ctrl.focus) != "undefined" && ctrl.focus != null) {
  ctrl.focus();
  Page_InvalidControlToBeFocused = ctrl;
}

To get this behaviour to work, you would ideally need to ensure that all your validators are set to be client-side - server side validators will obviously require a postback, and that might affect things (i.e. lose focus/position) - and setting MaintainScrollPositionOnPostBack to true would probably cause the page to reload to the submit button, rather than the invalid form element.

Using the server side .Focus method will cause ASP.NET to render out some javascript "on the page load" (i.e. near the bottom of the page) but this could be being overriden by one of the other mechanisms dicussed above.

like image 22
Zhaph - Ben Duguid Avatar answered Oct 24 '22 19:10

Zhaph - Ben Duguid


SO I believe the problem is because I was trying to focus on HtmlGenericControls instead of WebControls.

I just ended up doing a workaround based off of:

http://ryanfarley.com/blog/archive/2004/12/21/1325.aspx http://www.codeproject.com/KB/aspnet/ViewControl.aspx

...in the interest of time.

public static void ScrollTo(this HtmlGenericControl control)
{
    control.Page.RegisterClientScriptBlock("ScrollTo", string.Format(@"

        <script type='text/javascript'> 

            $(document).ready(function() {{
                var element = document.getElementById('{0}');
                element.scrollIntoView();
                element.focus();
            }});

        </script>

    ", control.ClientID));
}

Usage:

if (!this.PropertyForm.Validate())
{
    this.PropertyForm.ErrorMessage.ScrollTo();
    failed = true;
}

(Although it appears Page.RegisterClientScriptBlock() is deprecated for Page.ClientScript.RegisterClientScriptBlock()).

like image 40
core Avatar answered Oct 24 '22 17:10

core


Adding MaintainScrollPositionOnPostback is the closest that ASP.NET has built in, but won't necessarily jump to the invalid field(s).

<%@ Page MaintainScrollPositionOnPostback="true" %>
like image 26
Lance Harper Avatar answered Oct 24 '22 17:10

Lance Harper