.NET Forum / ASP.NET / General / September 2007
Validation Controls, Override/append Client Side Functionality
|
|
Thread rating:  |
IfThenElse - 26 Sep 2007 17:27 GMT Hello,
I am wondering how can I Override/Append to the Client Side JavaScript of a System.Web.UI.WebControls.RequiredFieldValidator Control.
I actually need to only add few lines of JavaScript to the Microsoft Supplied JavaScript Function.
So I need to Just extend it to do one or two extra things for me.
I know I can create a new Validation Control to do such thing but I wonder If I can Inherit the exiting functionality.
If I inherit the "System.Web.UI.WebControls.RequiredFieldValidator" How can I call the base class JavaScript that does the validation and then add some more to it.
I have seen Scott Michell's "Creating Validator Controls for CheckBox" etc... No inheritance because there was none. So the example does not answer my needs.
thanks
Shelly - 26 Sep 2007 17:56 GMT > Hello, > [quoted text clipped - 16 lines] > etc... No inheritance because there was none. So the example does not > answer my needs. I'm guessing, mind you, and have never done this, but from what I **just** learned could you encapusate that validation control inside a user control where you add what you need in the code-behind section?
Shelly
IfThenElse - 26 Sep 2007 19:29 GMT Shelly,
No, This is a built in server control "System.Web.UI.WebControls.RequiredFieldValidator" I want to inherit it and add just functionality for the client side JavaScript only but still calling the base-JavaScript-function that M.S. provided.
encapsulate that validation control inside a user control will not work for me. I am looking for a more elegant solution.
I can rewrite the entire control as System.Web.UI.WebControls.MyRequiredFieldValidator but I was hoping to inherit.
Thanks for you reply.
>> Hello, >> [quoted text clipped - 22 lines] > > Shelly bruce barker - 26 Sep 2007 19:30 GMT there is no support for inheriting. the required validator javascript is in a resource file that is downloaded if you use validation.
to do what you want is simple:
<script> function myRequired(s,a) { a.IsValid = true; rq = document.getElementById('<%=rqMS%>'); if (!rq.evaluationfunction(s,a)) a.IsValid = false; else { // my additional test } return a.IsValid } </script>
<!-- need one dummy rq validator -->
<asp:RequiredFieldValidator id=rqMS runat=server enabled=false controltovalidate=foo />
<asp:customvalidator runat=server controltovalidate=foo clientvalidationfunction="myRequired" errormessage="required" /> <asp:textbox id=foo runat="server" /> <asp:customvalidator runat=server controltovalidate=foo2 clientvalidationfunction="myRequired" errormessage="required" /> <asp:textbox id=foo2 runat="server" />
-- bruce (sqlwork.com)
> Hello, > [quoted text clipped - 18 lines] > > thanks IfThenElse - 26 Sep 2007 19:48 GMT Hi Bruce,
I am already using a custom validator to deal with this issue. I was hoping to not use any dummies. I have many fields to validate ( required, RegExp, etc...)
All I want to do is not to add more validation at the end but to scroll the window to a better "cosmetically" nicer position when validation fails and focus on error is set to true.
I wish M.S. added one more property to each Validation function that allows you to move the window scroll to some href#tag after focusing on Validation Failure.
I hope I was clear.
Any other Ideas.
Thank You,
> there is no support for inheriting. the required validator javascript is > in a resource file that is downloaded if you use validation. [quoted text clipped - 61 lines] >> >> thanks Teemu Keiski - 26 Sep 2007 19:57 GMT Hi,
In ASP.NEt 2.0 RequiredFieldValidatorIsValid is defined in System.Web assembly's resources (WebUIValidation.js). it looks like:
function RequiredFieldValidatorEvaluateIsValid(val) { return (ValidatorTrim(ValidatorGetValue(val.controltovalidate)) != ValidatorTrim(val.initialvalue)) }
You can do a function pointer switch in JavaScript. Basically first create a member to point to the old function, then create your new function which can use the previous member in case it needs to call the default implementation/method. Then assign your new method to the original function. In pseudo-code something like:
//Reference the original method var fxRequiredFieldValidatorIsValid = RequiredFieldValidatorEvaluateIsValid;
function MyRequiredFieldValidatorIsValid(val) { //Do your logic here (you can also do it after call to original method, just note that you shoul return a boolean to indicate the validation outcome) alert("This should be called...")
//Use original method reference to call the original method return fxRequiredFieldValidatorIsValid(val); }
However in this case, in ASP.NEt 2.0, reference to the used function is stored in as member of the validator element itself. If you check the markup it can look like:
var ctl02 = document.all ? document.all["ctl02"] : document.getElementById("ctl02"); ctl02.controltovalidate = "ddlAccomodationCountry"; ctl02.errormessage = "Make a selection"; ctl02.evaluationfunction = "RequiredFieldValidatorEvaluateIsValid"; ctl02.initialvalue = "0";
Note especially evaluationfunction attribute.
So just assigning
RequiredFieldValidator = MyRequiredFieldValidatorIsValid;
doesn't in fact seem to work. However you can write instead
<body onload="myLoad()">
function myLoad() { for(var i = 0;i<Page_Validators.length;i++) { if(Page_Validators[i].evaluationfunction == fxRequiredFieldValidatorIsValid) { Page_Validators[i].evaluationfunction = MyRequiredFieldValidatorIsValid; } } }
******* complete test page *********
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Untitled Page</title> </head> <body onload="myLoad()"> <form id="form1" runat="server"> <div>
<asp:DropDownList ID="ddlAccomodationCountry" runat="server"> <asp:ListItem Value="0" Text="Please make a selection" /> <asp:ListItem Value="1" Text="Country 1" /> <asp:ListItem Value="2" Text="Country 2" /> <asp:ListItem Value="3" Text="Country 3" /> </asp:DropDownList>
<asp:RequiredFieldValidator ControlToValidate="ddlAccomodationCountry" InitialValue="0" runat="server" ErrorMessage="Make a selection" />
<asp:Button ID="Button1" runat="server" Text="Button" /> <asp:ValidationSummary ID="ValidationSummary1" runat="server" />
</div> </form> <script type="text/javascript">
//Reference the original method var fxRequiredFieldValidatorIsValid = RequiredFieldValidatorEvaluateIsValid;
function MyRequiredFieldValidatorIsValid(val) { //Do your logic here (you can also do it after call to original method, just note that you shoul return a boolean to indicate the validation outcome) alert("This should be called...")
//Use original method reference to call the original method return fxRequiredFieldValidatorIsValid(val); }
function myLoad() { for(var i = 0;i<Page_Validators.length;i++) { if(Page_Validators[i].evaluationfunction == fxRequiredFieldValidatorIsValid) { Page_Validators[i].evaluationfunction = MyRequiredFieldValidatorIsValid; } } }
</script> </body> </html>
*** test page ends ***
Remember to always check Page.IsValid in server-side code too.
 Signature Teemu Keiski AspInsider, ASP.NET MVP http://blogs.aspadvice.com/joteke http://teemukeiski.net
> Hello, > [quoted text clipped - 18 lines] > > thanks IfThenElse - 26 Sep 2007 20:15 GMT Teemu,
What I would like to specifically is:
If Validation Fails and I have set Focus on Error to True I want to add just a document.location.href = "my#Tag";
I wonder when does and where does the focus occur in what function.
After the Focus on the first Invalid Field I want to be able to issue document.location.href = .... for that specific field. This is just cosmetically to adjust the screen or webpage vertical position. I am doing it now but with too much work, adding custom validator for many of my field controls some as groups.
the value of document.location.href if different for different Fields on my Form but always on the same page.
I am hoping to find a better, faster, easier solution so for any future web pages. this will save me lots of time.
Thank you for any further input.
> Hi, > [quoted text clipped - 149 lines] >> >> thanks Teemu Keiski - 26 Sep 2007 20:22 GMT If you use Reflector disassebler tool, you can view the resource file your self. The method which sets focus in error case is ValidatorSetFocus
function ValidatorSetFocus(val, event) { var ctrl; if (typeof(val.controlhookup) == "string") { var eventCtrl; if ((typeof(event) != "undefined") && (event != null)) { if ((typeof(event.srcElement) != "undefined") && (event.srcElement != null)) { eventCtrl = event.srcElement; } else { eventCtrl = event.target; } } if ((typeof(eventCtrl) != "undefined") && (eventCtrl != null) && (typeof(eventCtrl.id) == "string") && (eventCtrl.id == val.controlhookup)) { ctrl = eventCtrl; } } if ((typeof(ctrl) == "undefined") || (ctrl == null)) { ctrl = document.getElementById(val.controltovalidate); } if ((typeof(ctrl) != "undefined") && (ctrl != null) && (ctrl.tagName.toLowerCase() != "table" || (typeof(event) == "undefined") || (event == null)) && ((ctrl.tagName.toLowerCase() != "input") || (ctrl.type.toLowerCase() != "hidden")) && (typeof(ctrl.disabled) == "undefined" || ctrl.disabled == null || ctrl.disabled == false) && (typeof(ctrl.visible) == "undefined" || ctrl.visible == null || ctrl.visible != false) && (IsInVisibleContainer(ctrl))) { if (ctrl.tagName.toLowerCase() == "table" && (typeof(__nonMSDOMBrowser) == "undefined" || __nonMSDOMBrowser)) { var inputElements = ctrl.getElementsByTagName("input"); var lastInputElement = inputElements[inputElements.length -1]; if (lastInputElement != null) { ctrl = lastInputElement; } } if (typeof(ctrl.focus) != "undefined" && ctrl.focus != null) { ctrl.focus(); Page_InvalidControlToBeFocused = ctrl; } } }
and it is triggered by ValidatorValidate
function ValidatorValidate(val, validationGroup, event) {
So I think what you want to achieve isn't too far.
I think you should be able just reset the focused control's focus() method with similar tactics to set the anchor position.
obj.focus = yourfunction;
 Signature Teemu Keiski AspInsider, ASP.NET MVP http://blogs.aspadvice.com/joteke http://teemukeiski.net
> Teemu, > [quoted text clipped - 173 lines] >>> >>> thanks IfThenElse - 26 Sep 2007 21:00 GMT Teemu,
Originally I added the property off OnFocus="MyFocusFunction" for each field in my form . this was setting the Focus whether the control received the focus due to user clicking in a textbox or tabbing to a text box. ( textbox for example) Somehow I did not want that functionality. Now I am thinking, I can do the same thing, but check first if the field got focus and it is or was Invalid then I can do my window.location.href = MyTag#OnTheWebPage.
I don't remember but I think I had some issues with that Idea of OnFocus="myfocusfunction" but I don't remember what. I am revisiting as soon as time allows.
I am also trying to understand the function ValidatorSetFocus(val, event){} do you know where the definitions are for the val and event Parameters?
background: I can do JavaScript but I don't know it well yet...
Using reflector, can you give me a one sentence on how to use it please?
Thank you for your input and help..... it has and will be useful for me.
> If you use Reflector disassebler tool, you can view the resource file your > self. The method which sets focus in error case is ValidatorSetFocus [quoted text clipped - 235 lines] >>>> >>>> thanks Teemu Keiski - 27 Sep 2007 16:49 GMT If you have reflector from here: http://www.aisto.com/roeder/dotnet/
Open it and if it asks specify 2.0 as Framework version (you can change that later plus also view same assemblies from different FX versions). You should have System.Web assembly already in the tree, expand it. Under it you'll find Resources node, expand it also and locate WebUIValidation.js (it'd on bottom) Right click on top of it and choose "View Resource"
 Signature Teemu Keiski AspInsider, ASP.NET MVP http://blogs.aspadvice.com/joteke http://teemukeiski.net
> Teemu, > [quoted text clipped - 262 lines] >>>>> >>>>> thanks IfThenElse - 27 Sep 2007 17:41 GMT Thank you, will try it.
> If you have reflector from here: > http://www.aisto.com/roeder/dotnet/ [quoted text clipped - 274 lines] >>>>>> >>>>>> thanks IfThenElse - 27 Sep 2007 00:16 GMT Hi Teemu,
in the function function MyRequiredFieldValidatorIsValid(val) { .... } below
How do I get the current control or its Id that is being validated. or the group_id from within the MyRequiredFieldValidatorIsValid(val) function???
val mean Value but how about the control itself.
Thank you,
> Hi, > [quoted text clipped - 149 lines] >> >> thanks Teemu Keiski - 27 Sep 2007 16:44 GMT val.controltovalidate should return you the control which the validator is validating.
 Signature Teemu Keiski AspInsider, ASP.NET MVP http://blogs.aspadvice.com/joteke http://teemukeiski.net
> Hi Teemu, > [quoted text clipped - 162 lines] >>> >>> thanks Teemu Keiski - 27 Sep 2007 16:51 GMT To add, val refers to the client-side DOM element representing the validator.
 Signature Teemu Keiski AspInsider, ASP.NET MVP http://blogs.aspadvice.com/joteke http://teemukeiski.net
> val.controltovalidate should return you the control which the validator is > validating. [quoted text clipped - 165 lines] >>>> >>>> thanks IfThenElse - 27 Sep 2007 16:56 GMT Hi Teemu,
Thank you for the JavaScript-Function-Hijacking-delegating-hooking-intercepting trick.
I don't know what to call it you call it function pointer switching. Nice.
This works for me as a second option. because if Microsoft changes the name of the JavaScript functions that I am using then my code no longer works.
Do you agree that the ValidatorSetFocus(val, event) is inefficient? Since the focus should be on the First Validator that Fails, it seems that it is Fired for every Failed Validator
Is there a function or can I do a switch at ValidationFinihed Event or Function and get the First Validator That Failed Info?
Thank you for your valuable help.
> val.controltovalidate should return you the control which the validator is > validating. [quoted text clipped - 165 lines] >>>> >>>> thanks Teemu Keiski - 27 Sep 2007 17:16 GMT Validation is initiated by calling Page_ClientValidate() or Page_ClientValidate(group).
So maybe you could wire your own function to it - before calling to base Page_ClientValidate set a flag to indicate that validation has initiated and then in ValidatorSetFocus, when the flag is true (called the ValidatorSetFocus for the first time) do what you need to do and set the flag to false after that - e.g that logic runs only once and then in the wired method - after the call to base.ClientValidate() - also set the flag back to false.
It might also work that after call to wired Page_ClientValidate() (base method), loop through Page_Validators array, and find the first failed validator.
 Signature Teemu Keiski AspInsider, ASP.NET MVP http://blogs.aspadvice.com/joteke http://teemukeiski.net
> Hi Teemu, > [quoted text clipped - 186 lines] >>>>> >>>>> thanks IfThenElse - 27 Sep 2007 18:37 GMT Teemu,
I implemented the ValidatorSetFocus(val, event) Switch and that works. However a bit of work. For what I want that is better so far because it handles any validator ( not only required Field. etc.. )
I will look into the Page_ClientValidate Functions switch soon.
I was wondering, How do I ask a Validator if it is valid or not.
I tried something like MyValidatorID.IsValid but that did not work for me. Got undefined error.
MyValidatorID.IsValid() // no good.
I know args.IsValid works But I have no Args
I tried MyValidatorID.args.IsValid' is null or not an object
Thank you,
> Validation is initiated by calling Page_ClientValidate() or > Page_ClientValidate(group). [quoted text clipped - 203 lines] >>>>>> >>>>>> thanks Teemu Keiski - 27 Sep 2007 19:09 GMT In client-side DOM a validator has isvalid property (written literally in lowercase)
 Signature Teemu Keiski AspInsider, ASP.NET MVP http://blogs.aspadvice.com/joteke http://teemukeiski.net
> Teemu, > [quoted text clipped - 226 lines] >>>>>>> >>>>>>> thanks IfThenElse - 27 Sep 2007 19:31 GMT Teemu,
You are right. Thank you.
I can not find out how to Ask a validator to Validate. The "isvalid" property is always ture. what function to call to force a specific validator to validate.
Thanks again for all your help I am moving forward.
> In client-side DOM a validator has isvalid property (written literally in > lowercase) [quoted text clipped - 229 lines] >>>>>>>> >>>>>>>> thanks Teemu Keiski - 28 Sep 2007 17:17 GMT There is ValidatorValidate function in ASPNET client-side validation library.
var i; for (i = 0; i < Page_Validators.length; i++) { ValidatorValidate(Page_Validators[i], validationGroup, null); }
 Signature Teemu Keiski AspInsider, ASP.NET MVP http://blogs.aspadvice.com/joteke http://teemukeiski.net
> Teemu, > [quoted text clipped - 242 lines] >>>>>>>>> >>>>>>>>> thanks
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|