Introduction

uicForm3 is a jQuery plugin, that helps you to create html forms that provide a better user experience while reducing your programming effort. The plugin’s key feature are:

  • Populating javascript data to the form by providing flat or nested objects.
  • Retrieving data from the form and creating flat or nested objects according to the form element’s naming. For the mapping of form element’s names and the object’s properties refer to the Documentation.
  • Providing modifiedStateChange events and validStateChange events.

The creation of this plugin seemed to be necessary since except some new html5 form elements there is nearly no progress in the native implementation of forms for the last twenty years and it is a boring and sometimes complicated job to implement some up-to-date capabilities by hand every time you want to create a good form.

In this article I want to talk a little bit about my motivation to create this plugin and the basic concept behind it rather than showing examples or details of the plugin’s API. Please refer to “Documentation” and “Examples” for these topics.

So the basic thing is:

Creating forms sucks!

And the basic question is:

What makes creating forms suck?

To get aware of this it is a good idea to identify the most wanted requirements that a form should be able to handle.

I think these requirements are:

  • Populating data into an html form with javascript.
  • Getting data out of the html form into javascript.
  • Submitting forms with no page reload.
  • Keeping track of modifications / modification-states of the form and it’s form elements.
  • Keeping track of valid-states of the form and it’s form elements.

The first three requirements are dealing with an html form data to javascript object data relation while the other two requirements have something to do with notifications that occur when states within the form are changing. So we can reduce the five requirements to two problem categories:

  • Mapping html form data to javascript object data.
  • Adding notifications to get informed whenever something interesting happens with the form.

So let us walk through these two issues:

1. Mapping html form data to javascript object data

When you deal with form data and you want to do this with javascript you probably want to assign the form element’s values to javascript variables or properties and vica versa. This seems easy at first sight but turns out to be more complicated when you really try to implement it. This is because there is no one-to-one relationship between form elements and javascript variables or properties.

For example if you have a textfield with name “firstname” you could easily connect this field (to be more precise: it’s value) to a javascript variable or property named “firstname” (it could be an arbitrary name but it is very reasonable to use corresponding names for html form elements and javascript properties) with only one line of code:

var firstname = document.getElementById("firstname").value;

But if you have two or more radio buttons with the same name (for example “title” to let the user chose between “Mr” and “Ms”) you need to connect both of them to a single corresponding javascript property that is able to hold this single value. To do so you need a case differentiation to see which of both radio button currently is checked and then use it’s value.

The same goes for checkboxes with the difference that they can generate multiple values. So if you have a couple of related checkboxes (with the same name) that belong to one single property you have to iterate through these checkboxes and retrieve all the values of those checkboxes that are currently checked to get the value of these checkboxes or the corresponding javascript property. in addition you should ensure that the related property is able to hold multiple values. That is not a big deal in javascript as this language is not a typed one, but it will be important if you want to populate the property’s value back to the checkboxes, because to do this you definitely need to know the data type to assign it correctly.

When it comes to select boxes things are not getting easier. It is a single form element just like a textbox (input type=”text”) is, but it can be designed to hold only one value (than it appears as a drop down menu) or to hold multiple values (as a select box with attribute multiple=“multiple”). To make it a little more complicated it’s not the select box itself that holds the values but the option elements within the select box (that are not form elements). So you have to iterate through these option elements to gather all values that are currently selected and get the value that is related to the corresponding javascript property.

So having all this in mind we see it is not a one-to-one relationship between form elements and javascript properties but it is a many-to-one relationship that we can write down as follows:

Form elements with the same value within their name attributes belong together and are related to one single javascript property.

Although things are that easy, this sentence is not sufficient to describe the whole problem. As we have seen we also had to differentiate between single values and multiple values or in other words between “primitive” values (strings, numbers, booleans) and “complex” values. Every single value is one of the primitive types and every set of multiple values consisting of one or more primitive values is a complex type. In our case it is always an array that is assigned to a single javascript property.

So in addition to the mapping of form elements to javascript properties that turned out to be quiet simple we need to classify the corresponding value as “primitive” or “complex” value.

