Multipe validation control on single textbox - c#

I have following code snippet in asp.net In which I am validating a Textbox.I have added two validation control in which first validate the format of date and second validates the future data.
Now the problem is both validations fire at the same time.
I want that first it's check that date is valid or not then I want to fire rangevalidator.
<asp:TextBox Enabled="True" runat="server" size="8" MaxLength="10" meta:resourcekey="txtTravelerDOBResource2">mm/dd/yyyy</asp:TextBox>
<asp:RangeValidator ID="rangeValidator" ControlToValidate="txtTravelerDOB" MaximumValue="09/25/2013" MinimumValue="1/1/2012" Type="Date" ErrorMessage="Future Date Not allowed" runat="server"></asp:RangeValidator>
<asp:RegularExpressionValidator Enabled="True" ID="rgxDOB" runat="server" ControlToValidate="txtTravelerDOB"
Display="Dynamic" ErrorMessage="Date is not valid"
ValidationExpression="^(((0?[13578]|1[02])[\/](0?[1-9]|[12]\d|3[01])[\/]((1[6-9]|[2-9]\d)?\d{2}))|((0?[13456789]|1[012])[\/](0?[1-9]|[12]\d|30)[\/]((1[6-9]|[2-9]\d)?\d{2}))|(0?2[\/](0?[1-9]|1\d|2[0-8])[\/]((1[6-9]|[2-9]\d)?\d{2}))|(0?2[\/]29[\/]((1[6-9]|[2-9]\d)?(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)|00)))$"
></asp:RegularExpressionValidator>
I tried to enable disable the validation control using javascript as below.
function isGoodDate(){
var value=$("#ctl09_ctl00_ctl00_ctl00_rptTravelers_ctl01_txtTravelerDOB").val();
var v=$("#ctl09_ctl00_ctl00_ctl00_rptTravelers_ctl02_txtTravelerDOB").val();
var reGoodDate = /^((0?[1-9]|1[012])[- /.](0?[1-9]|[12][0-9]|3[01])[- /.](19|20)?[0-9]{2})*$/;
console.log(value);
if(reGoodDate.test(value))
{
$.each(Page_Validators, function (index, validator){
if (validator.validationGroup == "x"){
ValidatorEnable(validator, true);
}
});
}
else
{
ValidatorEnable(validator, false);
}
if(reGoodDate.test(v))
{
$.each(Page_Validators, function (index, validator){
if (validator.validationGroup == "y"){
ValidatorEnable(validator, true);
}
});
}
else
{
ValidatorEnable(validator, false);
}
}

Firstly, all the validators don't fire exactly at same time. They seem so as it happens in a fraction of seconds.
The validators that you add in a .aspx page, they are added to Page.Validators collection in the same order they are created/added to page. The validation runs in the order they are present in the Page.Validators collection.Thus the first validator in the aspx file is first in Page.Validators. If you want to rearrange the order, then the correct way is to arrange your validators in the page in the same order you want them to fire.
NOTE: The validators will fire one by one. in case you don't want the very next validators to fire you may use Javascript to disable the next ones. call a ClientValidation function in first validator
<asp:CustomValidator ID="CustomValidator1" runat="server" ControlToValidate="TextBox3"
ClientValidationFunction="disableNextVal" .... />
// Sample JavaScript code
function disableNextVal()
{
// firstly check here for first condition, if First condition fails,
// disable the next validator as below.
var nextVal = document.getElementById('nextValidatorClientID');
ValidatorEnable(myVal, false);
// or use this one:
myVal.enabled = false;
}
However, one more solution and possibly the better one is mentioned below.
In these scenarios where the value entered in TextBox should pass multiple conditions like:data format, Value should be greater than some minimum required value etc.. it is always good to use a CustomValidator control.
In this custom validator control check one by one each of your conditions. If first condition fails: date is not valid, do not check others and display the error message for first one only. Similarly, if second condition fails: range is not valid, display message for second failed condition only.
<asp:CustomValidator ID= "valxTextBox" runat="server"Enabled="true"
ControlToValidate="txtDate"
ClientValidationFunction ="ValidateTxtDate"
ValidateEmptyText="true"
OnServerValidate="valxTextBox_ValidatePostalCode"
></asp:CustomValidator>
As you see, this gives the flexibility to define your custom Client Side as well as server side events for Validation.
In your server validation, check for conditions one by one, and return as soon as you find one failing.
For validating data against regularExpressions, use Regex class of System.Text.RegularExpressions namespace.
protected void valeEmailAddress_txtEmailAddressValidate(object sender,
ServerValidateEventArgs e)
{
string MaximumValue="09/25/2013";
string MinimumValue="1/1/2012";
// check for first condition
if(txtTravelerDOB >MaximumValue ||txtTravelerDOB < MinimumValue )
{
// sample code here
// if failing, set IsValid to false
e.IsValid = false;
// dynamically set the error message as per first condition
valxTextBox.ErrorMessage ="Not a valid date";
}
// check for second condition
// read the expression pattern from appSettings
if(!Regex.Match(txtTravelerDOB.Text.Trim(),
WebConfigurationManager.AppSettings("travelerDOBRegEX")).Success)
{
// if fails,
e.IsValid = false;
valxTextBox.ErrorMessage ="Format is Invalid";
}
}
Appsettings Value:
<add key="travelerDOBRegEX" value="^(((0?[13578]|1[02])[\/](0?[1-9]|[12]\d|3[01])[\/]((1[6-9]|[2-9]\d)?\d{2}))|((0?[13456789]|1[012])[\/](0?[1-9]|[12]\d|30)[\/]((1[6-9]|[2-9]\d)?\d{2}))|(0?2[\/](0?[1-9]|1\d|2[0-8])[\/]((1[6-9]|[2-9]\d)?\d{2}))|(0?2[\/]29[\/]((1[6-9]|[2-9]\d)?(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)|00)))$"/>

