Validators / Controls will be executed always even a condition is false - asp.net

I'm experienced in developing with ASP.NET MVC but have to deal with a lagacy web application with web forms.
I have an html form and inside, there are several input fields and validators (<asp:TextBox />, <asp:CustomValidator />, <ajax:MaskedEditValidator />).
The second part of the form should only be rendered / visible if a condition resolves to true. Also the associated validators inside this block should only validate if a given condition resolves to true. For this I wrapped the respective part in a condition block:
<%
if (condition)
{
%>
...
<ajax:MaskedEditExtender runat="server" ID="meePreisProGruppe" TargetControlID="PreisProGruppeInsertTextBox"
Mask="999" MessageValidatorTip="true" OnFocusCssClass="MaskedEditFocus"
OnInvalidCssClass="MaskedEditError" MaskType="Number" InputDirection="RightToLeft"
AutoComplete="false" ErrorTooltipEnabled="True" />
<ajax:MaskedEditValidator ID="mevPreisProGruppe" runat="server" ValidationGroup="vgBuchungsanfrageMP"
ControlExtender="meePreisProGruppe" ControlToValidate="PreisProGruppeInsertTextBox" IsValidEmpty="false"
InvalidValueMessage="Preis p.Gruppe ungültig" emptyvaluemessage="Preis p.Gruppe fehlt" EmptyValueBlurredText='<img src="/bsb/img/srf/icon_exclamation_error.gif">'
InvalidValueBlurredMessage='<img src="/bsb/img/srf/icon_exclamation_error.gif">'
Display="Dynamic" />
...
<asp:CustomValidator ID="cvRechnungsadresse" Display="Dynamic" ErrorMessage="Rechnungsadresse nicht vollständig!"
OnServerValidate="ServerValidationRechnungsadresse" ValidationGroup="vgBuchungsanfrageMP"
runat="server" />
...
<%
}
%>
With this, the controls do not get rendered, this is what I want. But all the validators will be executed independent to what the condition resolve, though.
How can I solve this issue?

