How to Customize wForms
This documentation was updated on may 09 2005.
This post is part of the wForms Documentation. wForms is an open-source javascript library that adds commonly needed behaviors to traditional web forms without the need for any programming skill.
For additional help, visit the wForms forum.
wForms was designed from the onset to be easily customizable.
When the wForms extension loads, it instantiates a javascript object called ‘wf’. Public properties and methods of that object can be easily overwritten for customization purpose.
You should not change wForms.js directly, as it would hinder your ability to install updates. Instead, use a short javascript file, linked after wForms.js.
For instance,
<script type="text/javascript" src="js/wforms.js" ></script>
<script type="text/javascript" src="js/customization.js" ></script>
See the sample customization file.
wForms Behaviors Configuration Options
- wf.preserveRadioName [true / false]
- Default: true. The Repeat behavior preserves the name attribute of radio inputs accross repeated elements, effectively expanding the radio group. Set to ‘false’ to make repeated radio inputs independant.
- wf.preventSubmissionOnEnter [true / false]
- Default: false. If set to ‘true’ the form will not be submited when the ‘enter’ key is pressed. ‘True’ is the recommanded setting for multi-page forms, to prevent submission of incomplete forms.
- wf.showAlertOnError [true / false]
- Default: true. The validation routine will run the showAlert function if there’s an error, with the message in wf.arrErrorMsg[8]
- wf.switchScopeRootTag
- Default: “FORM”. If you need the Switch behavior to be able to target elements outside of its form, you may change the switchScopeRootTag value to ‘BODY’.
How to modify error messages and text outputs
See the documentation about wForms localization.
- wf.showAlert
- If you’d like to display the alert message in a different way (popup, insert..) you can overrite the wf.showAlert function.
wf.showAlert = function (nbTotalErrors) {
alert(self.arrErrorMsg[8].replace('%%',nbTotalErrors));
}
How to add a custom form validation routine
- Overwrite the default form validation handler with yours:
wf.functionName_formValidation = "myCustomValidation"; - Implement your custom function:
function myCustomValidation (evt) {
// evt is the onsubmit event.// call the wForms default validation routine
if(wf.formValidation(evt)) {// do your stuff..} else
// will prevent the form from being submitted.
return wf.utilities.XBrowserPreventEventDefault(evt);
}
How to change the CSS Classes used by wForms
Here are the classes defined in wForms. You probably won’t need to ever change them, but if you do, you may do so in the customization.js file.
Please note: if your form has been created using the form builder, you need to apply your changes to your form’s HTML as well.
wf.classNamePrefix_switch = “switch”;
wf.classNamePrefix_offState = “offstate”;
wf.classNamePrefix_onState = “onstate”;
wf.className_repeat = “repeat”;
wf.className_delete = “removeable”;
wf.className_required = “required”;
wf.className_validationError_msg = “errMsg”;
wf.className_validationError_fld = “errFld”;
wf.classNamePrefix_validation = “validate”;
wf.className_duplicateLink = “duplicateLink”;
wf.className_removeLink = “removeLink”;
wf.className_activeFieldHint = “field-hint”;
wf.className_inactiveFieldHint = “field-hint-inactive”;
// id attribute suffixes
wf.idSuffix_fieldHint = “-H”;
wf.idSuffix_fieldLabel = “-L”;
wf.idSuffix_fieldError = “-E”;
wf.idSuffix_repeatCounter = “-RC”;
Update: Comments are now closed for this post, but you can go to the wForms forum if you have any question or comment. Thanks !
June 13th, 2005 at 8:36 pm
Here’s the code to perform a field comparison (password confirmation):
// Custom validation with Field comparison function doPostBack(e) { if(!e) e = window.event; if(wf.formValidation(e)) { // call the default error management. var f = wf.utilities.getSrcElement(e); // reference to the form if(f['wf_Password'].value != "" && f['wf_Password'].value == f['wf_Confirmpassword'].value) { var strLogin = encodeURIComponent(f['wf_Username'].value); var strPassw = encodeURIComponent(f['wf_Password'].value); // ...validation ok... } else if(f['wf_Password'].value != "") { wf.showError(f['wf_Password'],"The passwords don't match"); return wf.utilities.XBrowserPreventEventDefault(e); } } }June 24th, 2005 at 12:08 am
I’m having trouble with “How to add a custom form validation routine”. I’m using the supplied example (”myCustomValidation”), and what I’m trying to do is prevent the form itself from submitting if it passes validation - I’m passing the form values to an AJAX function instead. However, I can’t get the custom validation to stop processing the submission.
function myCustomValidation (evt) {
if(wf.formValidation(evt)) {
alert(’stop!’);
return false;
} else
// will prevent the form from being submitted.
return wf.utilities.XBrowserPreventEventDefault(evt);
}
What am I missing?
June 24th, 2005 at 12:49 am
Bryan,
‘ return wf.utilities.XBrowserPreventEventDefault(evt); ‘ does exactly what you need.
Each browser has a different way to prevent the default behavior in their event model. Returning false is not enough, you need to either run the event’s preventDefault() method or set its returnvalue property to false. The XBrowserPreventEventDefault function does that for you.
June 24th, 2005 at 5:12 am
I stumbled across the solution about 20 minutes after posting my question. Thanks for the help, though. Love your work!
July 13th, 2005 at 8:24 am
First of all great site, great tools, great resources. I like some of the behaviors too, like hint, esp. I know this is probably off topic, but I’ve poked around here and don’t see exactly where to go with this. As far as hosting a form, I know you don’t host and we d-load & then run it on our site. You can see where I’m headed. If I then host the form on my site, the submit goes to formassembly.com. You supply so much help, and support files, etc. but there’s nothing about how to implement hosting the form. I know, I know, I’m supposed to know this already, but I’m afraid I don’t. If you could kindly point me in the right direction for resources, I’d appreciate it. (and I’ll quietly go there without too many other dumb questions….)
One other customization I don’t see is a confirmation page. Right now, the confirmation page is presented on formassembly domain and it’s boilerplate. What options do we have with the existing code?
Sorry, if this is newbie stuff.
-lee
July 13th, 2005 at 10:45 am
Lee…
The first thing to do is to change the action attribute of the form tag.
<form action=”http://www.formassembly.com/test-srvc.php” … >
Replace the http://etc…. with the address of the page that will process the form (your ‘confirmation’ page).
Now it’s up to you to build that page, and you will need some basic programming skills. Figure out with your hosting provider what server-side language is available (usually PHP). Then scout the web for some tutorials. A google search on ‘php form processing’ should do the trick.
July 19th, 2005 at 12:36 am
thanks cedsav…have a lil’ php experience, but never applied it to an app…so this’ll be a first!
August 8th, 2005 at 7:39 am
Cedric, I love what you’ve put together here. I’m just now starting to play with it as we are looking for a validation to use in our application. Two questions for you. Have you considered parameterizing the placement of the error messages? I’d like to place the message before the field in question, instead of after it. Second question is have you considered if there would be a way to make the validation rules an array that could be added to easily?
For example, I’d like to add a “validate-money” validation, which I can do (I think) through your customization approach, but it requires that I replicate a lot of your logic for looping through elements and such. It seems like the array would have to hold the validation class name, the function to be called (which would have to accept the field to be validated and return a boolean), and the message to be shown when validation fails (or the index in the existing message array).
Anyway, let me know if you think this might be possible.
Thanks,
Scott
August 9th, 2005 at 9:52 am
Scott,
Assuming the error occurs on field with the id ‘fieldA’, here’s the logic that determines where the error message appears.
1. if wForms finds a tag with the id ‘fieldA-E’ anywhere in the document, the message is inserted inside that element (error message placeholder).
2. if wForms finds a tag with the id ‘fieldA-L’ anywhere in the document, the message is inserted after that element (typically a field label)
3. If none of the above applies, the message is inserted after the field in error.
The first option gives you the most flexibility but you have to add the markup for the placeholders yourself (ex. <div id=’fieldA-E’ ></div>)
Regarding your second question, your approach to extend the validation routine seems sound and much more flexible than the one currently implemented in wForms. I’ll keep it in mind when I’ll start refactoring the script. Until then, unfortunately, you’ll have to replicate the formValidation function and add new cases in the switch around line 587.
August 17th, 2005 at 3:10 am
Your site rocks big time.
Thanks for writing back to me, i got your mail and it all works great!
I’m having a hard time trying to make the form fields go horizontal instead of vertical WITH repeat function, for some reason. I see how you did it on the repeat example page by using TR and TH tags, but for some reason, i can’t get the repeat link to appear when i put it all in the tags.
Help!
August 23rd, 2005 at 6:42 pm
Hi,
How can I use the code you posted in your first post? I pasted it in a new js file I linked from the page the form is in, but nothing happens.
Thanks,
Alex
August 30th, 2005 at 8:20 pm
I created a form that has a repeatable frameset and within it there is a select with languages and some text fields to write some texts.
What I need is that the value selected in the select don’t repeat within the repeats. Any instance of the frameset must have a different language selected.
How can I implement this validation at the client-side?
The form is http://www.formassembly.com/form-view.php?formID=3299
September 1st, 2005 at 1:38 am
HoloCocos…
You would need to get the value from each repeated select, build an array and make sure you have only unique values.
Here’s the skeleton for the custom javascript validation routines :
function myCustomValidation (evt) {
if(wf.formValidation(evt)) {
// get the repeated row counter value
// wf_-qiexnf is the id for your fieldset with the repeat class (randomly generated here)
var rowcount = document.getElementById(’wf_-qiexnf-RC’).value;
for(var i=1; i<rowcount ; i++)
if(i>1) rowSuffix = “-” + i;
else rowSuffix = “”;
// get select value (maybe use options/selectedIndex here)
var lang = document.getElementById(’wf_Lngua’+rowSuffix).value
// now you can just add ‘lang’ to an array and check if it’s unique. If not use:
// return wf.utilities.XBrowserPreventEventDefault(evt);
}
} else
// will prevent the form from being submitted.
return wf.utilities.XBrowserPreventEventDefault(evt);
}
September 7th, 2005 at 9:10 pm
Hi,
I have a form with a formassembly text field on it and a submit button. The validation works, and the form submits fine. I overrode the default validation so that I could set a hidden field in the form to a value to aid in logic on the submit, as the page submits to itself.
I also display a series of text fields with a links to control update and delete on the values displayed. I would to validate these fields, and they are inside the same form as the above text field. I added the class=”alphanumeric required”, and have my links do a “javascript:update($id);” for example. Those functions also set a hidden field value or two, followed by document.myform.submit().
The submit() is not caught by the custom override function I created. What is the difference between the form submit on the submit button and the document.submit()? I would like to ensure for example that if someone updates a value, they don’t update a text field that is blank.
Any tips on using a form with more than just one submit button much appreciated.
Thanks!!
September 7th, 2005 at 9:45 pm
HunkyBill.. In javascript, a call to form.submit() does not raise the onSubmit event, and therefore the validation routine is not triggered. This ‘problem’ is not related to wForms, it is a language feature.
You need to call the validation routine yourself in the update() function, before the form.submit() call.
if(customValidation(evt)) myform.submit()
wForms validation function takes an event as a parameter. You cannot raise the onsubmit event, but it will take the ‘onclick’ event raised when you click on the link (as long as the link is inside the form).
Alternatively, wForms.js could be slightly modified to accept the form element as a second optional parameter.
Let me know if you need more assistance.
September 8th, 2005 at 5:46 am
Hi cedsav,
Thanks for the input. Assuming my link is constructed like this update, I assume what you mean by the above that I need to generate an onclick? I rewrite this as update which sends an event to the customValidation() function, when my update(evt,id) function sends along the evt value. It is an event object as expected.
customValidation() receives this event object… but all I get is srcE has no tagname error in wsForms at line 515… it seems to be looking for the tag, which is in fact surrounding this link.
I am a little unclear on how to construct the link. Is there some pseudo code you could present that illustrates using elements other than the submit button (or more precisely, along WITH it)… THANKS!! The more I use your library, the more I see the uses I can put it to. Great stuff!
September 8th, 2005 at 6:11 am
I tried this too $update and it still refuses to process the event. What am I missing here? Thanks… sorry for the mess above…
September 8th, 2005 at 6:14 am
Damn… making a simple link is hard with this I mean onclick=”javascript:update(event,$id); return false;” with update getting the event as an onclick as expected. Sending that to customValidation(evt) returns as an unknown tag….
September 8th, 2005 at 7:51 am
Hi,
Okay, I figured it out… the DOM walk failed when the tag was not found. Careful placement of the is in order I guess. Nesting amongst various tags seemed to break the DOM… I decided to make two forms now. One for the form assembly creation, taking care of the add fields, with a submit button, and a separate form for my text fields that are dynamically generated with links for things like update and delete. It works fine… now, to just fix up the styles… Sorry for the obtuse questions…
September 15th, 2005 at 7:01 pm
Not sure which entry to post this question to, but this seemed the most appropriate. Anyways…
I’m building an app that uses wForms validation and repeat methods; I also use ‘Prototype’ for Ajax calls. The problem I’ve run into is that when I use ‘Ajax.Updater’ to fetch a block of code — containing a wForms repeatable element — from the server and insert it into the DOM, the repeat and switch methods don’t function. I’m sure it’s because I’ve modified the DOM - those objects weren’t there when the ‘new wFORMS();’ was created.
Just as an example, Ben Nolan’s “Behaviour” library (http://bennolan.com/behaviour/) includes a function to re-apply (”Behaviour.apply()”) custom behaviours after the DOM has been modified (objects created or removed). Is there a similar function hidden away in wForms? Or any other suggestions on how to accomplish this?
September 15th, 2005 at 9:43 pm
Once again, I answered my own question:
wf.onLoadHandler();
…after completion of the function that inserts the returned code into the DOM.
September 26th, 2005 at 9:51 pm
Hi,
How can i modify tag that the error message is contained in? Right now it puts a div i believe. I read
here where you can put a place holder and
it will put the error message but i was wondering how to just change it in the js.
thanks,
Chuck
September 27th, 2005 at 3:49 am
Chuck, in wforms.js search for the string
fe = document.createElement(”div”);
(in the showError function)
replace ‘div’ by the tag you want.
September 27th, 2005 at 5:39 am
Thanks Cédric,
I did do that. I was wondering if i could do it in a custom file. If not, in a future release, can this be made a variable that can be overwritten in
a custom file?
September 29th, 2005 at 10:37 pm
Chuck, you can copy the entire showError function in your customization file and make the change there.
wf.showError = function() {
// … function body (about 25 lines) …
}
but yes, a simple parameter would be more pratical. I’ll keep it in mind for the next update.
October 7th, 2005 at 5:39 pm
Is it possible to validate an element at a time with an onblur event, rather than validating the whole form all at once?
October 8th, 2005 at 3:29 am
Andy, not as is, but if you’re ready to dive into the javascript, here’s a head start:
Around line 515 in wForms.js, remove the while loop:
while (srcE && srcE.tagName.toUpperCase() != ‘FORM’) {
srcE = srcE.parentNode;
}
This should prevent the formValidation routine to process the entire form.
Now, you could try something like this and see if it works:
< input type=’text’ class=’required validate-alpha’ onblur=’wf.formValidation’ />
Don’t have time to test right now, so let me know how it goes.
October 10th, 2005 at 6:41 pm
That very almost worked… All that required was adding a behaviour for each of the elements in the wFORMS.prototype.addBehaviors. I added this at around line 780:
if (x[i].tagName.toUpperCase()!=’FORM’) {
wu.XBrowserAddHandler(x[i],’blur’,this.formValidation);
}
and commented out the while loop as you suggested, and it worked like a charm!
I suppose it might be nice to have a config variable control whether it’s inline validation or validating the form all in one go, but that can come later.
Many thanks for your help and the fantastic library!
October 14th, 2005 at 5:14 am
I created a form with a repeatable div within a fieldset. The div contains text input fields with default values.
When I repeat a row, the default values don’t carry over from the previous row. Can I customize the script
so default values for some fields are included on a new row? I would also like to know if it is possible to set
the option on a select field back to the first option for a repeated row. Thanks for your help.
October 14th, 2005 at 9:42 am
Jason,
in wForms.js (v0.99.23) the line 375 is the code that clears the text inputs:
var value='’;
If you wanted to preserve the existing value you coud use instead:
var value = srcNode.attributes[i].nodeValue;
..but then, even users inputs would be repeated, which is not what you want.
Depending of the situation, you could hard-code the default value, or store it somewhere else and retrieve it using javascript.
It’s not something that wForms do at this point, but if you come up with something let me know.
For your second question, try replacing line 377 by this (not tested yet):
if(srcNode.attributes[i].nodeName.toLowerCase() == “selected” &&
srcNode.tagName.toUpperCase()==’SELECT’)
var value='’;
else
var value = srcNode.attributes[i].nodeValue;
October 14th, 2005 at 11:05 pm
Hi Cédric,
Thanks for the code. This first customization works fine. This is not exactly what I wanted, but I’m happy with it. I tested the second customization.
The behavior was the same, so I think this code may need to be modified. By the way, I modified the code on lines 855 and 913 as follows:
var actionNode = document.createElement(”button”);
This seems to work nicely. It uses a botton instead of a link for the repeat behavior. Could this change cause any problems? I’m not that familiar
with javascript so I’m hoping it doesn’t break anything.
October 14th, 2005 at 11:23 pm
I’m having second thoughts about repeating the user inputs. How can I hard-code the default value for
some input fields? Are these changes that I can include in the customization script instead of updating
the wforms script directly? Thanks for your help!
October 15th, 2005 at 1:39 am
Jason, I think createElement(”button”) is not well supported accross browser. See: https://dav.globalmentor.com/public/ie/iebuttonbug.html
You should try:
var actionNode = document.createElement(”input”);
actionNode.type = ‘button’;
and no, you have to do these changes directly in wForms.js. It wouldn’t be practical to copy the entire ‘replicateTree’ function in the customization script.
I’ll get back to you later for the other issues.
November 3rd, 2005 at 1:40 am
Hi, I was trying to reassign the text of the link for the repeater in my own customization file like this:
this.arrMsg[0] = “add another set”; // repeat link
But when I do I get an error “this.arrMsg is null or not an object”. I thought it would just append the wforms.js, reassigning only that value. Anyway, I add the whole array to my script instead, like this:
this.arrMsg = new Array();
this.arrMsg[0] = “add another set”; // repeat link
this.arrMsg[1] = “repeats this field group” // title attribute on the repeat link
this.arrMsg[2] = “remove”; // remove link
this.arrMsg[3] = “removes this field group.” // title attribute on the remove link
this.arrMsg[4] = “next page”;
this.arrMsg[5] = “previous page”;
While I don’t get any errors this way, it is not changing the text. I assume because my second .js file does not have access to the object - this. I have some basic understanding of javascript but not of the DOM. Can someone help me out on this? Otherwise I’m just going to have to edit the wforms.js, which is probably fine for my purposes, but I’m really trying to use best practices!
November 3rd, 2005 at 1:47 am
Mahalie.
You’re close.. ‘this’ cannot be used outside of the wForms object definition. You need to refer to the object by its instance name, which is ‘wf’.
Thus:
wf.arrMsg[0] = “add another set”;
November 3rd, 2005 at 3:48 am
Sweet - that worked! Just to warn others, at first I was still getting a weird error (in IE). I opened the page in Firefox (love their Javascript console - under Tools) and realized I had fancy quotes from pasting from this page into the .js file…so for anyone copying code examples for this website, make sure your quotes are plain old straight quotes!
November 19th, 2005 at 11:47 am
Is there a way to temporarily change and disable the submit button? I would like to have the button read “processing” and be disabled to prevent multiple submissions but go back to default if errors are detected.
Thanks!
November 22nd, 2005 at 1:30 am
How can I use the library? What I need to do a form.
King regards
November 22nd, 2005 at 10:38 pm
Well I mean how I can use the library? I see that this library allow to create forms dinamically, but I not found any documentation for do this. For example I use scripts like scriptacolus I they put a simple way to do things with library. For example:
new Effect.SlideUp(element_id);
so If I need to build elements like INPUT, TEXTAREA, BUTTON is possible to do with wforms.js library.???
King regards
November 22nd, 2005 at 11:35 pm
ReynierPM, you can’t build forms with the wForms library (but you could use the form builder for that).
wForms’ purpose is to add functionalities to existing web forms (like input validation, conditional sections, etc..).
November 27th, 2005 at 11:30 pm
Tuck, that’s a good suggestion. I’ll add it in the next release of wForms (sometimes mid-december)
December 17th, 2005 at 1:06 am
Hey *GREAT* software!!!
Question: Any simple way to customize this so that it could throw up a warning?
For instance, I have Edit / Delete buttons in my form…if I click Delete, I’d love to be warned that THIS IS DESTRUCTIVE AND CANNOT BE UNDONE (either through a popup — or alternatively another press on the Delete Button along with some stylized CSS).
Sadly, Javascript just ain’t my thing (I’m a server side guy…I wish I knew more of the ins and outs of modern js).
Difficult? If I had some pointers, it might be enough to push me to where I want to go with this.
But still killer software! Thanks for putting it out there!!!
December 18th, 2005 at 6:57 am
I’m having layout problems when I try to use the Repeat behavior in a vertically-tiled form. I’m having a hard time making sure the dynamically-inserted “Add a row” or “Remove” buttons don’t mess up the overall appearance… is there a way to insert a placeholder for the button in each .Repeat and .Removeable row, so that there’s no guesswork required?
December 19th, 2005 at 9:25 am
clifyt, create a customization file and add the following in it:
wf.removeFieldGroup = function(e) {
if(window.confirm(’your message here’)) {
var srcE = wu.getSrcElement(e);
var delNode = srcE.parentNode;
while (delNode && (’ ‘+delNode.className+’ ‘).indexOf(’ ‘+self.className_delete+’ ‘) == -1) {
delNode = delNode.parentNode;
}
delNode.parentNode.removeChild(delNode);
}
return wu.XBrowserPreventEventDefault(e);
}
December 19th, 2005 at 9:28 am
Ride-My-Rocket!
Yes, though I’m not sure it has been fully tested yet.
if your repeated element as the id ’someid’, you can create a placeholder for the repeat/remove links by giving it the id
’someid-wfDL’ (append the ‘-wfDL’ suffix).
Let me know if you have any trouble with this.
February 1st, 2006 at 2:50 am
cedsav –
Thanks for the Help! I was looking through this site again and realized I never thanked you for the response!
And thanks for making this software available to the public