ASP.Net validation summary causes page to jump to top
Asked Answered
M

9

53

I have a simple form with a few required field validators and a validation summary control. When I submit the form, the client validation will cause the form to jump to the top of the page. If i remove the validation summary, the page does not move.

Heres a quick example:

<asp:TextBox ID="test" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="testrequired" runat="server" ControlToValidate="test">*</asp:RequiredFieldValidator>
<asp:ValidationSummary ID="summary" runat="server" />
<asp:Button ID="submit" runat="server" Text="submit" />

I've tried setting SetFocusOnError="true" in the required field validator and MaintainScrollPositionOnPostback="true" for giggles - even though this isn't a postback - without any luck. Is there a known solution for this problem?

EDIT:

I've found the problem in the js generated by WebResource.axd. Seems to come down to a single line in the ValidationSummaryOnSubmit() function.

line 534: window.scrollTo(0,0);

Any ideas on how to remove or bypass this?

EDIT2:

Quick work around for the time being:

  • set EnableClientScript="false" for all validation controls (disabling client validation)
  • set MaintainScrollPositionOnPostback="true" in Page directive

Still hoping for a client side solution...

EDIT3:

It seems a better work around is to just override the window.scrollTo() function so that it does nothing when called by the validation script:

<script type="text/javascript">
    window.scrollTo = function() { }
</script>

Adding the above anywhere on the page leaves the client validation in tact, but disables the window.scrollTo() method throughout the page

Montserrat answered 30/3, 2009 at 21:48 Comment(5)
I'm not familiar with this, but does it append a '#' to the end of your URL? Sometimes this will cause the page to jump to the top.Medicinal
@cory, no the html generates an submit button input not an anchor linkMontserrat
For edit3: This does not help when you have a validation summary on top of page and one at the bottom. The top one never gets focus.Barman
A quick fix could be to rewrite the method "ValidationSummaryOnSubmit(validationGroup)". That way we could get the position of the validation summary and "scrollTo(x,y)".Haddington
Exemple with jQuery to get the position: window.scrollTo(0,$(summary).position().top);Haddington
M
44

Two possible work arounds:

Disable client validation and jump to correct position on post back:

* set EnableClientScript="false" for all validation controls (disabling client validation)
* set MaintainScrollPositionOnPostback="true" in Page directive

Disable the scrollTo function in javascript:

<script type="text/javascript">
    window.scrollTo = function() { }
</script>
Montserrat answered 28/4, 2009 at 17:8 Comment(4)
This is what fixed it for me: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" MaintainScrollPositionOnPostback="true" %>Newsmonger
This won't focus the summary at top if there are two summaries on page (1 at top, 2nd at bottom)Barman
-1, didn't work for me. I've got a mix of client side and server side validation going on. Using one of these methods to fix the scroll will cause the page to scroll to the top for the other one. Using both doesn't fix it either.Bought
+1. Great solution Adamn. javascript solution works for me. @Bought OP asked about client validation. You need to post another question if you need the solution for mixed validation.Blaney
U
18

This is a known bug, as documented on Microsoft Connect. The relevant issue has the basis for the best work around:

var ValidationSummaryOnSubmitOrig = ValidationSummaryOnSubmit;
var ValidationSummaryOnSubmit = function() {
    var scrollToOrig = window.scrollTo;
    window.scrollTo = function() { };
    var retVal = ValidationSummaryOnSubmitOrig();
    window.scrollTo = scrollToOrig;
    return retVal;
}
Unlicensed answered 10/2, 2011 at 20:21 Comment(4)
The workaround in the comments of that issue don't account for validation groups, and introduce new variables into global scope. On the workaround tab of the issue, I've posted an updated workaround which takes those issues into consideration.Highpowered
Here is the updated workaround of @bdukes, in case the linked page goes missing: (function () { var originalValidationSummaryOnSubmit = window.ValidationSummaryOnSubmit; window.ValidationSummaryOnSubmit = function (validationGroup) { var originalScrollTo = window.scrollTo; window.scrollTo = function() { }; originalValidationSummaryOnSubmit(validationGroup); window.scrollTo = originalScrollTo; } }());Tiffany
@Frederic, you should post that updated workaround as a full answer so it can be voted up, with an acknowledgement Cleek and bdukes.Auvergne
@EuroMicelli ok, it is done. Sure it is more readable that way. And now that MS Connect seems to require registration, it is less convenient to go there for reading it. (But now I may get one more necro badge ^^)Tiffany
N
11

Instead of

<script type="text/javascript">
    window.scrollTo = function() { return true; }
</script>

which would indiscriminately override the ScrollTo function for all postbacks, I put the function in my OnClientClick event of the button. As below.

