Reputation: 19953
Summary
I have a single control with two (almost) identical validators, each linked to two validation groups. When the cursor leaves the control, both validators are automatically checked by ASP.NET. Is there a way to only fire one (without setting EnableClientScript="false"
) so there are not two *
symbols being displayed on the blur
?
Details
I have a form with two buttons asp:btnSave
and asp:btnSubmit
... both buttons require validation, as certain controls must be validated on the save for it to work correctly.
So I have two validation groups, the "default" group for submitting (i.e. ValidationGroup
property is NOT set), and the "SaveGroup" for saving. There are two asp:ValidationSummary
controls to reflect these.
On a single control that is (for example) designed to accept a decimal value, I have the following. Firstly a required field for the submit, then a range validator for the submit. Then a 3rd validator which is a replication of the range validator but is part of the "SaveGroup"...
<asp:TextBox runat="server" id="txtMyDecVal" />
<asp:RequiredFieldValidator runat="server" ControlToValidate="txtMyDecVal"
Text="*" ErrorMessage="Enter a value" />
<asp:RangeValidator runat="server" ControlToValidate="txtMyDecVal" Type="Double"
MinimumValue="0" MaximumValue="999.99" Text="*"
ErrorMessage="Value must be between 0 and 999.99" />
<asp:RangeValidator runat="server" ControlToValidate="txtMyDecVal" Type="Double"
MinimumValue="0" MaximumValue="999.99" Text="*"
ErrorMessage="Value must be between 0 and 999.99"
ValidationGroup="SaveGroup" />
This is working fine, and the two buttons validate correctly.
The problem is... there is a visual issue that if you type invalid text into the control, BOTH the RangeValidators
are fired automatically by ASP.NET when the cursor leaves the control, resulting in two *
symbols appearing.
Is there a way to make it so that only one of those validators are checked as part of the blur
event on the control?
I could set EnableClientScript="false"
on one of the validators, but I still want it to check the control on the client side without a post-back first.
Update
I have been playing with setting EnableClientScript="false"
as I decided that the post-back on the save wasn't actually going to be a big issue.
However, this then leads on to another visual issue: Enter invalid text, the "submit" validator shows the *
. Click the save, which posts-back and then displays the *
for the "save" validator. If you then change the text to valid text, the "save" validator doesn't disappear, so it still looks like there's a problem... and if you change the text to different invalid text, you get the "submit" *
appearing as well, resulting in the same as before... i.e. two *
symbols.
Upvotes: 4
Views: 10841
Reputation: 1179
I am faced with this issue too - I have:
Adding multiple validators works as above until you enter and then subsequently blank out a field - you get both messages. My workaround is as follows:
Overwrite the IsValidationGroupMatch
JavaScript method to allow for comma seperated values in the ValidationGroup
property:
function IsValidationGroupMatch(control, validationGroup) {
if ((typeof (validationGroup) == "undefined") || (validationGroup == null)) {
return true;
}
var controlGroup = "";
if (typeof (control.validationGroup) == "string") {
controlGroup = control.validationGroup;
}
//return (controlGroup == validationGroup);
var controlValidationGroups = controlGroup.split(",");
return (controlValidationGroups.indexOf(validationGroup) > -1);
}
Then in the ASP you add:
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server"
ControlToValidate="TextBox1" ValidationGroup="VG1,VG2" Display="Dynamic">
Text box is required
</asp:RequiredFieldValidator>
<asp:Button ID="Button1" runat="server" Text="Validate VG1"
OnClick="Button1_Click" ValidationGroup="VG1" />
<asp:Button ID="Button2" runat="server" Text="Validate VG2"
OnClick="Button2_Click" ValidationGroup="VG2" />
This works on the client, but on the server you would need to add custom line(s) of code to ensure the controls listed as needing to be validated by both are checked:
// controls listed as part of ValidationGroup 'VG1' will have had their
// validation tested, ones listed as 'VG1,VG2', 'VG2,VG1' etc would not
protected void Button1_Click(object sender, EventArgs e)
{
Page.Validate("VG1,VG2");
if (!Page.IsValid)
return;
// do something
}
This way the validation controls are only needed to be added once but can be implemented for multiple ValidationGroups. It's really only a workaround/hack that works on the client, the extra checks on the all-important server side validation will need to be done manually each time.
Upvotes: 0
Reputation: 432
Courtesy of Satheesh babu's artice, and having toyed with a couple of options -- I think the best way to deal with complex situations is to DIY.
I've set CausesValidation="False"
and removed ValidationGroup
s from buttons, and put something like:
OnClientClick="if (EnableVal(['ValidationGroup1','ValidationGroup2']) == false) {return false;}"
for client-side validations, where particular buttons validate increasingly complex rules as the process moves ahead. This allows me to reduce duplicating validators.
Then, on server-side, I am calling Page.Validate("ValidationGroup#")
for each group, depending on the buttons or even business process state, and then finally checking Page.IsValid
.
Also, depending on the business process state, the buttons' OnClientClick
s can be set from code-behind depending on which validation groups I want to deal with right now.
Finally, to combine validation summaries, see the javascript here: Page_ClientValidate() with multiple ValidationGroups - how to show multiple summaries simultaneously? (with some tweaks).
Net very elegant, but probably gives the most control.
Upvotes: 0
Reputation: 3662
You should add Display="Dynamic"
to your validators.
<asp:RequiredFieldValidator runat="server" ControlToValidate="txtMyDecVal"
Text="*" ErrorMessage="Enter a value" Display="Dynamic" />
<asp:RangeValidator runat="server" ControlToValidate="txtMyDecVal" Type="Double"
MinimumValue="0" MaximumValue="999.99" Text="*"
ErrorMessage="Value must be between 0 and 999.99" Display="Dynamic" />
<asp:RangeValidator runat="server" ControlToValidate="txtMyDecVal" Type="Double"
MinimumValue="0" MaximumValue="999.99" Text="*"
ErrorMessage="Value must be between 0 and 999.99"
ValidationGroup="SaveGroup" Display="Dynamic"/>
Upvotes: 1