Let me start by saying this: Niceforms isn't for everyone! It is only intended for web professionals as a method to spice up certain form elements. While the script tries to accommodate a wide range of user scenarios, due to browser inconsistencies and various other limitations, full scale testing is absolutely recommended for determining whether Niceforms is a good fit for a specific situation. Improper implementation can cause major usability issues. That being said, I will not address simple questions like "How do I use it on my page?". If you can't figure that out you probably shouldn't be using the script anyway. Sorry for being blunt.
Using Niceforms
Niceforms is magically applied to all forms that have the class “niceform”. You can have other classes in there as well but one of them has to be “niceform” in order for the script to work. One of the important aspects of the script is that it requires a correctly coded form, including properly declared labels and values. There’s not much room for error and, if anything, it will force you to code your forms correctly.
Browser Compatibility
Niceforms is fully compatible with most modern browsers: IE7+, Firefox2+, Safari3+, Opera9+, Chrome0.3+, Mozilla1.5+, Camino1.6+.
Please note that it is not compatible with IE6 (you can read why further down the page).
Concept Overview
Niceforms uses the javascript object model to extend form elements by adding a suite of custom attributes and functions to each of them. These custom elements usually contain the new graphical appearance, while the added functions handle things like the focus effects, data handling, as well as the loading and unloading of the script. Apart from addressing unique characteristics of each individual type of form elements, all element extending functions share a similar structure.
Let's look at the inputText(el) function. It's the function that extends regular text-type input fields. The first 9 lines create and append new graphical elements to the original input field:
el.oldClassName = el.className;
el.left = document.createElement('img');
el.left.src = imagesPath + "0.png";
el.left.className = "NFTextLeft";
el.right = document.createElement('img');
el.right.src = imagesPath + "0.png";
el.right.className = "NFTextRight";
el.dummy = document.createElement('div');
el.dummy.className = "NFTextCenter";
These new graphical elements represent the 2 ends, left and right, and also the middle section of the field. The naming conventions are pretty much self-explanatory. Form elements other than this text-type input may use different new graphic elements, but the idea behind this section remains the same.
The following 2 subfunctions, onfocus() and onblur() handle the background change that occurs when the field has been focused on, basically by changing its background:
el.onfocus = function() {
this.dummy.className = "NFTextCenter NFh";
this.left.className = "NFTextLeft NFh";
this.right.className = "NFTextRight NFh";
}
el.onblur = function() {
this.dummy.className = "NFTextCenter";
this.left.className = "NFTextLeft";
this.right.className = "NFTextRight";
}
Attention: These will overwrite any other custom onfocus and/or onblur events that you may have set up for the text-type input fields. To solve this issue you will have to integrate those custom functions within the ones from Niceforms. The same applies to all other form elements that require additional event handling functions (more about this in the next section).
Last 2 subfunctions, init() and unload(), represent the start and stop actions:
el.init = function() {
this.parentNode.insertBefore(this.left, this);
this.parentNode.insertBefore(this.right, this.nextSibling);
this.dummy.appendChild(this);
this.right.parentNode.insertBefore(this.dummy, this.right);
this.className = "NFText";
}
el.unload = function() {
this.parentNode.parentNode.appendChild(this);
this.parentNode.removeChild(this.left);
this.parentNode.removeChild(this.right);
this.parentNode.removeChild(this.dummy);
this.className = this.oldClassName;
}
These are common to all form elements. init() basically adds the new elements to the page, thus making Niceforms replace the existing form, while unload() removes these elements, reverting to the original form.
Custom Event Handling
As explained in the previous section, Niceforms overwrites certain events in order to function correctly. To make the script work with any additional event handling functions that you may have set up, you will need to add those to their respective counterparts within Niceforms.
For instance, let's say you want to perform some type of on-the-fly validation of text-type input fields. In order to do this, you would be using the onblur event but that is one of the events overwritten by Niceforms. To integrate the two, first you would need to locate the existing event function within Niceforms. This would be el.onblur() within the inputText() function. You can simply add your extra code in there and everything should be fine.
el.onblur = function() {
this.dummy.className = "NFTextCenter";
this.left.className = "NFTextLeft";
this.right.className = "NFTextRight";
//add any additional custom code here
}
The same method applies to all the other events on different form elements. Do note that various elements overwrite various events. A full list is available below:
| Element | Overwritten Event |
|---|---|
| input type="text" | onblur(), onfocus() |
| input type="radio" | onclick(), onblur(), onfocus() |
| input type="checkbox" | onclick(), onblur(), onfocus() |
| input type="submit" | onmouseout(), onmouseover() |
| input type="file" | onblur(), onfocus() |
| textarea | onblur(), onfocus() |
| select | onblur(), onfocus() |
| button | onmouseout(), onmouseover() |
Implementing a Jump Menu
By default, Niceforms overrides the onchange attributes of any drop down options, thus making a classic jump menu unusable. However, there is a quick workaround.
Add a custom class name to that particular select element (i.e. class="NFOnChange") so that the script can separate it from all the other regular select elements. Within the option(el, no) function, add the following code:
el.lnk._onclick = el.onclick || function () {
if(this.ref.oldClassName == "NFOnChange") {
//insert your code here
}};
Instead of the commented line simply insert your own custom javascript that should be executed when that particular option is selected.
Window Events
Niceforms also makes use of the window.onload() and window.onresize() events. These, however, will not overwrite any other existing similar events and will pass them on accordingly if they exist.
After Implementation
Since the (X)HTML code for your form isn't altered in any way by Niceforms, everything should work just like in the original. That being said, it is entirely up to you to handle what the form does with the data and how it passes it on to a server-side script. One of the questions I'm getting fairly often is why the "vars.php" file from the demo is not included in the distribution. All that script does is return the values you've entered for testing purposes. You should replace it with whatever it is you want your form to do. And again, if you don't know how an (X)HTML form should be used and implemented properly, you're probably just going to make things worse by using Niceforms.
Why Isn't IE6 Supported
I have considered and reconsidered this a number of times. While it is possible to achieve full IE6 compatibility, I chose not to for a number of reasons.
First of all, and most importantly, even if it were supported, due to its archaic javascript execution, Niceforms would behave very slowly. That would mean every hover effect would cause flickers, initialization would take so long that you would actually see it happening, and all that would result in a very poor overall user experience. Combined with any additional scripts you may be using on that page, it may cause it to run slowly, to the brink of crashing, and that is simply not acceptable.
Furthermore, adding full IE6 compatibility would almost double the size of Niceforms, thus negating one of its main qualities: small size. As a side note, this is also why Niceforms doesn't make use of any existing javascript libraries out there, such as jQuery or Prototype.
Lastly, user percentages for IE6 are constantly declining. Hopefully, in a couple of years we will be able to forget about it completely. For those still using it, Niceforms will simply not load, reverting back to the original CSS-styled form. No harm, no foul.
Themes
As more themes are being developed, a ready-sliced PSD template for the default Niceforms theme is already included with the latest distribution. You can use it as a starting point and create your own theme. After modifying it, if you've kept the original element sizes intact, just hit Save for Web, choose "Images Only", "Default Settings" and "All Slices" in the Save dialog and it will automatically create all the necessary images with the correct names. If, however, you do modify the size of various elements, you'll have to change the size of those slices as well.
I am currently working on a more detailed guide on how to develop custom themes and hopefully it will be available by the end of the year.
Acknowledgements
A lot of work has been put into creating the Niceforms script and all this would not have been possible without the support of certain people. A huge thanks goes out to Peter-Paul Koch and his awesome javascript resources. I’ve taken quite a few examples from his coding in creating Niceforms.
Another big thanks goes to all those that helped me test the script and provided excellent feedback on the initial preview. There are too many to mention them all here but needless to say, I probably couldn’t have done it without them.