As a first rule of thumb it can be said that whenever you have more than one form element that belong to a single property than the value is a complex one. But this is much too simple and is not true for a set of radio buttons that consists of multiple form elements but generates only one primitive value. It is also not true for select boxes with attribute multiple=”multiple” as this is only one form element that generates a complex value. So you cannot identify primitive or complex values just by counting the number of corresponding form elements. You definitely have to take some more properties of the involved form elements into account.

So the mapping of form elements to javascript properties can be considered as easy but the classification of the corresponding value as primitive value or complex value is some kind of complicated. In addition javascript as well as most frameworks do not help you too much assigning values to form elements or retrieving values from these elements. Or in better words: they help you assigning and retrieving values to and from form elements but that is not what you want!

You want to assign and retrieve values to and from properties!

To make this work in both directions, uicForm3 maps form elements to javascript properties (by the value of the name attributes) and classifies the corresponding values as “primitive” value or “complex” value by analyzing the number of form elements belonging to one property and checking their properties.

As a result you can easily assign and retrieve data to and from the whole form or to and from a single property by using the methods exposed by uicForm3. This works fine for plain javascript objects as well as for javascript objects that consists of a nested object structure.

When you are dealing with nested object structures the naming syntax convention for the form element’s names follows the concept of mapping form element values to variables or object’s properties in php. This is a very common backend for websites and the concept is very reasonable and intuitive. You will find more information on this topic in the Documentation and the Examples.

2. Adding notifications to get informed whenever something interesting happens with the form

To give the user a good experience while dealing with your form you might want to give him information about the state of the form. For example it might be a good idea to let the user know if the form contains only saved data or if some data is unsaved. This can especially be very helpful when the user edits a data set rather than creating a new one because then all fields might contain some data and it is not obvious which field he already has touched. Furthermore you probably want the user to be informed if the data he sent to the server is valid or not. To do so the form must process the server-response, identify the fields with rejected values and generate a visual output.

So what you want is notification from the form. As we all know html form elements do fire some events on certain actions. There is for example a “change” event that fires when the content of a form field changes. That works fine but it turns out that on text field or textarea it only fires when the element loses focus after having been edited. That is not very intuitive. I would say a change should occur immediately when the user changes the content of such a field what means it should fire on “keydown”. Ok, this is not the whole truth as there are keydowns that do not change the content of a text field as “shift”, “command”, “control” etc. In addition technically the content of a form element is still unchanged at the time of the keydown but changes immediately after that event is fired. For this reason modern browsers have an “input” event implemented that does all we expect from such kind of event. For the not so modern browsers we can work around with a “keyup” event that does not fire as immediately as the “keydown” event but allows to detect if something happened with the content of the form element’s value.

But what if you want to inform the user of unsaved values within the form? Do you really want to compare the initial value of a field with it’s current value each time this value changes as there is no “modifiedStateChange” event in plain javascript? I would say no! And don’t you actually want to compare properties rather then form element values? I would say yes! So because plain javascript and most of the common frameworks do not deal with form properties and don’t provide appropriate events it again is time for uicForm3. So let this plugin do all the dirty work for you and serve you with some appropriate events (or callbacks). That is exactly what it does: it fires events like “onPropertyValChange”, “onPropertyModifiedStateChange”, “onPropertyValidStateChange” and many more, but it does not change your DOM or handles these events in any way. As this handling is very specific to the needs of your form and your ideas, I left it up to you and your concrete implementation to handle these event and use them to create the very best form for the users. uicForm3 extends your capabilities while not touch the rest of your code or interfere with it.

So, no matter if you only use a small functionality of uicForm3 or if you make heavy use of if, this plugIn will do nothing more then extending your form with up-to-date capabilities.

This approach ensures that uicForm3 is compatible with all needs and all kind of forms no matter how complex or sophisticated your html structure is and it allows you to realize any behavior of your form you can imagine even if it is not covered by uicForm3 because this plugin does not prevent you to extend your native form in any way you want.

Please have a look at the examples and read the API documentation if you like to use this plugin. I am sure that it can do even more for you as you think about it after having read this article. I would love to get your feedback and see some forms that you created using uicForm3.

Ole Manshardt

One thought on “Introduction”

  1. Stunning content material. Just what I ended up being looking for!
    All the best,
    ps
    Take a peek at our new release with lepsoft,com

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>