This page has been archived. For the latest news on FormAssembly, go to: http://www3.formassembly.com/blog

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

  1. Overwrite the default form validation handler with yours:
    wf.functionName_formValidation = "myCustomValidation";
  2. 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 !

46 Responses to “How to Customize wForms”

  1. cedsav Says:

    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);
    		}
    	}
    }
    
  2. Bryan Buchs Says:

    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?

  3. cedsav Says:

    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.

  4. Bryan Buchs Says:

    I stumbled across the solution about 20 minutes after posting my question. Thanks for the help, though. Love your work!

  5. Lee Says:

    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

  6. cedsav Says:

    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.

  7. lee Says:

    thanks cedsav…have a lil’ php experience, but never applied it to an app…so this’ll be a first!

  8. Scott Mitchell Says:

    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

  9. cedsav Says:

    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.

  10. Ron Fish Says:

    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!

  11. void Says:

    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

  12. HoloCoCos Says:

    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

  13. cedsav Says:

    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);
    }

  14. HunkyBill Says:

    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!!

  15. cedsav Says:

    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.

  16. Hunkybill Says:

    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!

  17. Hunkybill Says:

    I tried this too $update and it still refuses to process the event. What am I missing here? Thanks… sorry for the mess above…

  18. Hunkybill Says:

    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….

  19. Hunkybill Says:

    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…

  20. Bryan Buchs Says:

    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?

  21. Bryan Buchs Says:

    Once again, I answered my own question:

    wf.onLoadHandler();

    …after completion of the function that inserts the returned code into the DOM.

  22. chuck Says:

    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

  23. cedsav Says:

    Chuck, in wforms.js search for the string
    fe = document.createElement(”div”);

    (in the showError function)

    replace ‘div’ by the tag you want.

  24. chuck Says:

    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?

  25. cedsav Says:

    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.

  26. Andy Says:

    Is it possible to validate an element at a time with an onblur event, rather than validating the whole form all at once?

  27. cedsav Says:

    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.

  28. Andy Says:

    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!

  29. Jason Says:

    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.

  30. cedsav Says:

    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;

  31. Jason Says:

    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.

  32. Jason Says:

    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!

  33. cedsav Says:

    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.

  34. mahalie Says:

    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!

  35. cedsav Says:

    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”;

  36. mahalie Says:

    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!

  37. Tuck Says:

    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!

  38. ReynierPM Says:

    How can I use the library? What I need to do a form.
    King regards

  39. ReynierPM Says:

    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

  40. cedsav Says:

    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..).

  41. cedsav Says:

    Tuck, that’s a good suggestion. I’ll add it in the next release of wForms (sometimes mid-december)

  42. clifyt Says:

    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!!!

  43. Ride-My-Rocket! Says:

    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?

  44. cedsav Says:

    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);
    }

  45. cedsav Says:

    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.

  46. Clifyt Says:

    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 :)