I am working with a wizard, where the user can sign up. There is a asp:RadioButtonList with two options, and some of the input fields in the wizard changes when the radiobutton changes. On each field there is some asp:Validators (asp:RequiredFieldValidator for example). The problem is, that when the user submits the page, the validator for the hidden textbox is still popping up.
First, here is the div tags which changes the shown textboxes and the RadioButtonList
<div id="divTxt1">
<asp:TextBox runat="server" CssClass="text" ID="txtNumber"
type="number"/>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1"
runat="server" ControlToValidate="txtNumber" EnableClientScript="true" ErrorMessage="Error" ToolTip="Error">*
</asp:RequiredFieldValidator>
</div>
<div id="divTxt2">
<asp:TextBox runat="server" CssClass="text" ID="txtNumber2"
type="number"/>
<asp:RequiredFieldValidator ID="RequiredFieldValidator2"
runat="server" ControlToValidate="txtNumber2" EnableClientScript="true" ErrorMessage="Error2" ToolTip="Error2">*
</asp:RequiredFieldValidator>
</div>
<div id="radio">
<asp:RadioButtonList ID="RadioButtonList1" runat="server" RepeatDirection="Horizontal">
<asp:ListItem Value="1" Selected="True">Privat</asp:ListItem>
<asp:ListItem Value="2">Offentlig</asp:ListItem>
</asp:RadioButtonList>
</div>
I have tried to solve it using JQuery like the following, which I have read should do the trick, but unfortunately it doesn't:
$(document).ready(function () {
$('#<%= WizardStep1.ContentTemplateContainer.FindControl("RadioButtonList1").ClientID %> input').change(function () {
if ($(this).val() == "1") {
$('#txtNumber').toggle('fast');
$('#txtNumber2').toggle('fast');
ValidatorEnable($('#<%=WizardStep1.ContentTemplateContainer.FindControl("RequiredFieldValidator1").ClientID %>')[0], false);
ValidatorEnable($('#<%=WizardStep1.ContentTemplateContainer.FindControl("RequiredFieldValidator2").ClientID %>')[0], true);
}
if ($(this).val() == "2") {
$('#txtNumber').toggle('fast');
$('#txtNumber2').toggle('fast');
ValidatorEnable($('#<%=WizardStep1.ContentTemplateContainer.FindControl("RequiredFieldValidator2").ClientID %>')[0], false);
ValidatorEnable($('#<%=WizardStep1.ContentTemplateContainer.FindControl("RequiredFieldValidator1").ClientID %>')[0], true);
}
});
});
So, any ideas what's wrong?
The client side API for validators is here.
Something you may be able to adapt to your needs (this will disable all the validators via client script):
if (Page_Validators) {
PageValidators.forEach(function(pageValidator) {
if (pageValidator == null) {return;}
vldGrp = pageValidator.validationGroup;
ValidatorEnable(pageValidator, false);
});
};
So you could add a if
block to check the validator name, or more so the .controlToValidate
which returns the target ID of the validator - then disable it:
if (Page_Validators) {
PageValidators.forEach(function(pageValidator) {
if (pageValidator == null) {return;}
if (pageValidator.controltovaliddate != "<%= txtNumber2.ClientID %>") {
return;
}
ValidatorEnable(pageValidator, false);
});
};
You should also probably add a break in the loop if it's right one, if you don't need to check any further validators. You can use .some
instead of .forEach
to break early:
if (Page_Validators) {
PageValidators.some(function(pageValidator) {
if (pageValidator == null) {return false;}
if (pageValidator.controltovaliddate != "<%= txtNumber2.ClientID %>") {
return false;
}
ValidatorEnable(pageValidator, false);
return true;
});
};
You can encapsulate this into a function:
var validatorState = function(element, isEnabled) {
if (Page_Validators) {
PageValidators.some(function(pageValidator) {
if (pageValidator == null) {return false;}
if (pageValidator.controltovaliddate != "<%= txtNumber2.ClientID %>") {
return false;
}
ValidatorEnable(pageValidator, false);
return true;
});
};
};
and use:
validatorState('txtCancellationReson', true);
or
validatorState($('#txtCancellationReson').attr('id'), true);
I found a better option was to use simply:
document.getElementById("<%=myValidator.ClientID %>").enabled = true;
The ValidatorEnabled option as suggested above automatically calls the validation of the linked control and in my case shows the error message "please enter a value for seller name" which wasn't necessary or desired..
Using the ".enabled = true" option doesn't.
use CustomValidator control for "RadioButtonList1" and separate controls visibilty logic to another javascript function.
<div id="divTxt1">
<asp:TextBox runat="server" CssClass="text" ID="txtNumber" type="number"/>
</div>
<div id="divTxt2">
<asp:TextBox runat="server" CssClass="text" ID="txtNumber2"
type="number"/>
</div>
<div id="radio">
<asp:RadioButtonList ID="RadioButtonList1" runat="server" RepeatDirection="Horizontal" onchange:"javascript:toogleTexxBoxesVisibility(this);">
<asp:ListItem Value="1" Selected="True">Privat</asp:ListItem>
<asp:ListItem Value="2">Offentlig</asp:ListItem>
</asp:RadioButtonList>
<asp:CustomValidator ID="CustomValidator1" runat="server" ClientValidationFunction="clientSideValidationFunction" ControlToValidate="RadioButtonList1" OnServerValidate="CustomValidator1_ServerValidate" Text="Validation Error Message">asp:CustomValidator>
<script type="text/javascript">
function clientSideValidationFunction(source,arguments)
var inputvalue = arguments.Value; //RadioButtonList1's value
if (inputvalue == "1" && $('#txtNumber').val() == '') {
arguments.IsValid = false;
}
else if (inputvalue == "2" && $('#txtNumber2').val() == '') {
arguments.IsValid = false;
}
else {
arguments.IsValid = true;
}
};
function toogleTexxBoxesVisibility(radiobutton)
{
if(radiobutton.val =='1')
{
$('#txtNumber').show('fast');
$('#txtNumber2').hide('fast');
}
else if(radiobutton.val =='2')
{
$('#txtNumber').hide('fast');
$('#txtNumber2').show('fast');
}
}
</script>
</div>
You can disable the validator like described in these posts:
http://www.aspdev.org/articles/asp.net-server-controls-disable-validation/
http://www.willasrari.com/blog/use-client-side-javascript-to-disable-aspnet-validators/000289.aspx
best regards