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;
}
Related
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.
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.
I am loading a control to a page dynamically with LoadControl("src to file").
In the usercontrol i have a validator and some other controls that i would like to access from my page. I canät get it to work, null pointer exception.
Scenario is like this. I have a Edit.aspx page which loads the EditTemplate.ascx usercontroll. I would like to get information or find the controls in the EditTemplate from the Edit.aspx site.
I have tried exposing the controls and validators as properties but how do i access them from my Edit.aspx?
Example code:
Edit.aspx, the control is later added into a
Control control = LoadControl("src to ascx");
TemplatePlaceHolder.Controls.Add(control);
EditTemplate.ascx
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="CompanyImageFile" ErrorMessage="RequiredFieldValidator"></asp:RequiredFieldValidator>
CodeBehind
public partial class EditTemplate : System.Web.UI.UserControl, IEditTemplate {
public RequiredFieldValidator Validator {
get { return this.RequiredFieldValidator1; }
set { this.RequiredFieldValidator1 = value; }
}
From the Edit.aspx site i would like to check the validators isValid property. Isvalid is set in a Save method.
The save button that saves the template is located in edit.aspx, so the post in done from that page.
So the question is how to get a hold of the property from the usercontrol in the edit.aspx page, where and how should this be done?
Thanks again.
Easiest way is to have the user control define properties like:
public IValidator SomeValidator {
get { return this.cuvValidator; }
set { this.cuvValidator = value; }
}
public string Text {
get { return this.txtText.Text; }
set { this.txtText.Text = value; }
}
Which your edit page can use.
HTH.
You can always use recursive approach. Check the solution on Steve Smith's blog:
Recursive-FindControl.
As mentioned in previous answers, I would expose any validators you must access from the parent ASPX page as properties in the user control.
public RequiredFieldValidator ValidatorToCheck
{
get { return this.rfvMyField; }
}
Then, you can dynamically add your user control to some placeholder (being sure to assign an ID to the user control).
// In my example, this is occurring in the Page_Load event
Control control = LoadControl("~/Controls/EditTemplate.ascx");
control.ID = "ucEditTemplate";
pnlControlHolder.Controls.Add(control); // the placeholder in my example is a panel
When you want to access the IsValid property on the given validator (presumably in your save action) you can do so as follows (being sure to cast the control to the appropriate type and using the ID you originally assigned to the user control):
EditTemplate control = (EditTemplate)pnlControlHolder.FindControl("ucEditTemplate");
if (control.ValidatorToCheck.IsValid)
{
// Some action
}
We're trying to build a simple asp control for some clients where they can just drop in a single block -
i.e.
<captcha:CaptchaControl ID="CaptchaControl1"
runat="server"
Server="http://localhost:51947/"
/>
and have it render the control. The catch is that I can't get this to include custom validation. Right now I'm using the RenderContents function to display the layout of the control itself as well as hook it up the to Javascript. The problem is that I don't know how to get custom validation to fire when used as part of a control.
protected override void RenderContents(HtmlTextWriter output)
{
output.Write(#"
<script type=""text/javascript"" src=""http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js""></script>
<link rel=""stylesheet"" type=""text/css"" href=""/Layout/CaptchaLayout.css"" />
//etc
<asp:Textbox id=""text1"" runat=""server"" text=""""></asp:Textbox>
<asp:CustomValidator id=""CustomValidator2"" runat=""server""
ControlToValidate = ""text1""
ErrorMessage = ""You must enter at least 8 characters!""
ClientValidationFunction=""validateLength"" >
</asp:CustomValidator>"
);
}
Any suggestions for a better way to do this?
Oogh, I would definitely not recommend your approach. It's very brittle and difficult to maintain, and depending on how your control is used, I'm not even sure that you can output more asp tags and have them processed properly.
Why don't you just inherit your custom control from Panel, and then in the Init or Load event handlers, add the textbox and custom validator to it? Roughly:
public class MyControl : Panel
{
public MyControl()
{
}
protected override void OnInit(EventArgs e)
{
ScriptManager.RegisterScript( ... Google script, CSS, etc. ... );
TextBox txt = new TextBox();
txt.ID = "text1";
this.Controls.Add(txt);
CustomValidator vld = new CustomValidator();
vld.ControlToValidatre = "text1";
vld.ID = "validator1";
this.Controls.Add(vld);
}
}
Your CustomValidator doesn't work because ASP.NET has no idea it's there. You are basically just dumping that output to the response... ASP.NET is not interpreting it.
It seems to me that this is a perfect situation for a User Control rather than a Custom Control. Just drop that output string in its own .ASCX file.
This is my label I want to display if the user have left out field before clicking the button. What am I doing wrong because nothing is happening when I click the button.
<asp:Label ID="lblError" runat="server"
Text="* Please complete all mandatory fields" style="display: none;" >
</asp:Label>
This is the function I call when I click on the button:
function valSubmit(){
varName = document.form1.txtName.value;
varSurname = document.form1.txtSurname.value;
if (varName == "" || varSurname == "")
{
document.getElementById('lblError').style.display = 'inherit';
}
else
{
.................other code go here...........................
return true;
}
}
Why not use the Validation controls? These will give you client and server side validation out of the box - not that I'm lazy or anything... ;-)
Edit for comment:
The RequiredFieldValidator can be set to display a single red asterisk by the side of each control, and a validation summary control could be used BUT that would take up space.
So, it's possible that ASP.Net is renaming your control, so your JS should read:
document.getElementById('<%= lblError.ClientID %>').style.display = 'inherit';
Give that a go...
Personally, I'd still use the Validator controls ;-)
You shouldn't be using lblError as an ID in JavaScript code. Instead you should use:
'<%= lblError.ClientID %>'
Of course this is only possible if you are generating the JavaScript code in the ASP.NET file.
on your desired event use this
document.getElementById('<%= lblError.ClientID %>').style.display = ""; or
document.getElementById('<%= lblError.ClientID %>').style.display = "block"
ok then try this, instead of client side, make it serverside. First set it invisible like , on formload event set invisible using lblEror.visible = false and remove style ="display:none" from html.
Then on the desired event/s make it visible and after processing again invisible.
If you want it strictly thorugh js.try this workaround. remove style from asp label. on body onload make it disable from some js function. now on the btn click event make it visible using the method something like this
function Validate()
{
var objLbl = $get('<%=lblError.ClientID%>');
if (validations fails)
{
objLbl.style.display = ""; //displays label
return false;
}
else
{
objLbl.style.display="none" //hides label
return true;
}
}
<asp:button id="btnValidate" runat="server" onclientclick="return validate();"/>
Hope this will work
Take a look at jquery, you can select by classes instead of id's which will never be altered when rendered onto the page (unlike id's)