Showing posts with label initial. Show all posts
Showing posts with label initial. Show all posts

Wednesday, March 28, 2012

How do I scroll to the top of a page to view a ValidationSummary if there is a validation

Hi All,

So, I'm starting a new post that is related to my initial post from approximately 7 months ago (http://forums.asp.net/t/1040392.aspx). My hope is to finally find a solution to this problem... here is the issue:

A couple of our Ajax enabled pages have a lot of form fields, thus a user has to scroll to the bottom of the page to view the Submit button. When a control's RequireFieldValidator's EnableClientScript property is set to"true", upon a validation error the page will scroll up to the ValidationSummary. This is the functionality that I desire. But, when a control's RequireFieldValidator's EnableClientScript property is set to"false", upon a validation error the page does NOT scroll up to the ValidationSummary. Why not?

Here is a quick code sample to illustrate the problem:

<%@dotnet.itags.org.PageLanguage="C#"AutoEventWireup="true"CodeFile="ValidationTest.aspx.cs"Inherits="Register_Playground_Shamus_ValidationTest" %>
<!DOCTYPEhtmlPUBLIC"-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<htmlxmlns="http://www.w3.org/1999/xhtml">
<headrunat="server">
<title>Validation Test</title>
</head>
<body>
<formid="form1"runat="server">
<div>
<asp:ScriptManagerID="asmScriptManager"EnablePartialRendering="true"runat="server"/>
<asp:UpdatePanelID="udpUpdatePanel"runat="server">
<ContentTemplate>
<asp:ValidationSummaryID="valSummary"runat="server"/>
<!-- Lots of space to induce scrolling upon a validation error. -->
<p>Scroll Down</p>
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
<asp:TextBoxID="TextBox1"runat="server"/><asp:RequiredFieldValidatorID="RequiredFieldValidator1"EnableClientScript="true"ControlToValidate="TextBox1"runat="server"ErrorMessage="* TextBox1"/><br/>
<asp:TextBoxID="TextBox2"runat="server"/><asp:RequiredFieldValidatorID="RequiredFieldValidator2"EnableClientScript="false"ControlToValidate="TextBox2"runat="server"ErrorMessage="* TextBox2"/><br/>
<asp:ButtonID="Button1"runat="server"Text="Button"/>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>

And, the codebehind... 
using System;using System.Data;using System.Configuration;using System.Collections;using System.Web;using System.Web.Security;using System.Web.UI;using System.Web.UI.WebControls;using System.Web.UI.WebControls.WebParts;using System.Web.UI.HtmlControls;public partialclass Register_Playground_Shamus_ValidationTest : System.Web.UI.Page{protected void Page_Load(object sender, EventArgs e) { }}

The only difference between TextBox1 and TextBox2 is their RequiredFieldValidator's EnableClientScript property (TextBox1 is true and TextBox2 is false). To reproduce the issue:

    Load the page, scroll to the bottom and click the "Button" without entering any text into the text boxes.The page will scroll to the top and you will see the validation summary (good!).Scroll back down to the bottom of the page and put some text into the first textbox. Click the "Button".The page will NOT scroll to the top (bad!).

All I want is for the page to scroll to the top in both scenarios.

Thanks,
-Shamus

So, I fixed the problem with a hack... here is the new codebehind code:

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partialclass Register_Playground_Shamus_ValidationTest : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
Page.Validate();
if (!Page.IsValid)
{
ScriptManager.RegisterStartupScript(this,this.GetType(),"ReturnToTop","setTimeout(\"window.scrollTo(0,0)\",1);",true);
}
}
}
}

By adding a 1 millisecond timeout before calling window.scrollTo() it now works. If you remove the timeout, then when there is a validation error on Textbox2 the page will not scroll to the top. Personally, I hate hacks like this... I would still love to understand why the client vs. server-side validators behave so differently.

I hope this hack helps somebody else...

-Shamus


Yes sure, it will help for othersSmile

How do I reset a ModalPopup?

How do a reset the contents of a ModalPopup that has been closed (using the .Hide() method or by clicking the cancel button) to it's initial state (at page load)?

I am using a ModalPopup control that contains a UserControl that allows users to search for records in a database. If they find a match, they can click the 'Select' link in the GridView (where the subsequent event handler calls the ModalPopup.Hide() method). They can also click on the Cancel button to close the popup if they don't find what they are looking for.

Everything is working perfectly, except after the ModalPopup has been used once, subsequent use shows the ModalPopup in the exact state it was when it was closed, either by the .Hide() method or the cancel button.

Is there a way around this?

If its a usercontrol in the modalpopup why not create a public reset method in the usercontrol to set all the values back to "" or whatever needs to be done. You could call that right before your .hide(). It sounds like the viewstate of the controls are on. You may be able to kill viewstate on your usercontrol or set initial values, but that could potentially cause problems depending if your user control posts back a bunch of times.

HTH,

AjaxButter


I have started down the road of creating a .ResetForm() method for the user control and will see if that works.

I am hopeful that your suggestion about disabling the ViewState will work, since ideally the ModalPopup should be at it's initial state whenever it's loaded and this would involve the least amount of effort (and code to test). The only issue here might be the use of UpdatePanels for partial-page postbacks (both in the main page on in the popup), so it might not work as hoped.

I guess my best option will be to leave the ModalPopup.TargetID property blank (if it's not required) and handle showing the popup from a button Click() event that resets the UserControl first.

Thanks for the assistance.


Creating a reset event in the UserControl and calling it after certain events works for simple controls (manually created and handled forms). There are still some issues remaining...

Trapping the cancel button click event and performing a reset there causes a full page refresh since it's not wired up through the ModalPopupExtender control (and it can't be part of the UpdatePanel in the popup). Maybe I'm doing something wrong here?

If the ModalPopup contains a UserControl with a FormView (for inserting & updating), the data remains as is after the cancel button is clicked. I tried disabling the ViewState, but since the page has not been refreshed, the FormView stays the same. I also tried creating a _Click() method for the cancel button, but the event doesn't seem to get called for some reason.

Do I have to do some funky client-side scripting to get this to work?


Nevermind... I did some more playing and figured out what I was doing wrong. Staring at it for too long sometimes prevent you from seeing the forest through the trees! Wink

If I moved the cancel button into the UpdatePanel in the popup (and left the ModalPopupExtender.CancelControlID property blank), then this started to work as hoped (without the full page refreshes).

Resetting the FormView inside the UserControl turned out to be as simple as calling for the FormView.ChangeMode() method and setting it to the default mode (insert in this case) and then calling the DataBind() method (may not be needed?).

If anyone else agrees, please mark this post as an answer.