ASP.Net validation summary causes page to jump to top
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
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>
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;
}
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.
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.)
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.