My answer below is based on the assumption that the condition for validators to evaluate is different from the condition for the input control/validators to be rendered.
There is a standard JavaScript function called ValidatorValidate when you use validation in web forms. You need to override this using sample code like below to implement your requirement.
An important point to keep in mind with this solution is to place the code below just before the closing body tag so the function being overridden has been already loaded in browser else you might get a JavaScript error saying that window.ValidatorValidate is undefined.
Also, implement same requirement on server-side using the C# code below, since validators are evaluated on client-side as well as server-side.
Override ValidatorValidate function in JavaScript
<script type="text/javascript">
//create a condition in JavaScript for your validators to validate
//make condition a global variable, like here ( don't set it inside a function)
var condition = ...; //write your condition code on right side of equal operator
//populate this array with client ID's of all validators for which you want to conditionally validate
var conditionalValidatorIds = [];
conditionalValidatorIds.push("<%= validator1.CleintID%>";
conditionalValidatorIds.push("<%= validator2.CleintID%>";
conditionalValidatorIds.push("<%= validator5.CleintID%>";
//now override the standard ValidatorValidate function
var originalValidatorValidate = window.ValidatorValidate;
window.ValidatorValidate = function (val, validationGroup, event) {
//check if the condition is true and if yes then skip this function for all
//validators within the conditionalValidatorIds array
if(condition === true) {
for(var i=0; i < conditionalValidatorIds.length; i++) {
if( val.id === conditionalValidatorIds[i] ) {
val.isvalid = true;
ValidatorUpdateDisplay(val);
return;
}
}
}
//perform original validation when condition is false
window.originalValidatorValidate(val, validationGroup, event);
}
</script>
C# code to override validators evaluation on server-side
public override void Validate(string validationGroup)
{
//you will need to define yourCondition on server-side
bool enableValidators = (someCondition === true);
//then enable/disable your validators based on above condition
validator1.Enabled = enableValidators;
validator2.Enabled = enableValidators
validator3.Enabled = enableValidators;
base.Validate(validationGroup);
}
Another option instead of using above approach is to define only custom validators ( no standard validators like requiredfieldvalidator or comparevalidator etc.) within the if condition block and then within each custom validator client-side function, just check for the condition and if its true then set args.IsValid = true; in it. Do the same on server-side events you have for these custom validators.

Related

Custom Validation not working in ASP.NET

I need to have a custom validation for a "Save" operation in my page. The requirement is that, I need to display the alert and when I click the OK button in the alert, my page should not be posted back.
Here goes my code.
function RedirectForSaveValidation(source,arguments) {
var StatusFlag = '';
StatusFlag = document.getElementById('<%= HiddenStatusFlag.ClientID%>');
if (StatusFlag == "F") {
alert("Selected student entry has been qualified for lead. Entry cannot be modified...!");
arguments.IsValid = false;
}
if (StatusFlag == "Q") {
alert("Selected student has been scheduled for interview/counselling. Entry cannot be modified...!");
arguments.IsValid = false;
}
if (StatusFlag == "S") {
alert("Selected student entry has been scheduled with interview/counselling. Entry cannot be modified...!");
arguments.IsValid = false;
}
if (StatusFlag == "I") {
alert("Selected student entry has been converted to Intake. Entry cannot be modified...!");
arguments.IsValid = false;
}
window.location.assign("EnquiryRegister.aspx");
}
I call this function in my button click.
<asp:Button ID="btnSaveEnquiryRegister" runat="server" Text="Save Enquiry Register" CssClass="button" OnClick="btnSaveEnquiryRegister_Click" ValidationGroup="valEnquiry" OnClientClick="RedirectForSaveValidation();"/>
The issue is, I am not getting any alert as I have specified and my page is posted back. What am I missing?
The correct way for solving this problem would be to use CustomValidator control and its ClientValidationFunction property. With this you can integrate your client side validation with ASP.NET validation functionality.
Have a look at the example on MSDN documentation.
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.customvalidator.clientvalidationfunction.aspx
Hope it helps!
Regards,
Uroš
Your are using a Custom Validation function directly on button click. Look you are passing two parameters in the Function and OnClientClick you are not passing parameters. this method should be called through CustomValidator control of asp.net.
Or just remove parameters from method. Use method without parameters
well this is not the correct way to implement the custom validator look at this http://www.w3schools.com/aspnet/control_customvalidator.asp and http://www.w3schools.com/aspnet/showaspx.asp?filename=demo_customvalidator (show you how to do it properly)
but still if you want to do the validation like this you have to return false in case it is not valid
so your validation function should return true (in case it is valid) or false
then
<asp:Button ID="btnSaveEnquiryRegister" runat="server" Text="Save Enquiry Register" CssClass="button" OnClick="btnSaveEnquiryRegister_Click" ValidationGroup="valEnquiry" OnClientClick="return RedirectForSaveValidation();"/>
Silly me! The issue was with getting the value of my hidden field.
var StatusFlag = '';
StatusFlag = document.getElementById('<%= HiddenStatusFlag.ClientID%>').value;
I had missed to include value property so the variable had empty value which caused the validator to fail.

asp.net - manually run client-side validation code from another event

I want to run whatever client-side validation routine is hooked up to a particular text input element.
The validation has been set up using CustomValidator:
<asp:textbox id="AddEstTime" runat="server" Width="55px"></asp:textbox><br />
<asp:CustomValidator ID="AddEstTimeCustomValidator" ClientValidationFunction="AddEstTimeCustomValidator_ClientValidate" OnServerValidate="AddEstTimeCustomValidator_ServerValidate" ErrorMessage="Please enter a time" ControlToValidate="AddEstTime" runat="server" Display="Dynamic" ValidateEmptyText="true"/>
<asp:CheckBox ID="AddIsTM" runat="server" Text="T&M" />
and the javascript:
function AddEstTimeCustomValidator_ClientValidate(sender, args) {
var checkbox = $("input[id$='IsTM']");
args.IsValid = checkbox.is(":checked") || args.Value.match(/^\d+$/);
}
When the CheckBox "AddIsTM" state changes, I want to revalidate the textbox "AddEstTime", using its hooked-up CustomValidator "AddEstTimeCustomValidator".
I am aware of focus -> add a character refocus -> remove character. I am trying to find a more correct way. New to asp.NET.
After looking through the Microsoft client-side code, I came up with this which seems to work:
// client-side validation of one user-control.
// pass in jquery object with the validation control
function ValidateOneElement(passedValidator) {
if (typeof (Page_Validators) == "undefined") {
return;
}
$.each(Page_Validators, function (index, value) {
if ($(value).attr("id") == passedValidator.attr("id")) {
ValidatorValidate(value, null, null);
}
});
}
This was after examining the Page_ClientValidate function:
function Page_ClientValidate(validationGroup) {
Page_InvalidControlToBeFocused = null;
if (typeof(Page_Validators) == "undefined") {
return true;
}
var i;
for (i = 0; i < Page_Validators.length; i++) {
ValidatorValidate(Page_Validators[i], validationGroup, null);
}
ValidatorUpdateIsValid();
ValidationSummaryOnSubmit(validationGroup);
Page_BlockSubmit = !Page_IsValid;
return Page_IsValid;
}
thx sennett (voted)
i just ran the simplest JS
Page_ClientValidate();
if you have a validation group then is
Page_ClientValidate("validationGroupName")
If you want stick with ASP.NET validators eventually you can abuse Validation Groups, but I think that this approach will give you nothing but trouble. Other option is to use jQuery on the client (nice list) only then you will have to duplicate validation on the server side, or to avoid that call server methods from client validations.

How to stop WebForm_doPostBack() conditionally?

I need to run some script by onclick() of some , checkbox particularly, to decide should i invoke WebForm_doPostBack() or not.
If I will submit form in myScript() myself, it will not cause validation of another asp.net validators, so I really need a native WebForm_doPostBack() call.
Should I handle a submit form event or are there any more "asp.net" ways to do it?
CustomValidators don't work with checkboxes:).
Just to ensure your assumptions that custom validators do not work with checkboxes is not the ONLY reason for wanting to handle the checkbox click seperately, here is some code that will validate checkboxes using ASP.NET custom validators.
Custom Validators have a ClientValidationFunction property that is called automatically when the __doPostback is called or the form is submitted.
//The Script
function validateCheckBox(source, arguments)
{
if(!source.checked) arguments.IsValid = false;//set IsValid property to false
}
//The Validator
<asp:CustomValidator ID="validateCheckbox" runat="server" ControlToValidate="CheckBox1" ErrorMessage="You REALLY need to check this!" Display="Static" ClientValidationFunction="validateCheckBox"/>
Don't you try simply putting your own validation at submit button like that :
btnSubmit.Attributes["onclick"] += "return myValidation();";
<script>
function myValidation()
{
// if you do not want to postback just return false...
return true;
}
</script>
EDIT : You can use Page_ValidationActive to programmatically enable / disable the client side validation of your page.
Page_ValidationActive A Boolean
value that indicates whether
validation should take place. Set this
variable to false to turn off
client-side validation
programmatically.

How to set Page.IsValid in ASP.Net

When the page class property IsValid is read only, how can I set it using my own validation method?
So far all I've been able to do is set this property by calling Page.Validate().
How can I write my own functionality that will change the IsValid property just like Page.Validate()?
You don't set IsValid directly instead you call Validate() method of the Page object. If you have your custom validation methods then you need to use CustomValidator object and set that function in its server side validation property.
<asp:CustomValidator ID="YourValidator" runat="server" SetFocusOnError="true"
ControlToValidate="YourControl"
ClientValidationFunction="YOUR_JAVASCRIPT_FUNCTION"
OnServerValidate="YOUR_SERVER_VALIDATION_FUNCTION" Text="*" />
I know this is old, but, I needed to do something similar, basically forcing the IsValid property to false (don't ask why). Here is what I did basically (what you see here is my proof of concept):
Added this to the .aspx page:
<asp:TextBox ID="txtDummy" runat="server" Visible="false" />
<asp:RangeValidator ID="rvDummy" ControlToValidate="txtDummy" runat="server" MinimumValue="1" MaximumValue="2" />
And then I added this to the code behind:
bool makeMyPageInvalid = true;
if (makeMyPageInvalid)
txtDummy.Text = "0";
Page.Validate();
if (Page.IsValid)
ScriptManager.RegisterStartupScript(Page, Page.GetType(), "test", "alert('valid');", true);
else
ScriptManager.RegisterStartupScript(Page, Page.GetType(), "test", "alert('not valid');", true);
You can see that this only allows you to force the page validation to an invalid state. You can use any validator or reason to set this. Hope this helps someone!
The IsValid property is read-only because it is intended for use with server and client-side validators like the RequiredFieldValidator and RegularExpressionValidator. It's read-only because you can't force a page to be valid programmatically. "Valid" in this context means all the validators on the page evaluate to true.
If you feel like using some JavaScript you can do it in the client-side by modifying the variable Page_IsValid like this:
function pageLoad() {
Page_IsValid = false;
}
I use this just in case someone clicks the submit button w/o entering data. Then I can display an alert like this:
function valid() {
if (!Page_IsValid) {
alert("Some Questions Remain Unanswered and are Marked with a Red Asterisc. ( * )");
}
(at the beginning I thought 'who would submit a form w/o data' but sooner rather than later I realized it happens)
This is a really old question, but it came up in a search so I thought I'd add my answer to it. First, create an extension method in one of your helper classes.
public static IEnumerable<T> GetAllControlsOfType<T>(this Control parent) where T : Control
{
var result = new List<T>();
foreach (Control control in parent.Controls)
{
if (control is T)
{
result.Add((T)control);
}
if (control.HasControls())
{
result.AddRange(control.GetAllControlsOfType<T>());
}
}
return result;
}
Now in your code behind file, loop over every validator on the page that is not validating.
foreach (var validator in Page.GetAllControlsOfType<BaseValidator>().Where(w => !w.IsValid))
{
validator.IsValid = true;
}

How to skin all ASP.Net validators?

I want all of the validators in an ASP.Net 3.5 website to have a CssClass value of "error". My initial thought was to do this in a theme skin like so:
<asp:CompareValidator runat="server"
CssClass="error" />
<asp:CustomValidator runat="server"
CssClass="error" />
<asp:RequiredFieldValidator runat="server"
CssClass="error" />
<belCommon:ZipCodeValidator runat="server"
CssClass="error" />
<belCommon:PhoneNumberValidator runat="server"
CssClass="error" />
This is only a partial listing of validators that I use. Ideally, I would like to do something like this:
<asp:BaseValidator runat="server"
CssClass="error" />
And because all validators inherit from BaseValidator, I would expect that this would work, but it doesn't. Is there a way to accomplish this without adding every single validator control to the skin explicitly?
Update:
I found a different approach using javascript:
Sys.Application.add_init(function(sender, args)
{
if (Page_Validators != null)
{
for (i = 0; i < Page_Validators.length; i++)
{
Page_Validators[i].className = "error";
}
}
});
ASP.Net generates a javascript variable called Page_Validators, which is an array of the validation spans. This script checks to see if it exists and then loops through and sets the class name. I added this to the master page and its working so far.
Not that I am aware of, when defining a skin you are specifically working with individual controls and you don't have a way of specifying it any other way, as it matches based on the tags used.
From the looks of it though, you are creating your own custom validators as well, you might modify your controls to have a default cssclass of error to save a bit of time.
I'd be tempted to iterate over the controls of the page in the server pageload method and to apply the css class there:
foreach (object obj in this.Controls)
{
if (obj is BaseValidator)
{
((BaseValidator)obj).CssClass = "error";
}
}
This may not be the best way to do this and I've not had the opportunity to test it but hopefully it might help you along the way.
I found a different approach using javascript:
Sys.Application.add_init(function(sender, args)
{
if (Page_Validators != null)
{
for (i = 0; i < Page_Validators.length; i++)
{
Page_Validators[i].className = "error";
}
}
});
ASP.Net generates a javascript variable called Page_Validators, which is an array of the validation spans. This script checks to see if it exists and then loops through and sets the class name. I added this to the master page and its working so far.

Resources