Related

Custom compare validator

I've got an assignment for school in which two textboxes have to be the same, exactly the same as using a compare validator but instead we have to use a custom validator.
The code I used so far is:
protected void CustomValidator1_ServerValidate1(object source, ServerValidateEventArgs args)
{
if (TextBox2.Text == TextBox3.Text)
{
args.IsValid = true;
}
else
{
args.IsValid = false;
}
}
and in ASP.NET
<asp:CustomValidator ID="CustomValidator1" runat="server"
ErrorMessage="The second and third haven't got the same input."
onservervalidate="CustomValidator1_ServerValidate1"
ValidateEmptyText="True" ValidationGroup="Custom"></asp:CustomValidator>
But when I debug the webform nothing shows up when I fill in two different inputs.
The controls won't be validated until you attempt to submit the form to the server; they won't be validated as soon as they are edited.
You can specify AutoPostback to be true to cause the form to be submitted to the server every time the textboxes are edited, but that's likely to cause its own set of problems.
To have the form be validated entirely on the client, without posting to the server, you'll need to write that JavaScript code yourself, rather than a custom validator.
To enable client side (before posting back) validation with a CustomValidator, you must set the ClientValidationFunction to some JavaScript.
Something like:
<asp:CustomValidator ID="CustomValidator1" runat="server"
ErrorMessage="The second and third haven't got the same input."
onservervalidate="CustomValidator1_ServerValidate1"
ClientValidationFunction="CustomValidator1_ClientValidate1"
ValidateEmptyText="True" ValidationGroup="Custom"></asp:CustomValidator>
<script type="text/javascript">
function CustomValidator1_ClientValidate1(source, arguments) {
if (/* validation code */) {
arguments.IsValid = true;
} else {
arguments.IsValid = false;
}
}
</script>

Validating user controls regardless of page controls

I want to validate my user control whenever postback occurs. This is the property inside usercontrol wish I want to validate:
public string Text
{
get
{
return DateTextBox.Text;
}
set
{
DateTextBox.Text = value;
}
}
The Text Property always must have format like "YYYY/MM/DD". I want wherever user add this control to every page, when user submits any button, if the Text is not valid, button submit event does not raise. The main problem is that i want this works without altering any page. I means without checking something like Page.IsValid.
You can do this by adding ASP.Net validation controls to your .ascx markup code.
Try adding the following code
<asp:CompareValidator
id="dateValidator" runat="server"
Type="Date"
Operator="DataTypeCheck"
ControlToValidate="DateTextBox"
ErrorMessage="Please enter a valid date.">
</asp:CompareValidator>
<asp:RequiredFieldValidator
ID="RequiredFieldValidator1"
ControlToValidate="DateTextBox"
runat="server"
ErrorMessage="Required!">
</asp:RequiredFieldValidator>
But, the problem with this method is all buttons (Save or Submit) not having CauseValidation=False will try to validate this TextBox.
To overcome this issue you need to
If buttons are in the user control add a ValidationGroup to all controls (TextBox, Validation controls, buttons etc)
If buttons are in your pages
add a public property to your control to hold the ValidationGroup and assign this value to all controls and all the buttons that need to validate.
Try below code:-
public string Text
{
get
{
return DateTextBox.Text;
}
set
{
try
{
DateTime d = DateTime.ParseExact(value, "yyyy/MM/dd",CultureInfo.InvarientCulture);
DateTextBox.Text = value;
}
catch(Exception ex)
{
//// Code when it does not match format.
}
}
}