onClientClick="window.scrollTo = function(x,y) { return true; };"

Not sure if it's the best solution, but it seems to have done the job for me.

Nares answered 28/4, 2011 at 10:13 Comment(1)
It works one time until the button is clicked,then scrollto is lostHydric
W
9

As stated by cleek's answer, this is a known bug having workarounds.

Here is bdukes one, which looks to me as the best currently available.

(function () {
  var originalValidationSummaryOnSubmit = window.ValidationSummaryOnSubmit;
  window.ValidationSummaryOnSubmit = function (validationGroup) {
    var originalScrollTo = window.scrollTo;
    window.scrollTo = function() { };
    originalValidationSummaryOnSubmit(validationGroup);
    window.scrollTo = originalScrollTo;
  }
}());

(He has not posted it directly here on SO, and now the connect issue seems to require registration for being seen, which renders his workaround harder to access.)

Wentzel answered 8/4, 2015 at 9:43 Comment(1)
even this is really old but still valid. can you pass the arguments instead of validationGroup e.g. fnc.apply(null, arguments);Interlay
H
5

I use this: (requires jquery and jquery.scrollTo)

First you put an anchor with a specific class above your validation summary, like so:

<a class="custom_valsum_anchor" />
<asp:ValidationSummary ID="valSum" runat="server" EnableClientScript="true" />

then include this bit of javascript:

$(document).ready(
        function () {
            var $valSum = $(".custom_valsum_anchor");
            if ($valSum.size() > 0) {
                var backup_ValidationSummaryOnSubmit = ValidationSummaryOnSubmit;
                ValidationSummaryOnSubmit = function (validationGroup) {
                    var backup_ScrollTo = window.scrollTo;
                    window.scrollTo = function () { };
                    backup_ValidationSummaryOnSubmit(validationGroup);
                    window.scrollTo = backup_ScrollTo;
                    setTimeout(function () { $("body").scrollTo($valSum); }, 1);
                };
            }
        }

);

Basicaly, it replaces, when necessary, the ValidationSummaryOnSubmit function with a version that temporarily disables window.scrollTo and scrolls to the anchor. It should not be to hard to modify so that it does not use jquery.

Humour answered 12/10, 2012 at 19:51 Comment(0)
B
0

I was running into an issue where using MaintainScrollPositionOnPostback=true would work but would break client-side validation scroll position. So I added a script to bring the validation summary control into view on a postback.

 private void FocusControlOnPageLoad(Control ctrl)
    {

        this.Page.ClientScript.RegisterClientScriptBlock(
          typeof(System.Web.UI.Page), "ctrlFocus",
        @"<script> 
              function ScrollView()
              {
                 var el = document.getElementById('" + ctrl.ClientID + @"')
                 if (el != null)
                 {        
                    el.scrollIntoView();
                    el.focus();
                 }
              }
              window.onload = ScrollView;
        </script>");
    }

with:

protected void Page_PreRender(object sender, EventArgs e)
{
   if (Page.IsValid == false)
        {
          FocusControlOnPageLoad(TheValidationSummary);
        }
}

It seems that I also have to have the scrollTo function blanked out:

window.scrollTo = function() {
            return true;
        }

Got the code (mostly) from here.

Bought answered 9/2, 2011 at 22:24 Comment(0)
I
-1

The page is going to jump to wherever your validation summary is. If you'd like it to stay near the bottom, move the validation summary down near the submit button.

EDIT, you can also try turning the validation summary off.

Impostume answered 31/3, 2009 at 19:55 Comment(3)
@sausemaster, the page jumps to the top no matter where I put the validation summary. when I turn the validation summary off, it does not jump around, but unfortunately thats the one thing thats requiredMontserrat
Ok. I think you may be stuck writing some javascript to have a control call focus when submit is clicked of something similar. A quick google search returned this forum (forums.asp.net/t/1089469.aspx) topic. Sorry and best of luck.Impostume
I have 3 summaries, and it always jumps to the top.Lyons
L
-1

Perhaps you could inherit from the required fieldvalidator and override the client side validation in a custom control?

Lilley answered 2/4, 2009 at 2:2 Comment(0)
W
-2

Look at setting the target schema for your html.

Try http://msdn.microsoft.com/en-us/library/6379d90d(VS.71).aspx

Prior to VS 2005 you could set the schema on a page by page level.

Just a thought.

Waldenburg answered 30/3, 2009 at 21:56 Comment(2)
I'm not sure I follow. This doesn't appear to be browser specificMontserrat
the statement is not coherent. And thoughts are not appropriate as answers. They belong as COMMENTS!!!!!!Kamenskuralski

© 2022 - 2024 — McMap. All rights reserved.