OnSelectedIndexChange only fires on second click when using custom page validation script
Okay.. this is hard to explain, so here it goes.
I have an update panel which contains a number of controls. The update panel is triggered by the OnSelectedIndexChanged event of a dropdownlist called: ddlUSCitizenshipStatus. It works as expected when I selected a new item.
However, if I leave ddlUSCitizenshipStatus with the default value, and then click "submit" button on the page, the requiredfieldvalidators say there is an error on ddlUSCitizenshipStatus (which it should, as I never selected a value). So I then choose a value, the error message goes away on ddlUSCitizenshipStatus, however the updatepanel does not refresh. I've debugged this locally and the OnSelectedIndexChanged event for ddlUSCitizenshipStatus does not fire.
If I choose an item in the ddlUSCitizenshipStatus list a second time, the OnSelectedIndexChanged server event fires and the update panel refreshes and works as expected.
The issue is, I have to select an item in ddlUSCitizenshipStatus twice, after failed validation, before the updatepanel it's sitting in updates.
The submit button on the page looks like this:
<asp:LinkButton ID="btnSubmitPage1" runat="server" CssClass="continueButton" OnClick="btnSubmitPage1_Click" CausesValidation="true" OnClientClick="javascript: return ValidatePage();" />
If I remove my custom OnClientClick script, making the submit button look like this:
<asp:LinkButton ID="btnSubmitPage1" runat="server" CssClass="continueButton" OnClick="btnSubmitPage1_Click" CausesValidation="true" ValidationGroup="valGrpAdditionalInformation" />
The dropdownlist, update panel, and reguiredfieldvalidator all work as expected. However, I need to run that custom "ValidatePage()" script when the button is clicked.
Below is what my ValidatePage script looks like. I've been troubleshooting this for more hours than I can count.... I hope someone is able to help me. Please let me know if you can figure out why ddlUSCitizenshipStatus doesn't update the updatepanel until the second click after a failed validation.
function ValidatePage()
{
var blnDoPostBack = true;
if (typeof(Page_ClientValidate) == 'function' )
{
//Client side validation c开发者_开发百科an occur, so lets do it.
//Validate each validation group.
for( var i = 0; i < Page_ValidationSummaries.length; i++ )
Page_ClientValidate( Page_ValidationSummaries[i].validationGroup.toString() );
//Validate every validation control on the page.
for (var i = 0; i < Page_Validators.length; i++)
ValidatorValidate(Page_Validators[i]);
//Figure out which validation groups have errors, store a list of these validation groups in an array.
var aryValGrpsWithErrors = [];
for( var i = 0; i < Page_Validators.length; i++ )
{
if( !Page_Validators[i].isvalid )
{
//This particular validator has thrown an error.
//Remeber to not do a postback, as we were able to catch this validation error client side.
blnDoPostBack = false;
//If we haven't already registered the validation group this erroring validation control is a part of, do so now.
if( aryValGrpsWithErrors.indexOf( Page_Validators[i].validationGroup.toString() ) == -1 )
aryValGrpsWithErrors[aryValGrpsWithErrors.length++] = Page_Validators[i].validationGroup.toString();
}
}
//Now display every validation summary that has !isvalid validation controls in it.
for( var i = 0; i < Page_ValidationSummaries.length; i++ )
{
if( aryValGrpsWithErrors.indexOf( Page_ValidationSummaries[i].validationGroup.toString() ) != -1 )
{
Page_ValidationSummaries[i].style.display = "";
document.getElementById( Page_ValidationSummaries[i].id.toString() + "Wrapper" ).style.display = "";
}
else
{
//The current validation summary does not have any error messages in it, so make sure it's hidden.
Page_ValidationSummaries[i].style.display = "none";
document.getElementById( Page_ValidationSummaries[i].id.toString() + "Wrapper" ).style.display = "none";
}
}
}
return blnDoPostBack;
}
I found the solution to this issue and posted it here: http://forums.asp.net/t/1554406.aspx This post had the answer I was looking for: http://lionsden.co.il/codeden/?p=137&cpage=1#comment-143
What is Page_BlockSubmit
When the user clicks on a button causing a full post back, after running Page_ClientValidate ASP.NET runs another built in function ValidatorCommonOnSubmit. Within Page_ClientValidate, Page_BlockSubmit is set based on the validation. The postback is then blocked in ValidatorCommonOnSubmit if Page_BlockSubmit is true. No matter what, at the end of the function Page_BlockSubmit is always reset back to false.
If a page does a partial postback without running any validation and Page_BlockSubmit has not been reset to false, the partial postback will be blocked. In essence the above function, RunValidation, acts similar to ValidatorCommonOnSubmit. It runs the validation and then returns false to block the postback if needed. Since the built in postback is never run, we need to reset Page_BlockSubmit manually before returning the validation result.
After Page_ClientValidate is called, the variable Page_BlockSubmit gets set to true, which blocks the autopost back. Page_BlockSubmit was getting reset to false on the second click, for reasons I still don't fully understand. I'm looking more into this, but I have a solution and I'm under the gun so I'm rolling with it.
In summary, I previously had the following code:
for( var i = 0; i < Page_ValidationSummaries.length; i++ )
Page_ClientValidate( Page_ValidationSummaries[i].validationGroup.toString() );
By adding Page_BlockSubmit = false
below that, I get this:
for( var i = 0; i < Page_ValidationSummaries.length; i++ )
Page_ClientValidate( Page_ValidationSummaries[i].validationGroup.toString() );
Page_BlockSubmit = false;
Which allows AutoPostBack=true controls to execute inside of updatepanels. However, the form itself is still never submitted because my client side validation code returns false whenever a single Page Validator has in invalid value.
I was having the same problem, though all I have is a Textbox using a RangeValidator, along with a submit button. When the user entered a number outside the range and clicked Submit, the invalid-number message came up. If they changed the number to a valid one and clicked Submit again, the message went away, but the onclick event did not fire. If they clicked Submit a second time it did fire.
I had to remove the Display="Dynamic" attribute from the RangeValidator to fix it.
精彩评论