Using a validation summary to display label text

I have taken over maintenance of a site that makes calls through a WCF service. There is a validation summary that displays in a message box for some validators on the client-side. I also have a label that fires if any exceptions arise from my web service calls. After tweaking the layout, the label sits in an inconvenient spot. I want to know if there is a way to display the label text in the validation summary should the exception fire in the code behind.
Any advice is appreciated.
Example in cs file:
bool ResultUserExistence = register.CheckUniquenessUserID(txtUserId.Text);
if (ResultUniquenessEmail == null)
{
continue through code...
}
else
{
lblException.Text = "Please choose a different user name. The current user name is already registered.";
}
Validation Summary:
<asp:ValidationSummary ID="valSummary"
runat="server"
HeaderText="Please correct the following error(s):"
DisplayMode="List"
ForeColor="#FF9999"
ShowMessageBox="True"
ShowSummary="False" />
As notied in this answer you could create a custom validator, and set the message on that, which will make the message show up in your validation summary.
bool ResultUserExistence = register.CheckUniquenessUserID(txtUserId.Text);
if (ResultUniquenessEmail == null)
{
continue through code...
}
else
{
var err As new CustomValidator()
err.ValidationGroup = "UserUniqueness";
err.IsValid = False;
err.ErrorMessage = "Please choose a different user name. The current user name is already registered.";
Page.Validators.Add(err);
}
Ideally this would be factored out into a method for reusability.

ASP.NET Custom Validator not firing

Here's the deal: I built a custom validator that should only fire if there is input in the text box. When it fires, it should test to see if the text in the box is an integer, and it will reject it if not. It won't fire, though, and I'm trying to figure out why.
I put this void in the body of the partial c# class:
protected void intValidate_Validate(object sender, ServerValidateEventArgs arg)
{
int num;
bool isNum = int.TryParse(arg.ToString(), out num);
if(arg.Value.Length>0){
if (isNum)
{
arg.IsValid = true;
}
else
{
arg.IsValid = false;
}
}
else{
arg.IsValid=true;
}
}
The code for the validator is as follows:
<div class="adult">
<label>Adults ($10)</label>
<asp:TextBox runat="server" ID="wAdultLunch" class="adultLunch" MaxLength="2" />
<asp:CustomValidator ID="intValidate" ControlToValidate="wAdultLunch" ErrorMessage="Invalid number" OnServerValidate="intValidate_Validate" Display="Static" runat="server" EnableClientScript="False" ValidateEmptyText="True"></asp:CustomValidator>
</div>
Insight would be appreciated!
EDIT: I attached the postback code below
<asp:Button ID="wSubmit" runat="server" Text="Submit" OnClientClick="return validateForm();" causesvalidation="true"/>
You are doing the parse on the wrong thing. arg.ToString() will give you the string of "System.Web.UI.WebControls.ServerValidateEventArgs", when you actually want to the arg.Value (which is already a string)
So, instead of...
bool isNum = int.TryParse(arg.ToString(), out num);
Change it to (note the .Value)...
bool isNum = int.TryParse(arg.Value, out num);
Although it is a lot more complex than it actually needs to be. The whole thing could be rewritten a lot more comprehensively like this...
protected void intValidate_Validate(object sender, ServerValidateEventArgs arg)
{
int num;
arg.IsValid = int.TryParse(are.Value, out num);
}
This is because TryParse will return a true if the conversion was successful, and false otherwise.
And as a final thought, all this could be achieved using the <asp:RequiredFieldValidator ...>, <asp:CompareValidator Operator="DataTypeCheck" Type="Integer" ...> and <asp:RangeValidator ...> validator controls.
UPDATE
As the OP points out, he doesn't want the error when when the textbox is empty, so instead try this...
protected void intValidate_Validate(object sender, ServerValidateEventArgs arg)
{
if (args.Value.Length > 0)
{
int num;
arg.IsValid = int.TryParse(are.Value, out num);
}
else
{
arg.IsValid = true;
}
}
And has already been pointed out by #HansKesting... this will only ever be called if all client-side validation is passed. As soon as client-side validation fails, the submission of the form back to the server is also cancelled.
I don't know if it's related, but I had an issue with a custom validator not firing. I had it validating a dropdownlist, which had a default value of an empty string. I had to set
ValidateEmptyString="true"
and then it started working just fine.
You could also call the Validate() function and read the IsValid property from the custom validator control. However, the Page's validation function should work just fine, and shouldn't require such a call.
I suppose you have a server side event to execute if the validation passes.
for ex: a button click event.
In that if you check Page.IsValid then it will be false if the validation passes then Page.IsValid will be true.
You need to use Page.IsValid to check whether the validation passed or not.
On the front-end try setting the CausesValidation attribute to true as shown below. See if that helps.
<asp:Button ID="btnSubmit" Text="Submit" CausesValidation="true" runat="server" />

