How to combine RegularExpressionValidator control and RequiredFieldValidator? - c#

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.

Related

How to display confirmation message when a checkbox is clicked

I want to be able to display a confirmation message when asp.net checkbox is clicked, i tried using:
OnClientClick = "return confirm('Are you sure you want to logout?')"
It doesnt report error, but not working, i later found out that asp.net checkbox doen't have OnClientClick attribute.
I have also done a few research on google still couldn't achieve! Please does anyone know how to do this? Thanks in advance.
After much research i was able to implement this, here is the answer so other users who are facing this same issue can use it:
OnClick="if(!confirm('Are you sure you want to sign out?'))return false;" this works perfectly for me.
You can assign function to all checkboxes then ask for confirmation inside of it. If they choose yes, checkbox is allowed to be changed if no it remains unchanged.
In my case I am also using ASP .Net checkbox with Autopostback="True" attribute, so on server side I need to compare the value submitted vs what's currently in db in order to know what confirmation value they chose and update db only if it was "yes".
$(document).ready(function () {
$('input[type=checkbox]').click(function(){
var areYouSure = confirm('Are you sure you want make this change?');
if (areYouSure) {
$(this).prop('checked', this.checked);
} else {
$(this).prop('checked', !this.checked);
}
});
});
You can have a look at here
Checkbox check confirmation message.
You can do that by using javascript, by checking the count of the checkbox.
Like below
if (chkCount === 0) {
alert("You do not have any selected files to delete.");
return false;
} else {
return confirm("Are you sure you want to proceed deleting the selected files?");
}
Hope that helps
Since you did not mentioned below is jquery
$(document).ready(function() {
$('#yourelemntid_as_enderedHtml').change(function() {
if ($(this).prop('checked')) {
alert("Are you sure you want to logout."); //checked
}
else {
alert("text here"); //not checked
}
});
});
you also better call it on EndprocessRequest() as well as asp loose this script
And in c#
<asp:CheckBox ID="chkgen" runat="server" Checked='<%# Eval("col3") %>'
OnCheckedChanged="chkgen_OnCheckedChanged"/>
protected void chkgen_OnCheckedChanged(object sender, EventArgs e)
{
int selRowIndex = ((GridViewRow)(((CheckBox)sender).Parent.Parent)).RowIndex;
CheckBox cb = (CheckBox)gridView.Rows[selRowIndex].FindControl("chkgen");
if (cb.Checked)
{
//Perform your logic
}
}
You can use onchange in asp:checkbox, like this -
<asp:CheckBox Text="check this out" runat="server" onchange="return confirm('Are you sure you want to logout?');" />
If you have set autopostback = true, it will postback.
Problem with this is it will work for every change - be it check or uncheck, to mitigate this you can use it like this.
<asp:CheckBox Text="check this out" runat="server" onchange="return Confirmation(this);" />
function Confirmation(element)
{
if(element.checked) // so that only for checked case, this will execute.
return confirm('Are you sure you want to logout?');
else
return false;
}

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>

Multipe validation control on single textbox

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)))$"/>

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 get the 'controlToValidate' property on ClientValidationFunction?

Lets say I have this code.
<asp:TextBox ID="TextBox1" runat="server" />
<asp:CustomValidator ID="CustomValidator1" runat="server"
ClientValidationFunction="ValidationFunction1"
ControlToValidate="TextBox1"
Display="Dynamic" />
And a validationFunction:
function ValidationFunction1(sender, args)
{
}
And i would like to know if, inside the function I could get the Control to validate something like:
var v = sender.ControlToValidate;
Actually sender.controltovalidate gives the ClientID of the control. So this seems like a solution.
function ValidationFunction1(sender, args){
var v = document.getElementById(sender.controltovalidate);
}
I tried and it worked for me. Please notify if it works.
Not verified, just a hint:
var v = document.getElementById('<%=CustomValidator1.FindControl(CustomValidator1.ControlToValidate).ClientID>%');
of course you could simply do it like:
var v = document.getElementById('<%=TextBox1.ClientID%>');
if you know exactly what you're validating. The first method is good when the control to be validated is set dynamically and you don't know beforehand which one it will be.
Also FindControl() might return null so you'd need to test for that too in order to avoid an exception.
Hope this helps.
Here's my take on a server-side solution in C# to mimic the above answer, for anyone interested:
<asp:TextBox ID="txtStudentComments" runat="server"
Rows="8" Width="100%"
ToolbarCanCollapse="False" ValidationGroup="vg1" />
<asp:CustomValidator ID="cv1" runat="server" ControlToValidate="txtStudentComments"
ErrorMessage="THESE COMMENTS DO NOT SEEM RIGHT. PLEASE REVIEW THEM AGAIN!" SetFocusOnError="true"
Font-Bold="True" Font-Size="Medium" ValidationGroup="vg1" OnServerValidate="cv1_ServerValidate"></asp:CustomValidator>
And on the server:
//validate of the comment contains some specific words which imply the TET has not reviewed the comments!
protected void cv1_ServerValidate(object source, ServerValidateEventArgs args)
{
CustomValidator cv = (CustomValidator)source;
GridViewRow gvRow = (GridViewRow)cv.NamingContainer;
TextBox editor = (TextBox)gvRow.FindControl("txtStudentComments");
if (editor.Text.ToUpper().Contains("FACILITATOR TO INSERT COMMENTS HERE PLEASE"))
args.IsValid = false;
else
args.IsValid = true;
}
These two lines are the crux of it.
CustomValidator cv = (CustomValidator)source;
GridViewRow gvRow = (GridViewRow)cv.NamingContainer;
The NamingContainer will be a GridViewRow in my case, but it could be your entire page depending on your program. Either way it allows me to find the control I want, relative to the ControlToValidate object, which as mentioned will return the ClientID.
Here's my easy solution to be able to access the control to validate on client side.
Add the regular Custom Validator control with the options you might need.
<asp:CustomValidator ID="cvalShippingRegionCountries" ErrorMessage="Choose a country" ClientValidationFunction="ClientValMultiSelectCountries" runat="server" Display="Dynamic" SetFocusOnError="true" />
Then, in code behind, just add a custom attribute to store the clientID of the control to validate.
cvalShippingRegionCountries.Attributes.Add("ControlToValidateClientID", multiselectShippingRegionCountries.ClientID);
Now, in the function that deals with the validation you can access the value like this:
function ClientValMultiSelectCountries(sender, args) {
var multiselect = $find(sender.attributes.controltovalidateclientid.nodeValue);
if ( #VALIDATION_CHECK_HERE# ) {
args.IsValid = false;
}
}
You will get the clientID inside your function ;)

Categories

Resources