How to combine RegularExpressionValidator control and RequiredFieldValidator?

I often use regex expression validators that are also a required field. Which leads to what seems like redundant controls on the page. There is no "Required" property of the regex validator which means I need another control. Like this:
<asp:TextBox ID="tbCreditCardNumber" runat="server" Width="200"></asp:TextBox>
<asp:RegularExpressionValidator ID="revCreditCardNumber" runat="server"
ControlToValidate="tbCreditCardNumber" ValidationGroup="CheckoutGroup" ErrorMessage="Invalid Credit Card Number!"
ValidationExpression="^(3[47][0-9]{13}|5[1-5][0-9]{14}|4[0-9]{12}(?:[0-9]{3})?)$">*</asp:RegularExpressionValidator>
<asp:RequiredFieldValidator ID="rfvCreditCardNumber" runat='server' ControlToValidate="tbCreditCardNumber" ValidationGroup="CheckoutGroup"
ErrorMessage="Credit Card Number Required">*</asp:RequiredFieldValidator>
Is there a way to combine the two controls so I don't have to type so much code?
One common problem is that the validator component still takes space when it is not shown, which looks odd if you have several and i.e. the last one is triggered leaving a larger gap to the asterisk or other error marker. This can be easily solved by adding:
display="Dynamic"
...to the validator.
But it does not solve the problem of several trigging at the same time which will still show many validator errors in a row. A custom validator would then probably be the best solution.
You can roll your own CustomValidator, combining the functionality. Other than that, no not to my knowledge.
You can override EvaluateIsValid method
public class RegularExpressionValidatorEx : RegularExpressionValidator
{
protected override bool EvaluateIsValid()
{
string controlValidationValue = base.GetControlValidationValue(base.ControlToValidate);
if ((controlValidationValue == null) || (controlValidationValue.Trim().Length == 0))
{
return false;
}
return base.EvaluateIsValid();
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
Page.ClientScript.RegisterStartupScript(GetType(), "customVal", ClientID + #".evaluationfunction = function(val){
var value = ValidatorGetValue(val.controltovalidate);
if (ValidatorTrim(value).length == 0)
return false;
return RegularExpressionValidatorEvaluateIsValid(val);}", true);
}
}
To be more specific, you need to set the ValidateEmptyMessage property of the CustomValdiator to true, otherwise he won't validate emprty input fields. Example:
<script type="text/javascript">
function clientValidate(sender, args){
if (args.Value.length == 0) {
args.IsValid = false;
}
}
</script>
<asp:CustomValidator runat="server"
ID="CustomValidator"
ControlToValidate="TextBox1"
ClientValidationFunction="clientValidate"
ValidateEmptyText="true"
Text="Error!">
</asp:CustomValidator>
But, as you can see this is in no way shorter than your former code, so if it is up to me, there is no point in using custom validator in this very case. As for the original question, unfortunately there is no way to make the default RegExpressValidator validate empty input fields.

Categories

Resources