Saturday, December 29, 2007

How to Use the Same Server-Side Code to Validate Form Data With or Without AJAX Using jQuery

In any web application, if the user submits information to be stored in a database using a form, you always want to validate that information before it's stored in the database. The majority of users have JavaScript enabled in their web browser, allowing you to use JavaScript functions to validate the data on the client-side before the submission is allowed to proceed. However, there are those rare individuals who have JavaScript turned off, so a conscientious developer will also validate the submitted data on the server side as well as a backup.

The problem with this is that you end up having to maintain two sets of validation functions, which means twice the work if you have to make a change to the submission form or the validation rules themselves. In addition, if you're not experienced with JavaScript, you may find it harder to write the JavaScript validation code than similar code in your server-side programming language of choice.

In an earlier blog post, I wrote about how the latest version of ColdFusion, ColdFusion 8, provides a new tag called <cfajaxproxy> that allows you to make JavaScript calls to functions contained in ColdFusion Component (CFC) files on the server, enabling you to write your validation code within CFC functions and call them for either client-side or server-side validation.

But what if you're not running ColdFusion 8 yet, or you're using another web programming language (like PHP)? Here's a technique I came up with using the jQuery JavaScript library and the jQuery Form plugin that lets you write your validation and database-update code on the server-side in such a way that you can either call it via AJAX if JavaScript is enabled or run it server-side if JavaScript isn't available.

First, here's the code for the HTML form:

It's a very simple form, with only two text inputs (firstName and lastName). The JavaScript files and the CSS stylesheet used with the form are included in the <head> block. At the beginning of the form is a hidden text field called "submitType." Below the form are two <div> blocks that both have the class "hideElement."

Here's the code for the submitDemo.css file:

The very first entry is for the "hideElement" class, which contains a single style declaration ("display:none;"). So the two <div> blocks at the end of the form are not displayed.

The first two JavaScript files referenced by the HTML form page are the core jQuery file and the jQuery Form plugin, which you can simply download and place somewhere within your web application's directory structure. The third JavaScript file, submitDemo.js, has the custom functions that apply to the HTML form:

These functions are the key to how this technique works. The first function, the "ready" function, is a special jQuery function that runs as soon as the HTML elements on the page are able to be acted upon by JavaScript. The "ready" function assigns two event handlers. The first one defines the actions that occur when the the submit button of the HTML form (which has an id attribute of "submitButton") is clicked: when it is clicked, the value of the hidden text field at the start of the form is changed to "ajax." If JavaScript is disabled in the user's browser, this event will not fire and the value of the submitType hidden text field will remain "regular".

The second event handler executes when the HTML form (which has an id attribute of "submitDemoForm") is submitted. The form is submitted via AJAX using the ajaxSubmit function in the jQuery form plugin with the parameters contained in the submitOptions JavaScript object, which is declared and defined right below the second event handler. Again, if JavaScript is disabled in the user's browser, this event will not fire and the form with be submitted in a normal HTTP POST action to the server.

The submitOptions JavaScript object defines certain aspects of the AJAX submission. The "target" value is the id of the HTML element that will receive the HTML content returned by the server-side page that answers the AJAX call, and in this case the target is the second currently-hidden <div> block beneath the HTML form (the "ajaxResult" <div>). The "beforeSubmit" and "success" values denote JavaScript functions that should be called just before the AJAX call is made and after the AJAX call has completed, and in this case the showProcessing and hideProcessing functions are called. The "URL" value is the server-side page where the AJAX call should be directed, and in this case it is the same page defined in the "action" attribute of the HTML form.

The showProcessing function uses jQuery calls to disable the submit button of the HTML form (so the user cannot submit the form twice), hides the ajaxResult div (in case it was revealed during a previous form submission attempt) by adding the "hideElement" class, and displays the "processingMessage" <div> to alert the user that something is happening by removing the "hideElement" class from that <div>. The hideProcessing function performs the opposite actions: hides the processing message, reveals the ajaxResult <div>, and re-enables the form's submit button.

Finally, here is the code for the server-side page (serverSubmit.cfm) that handles the form validation and, if there are no errors, records the form information to the database:

This example uses ColdFusion to process the validation and submit the data to the database, but you could use any web programming language for this page.

The code starts by defining a variable ("errorList") to contain all of the validation problems found in the submission (if there are any). In this example, the only two validation rules are that the user must submit a first name and a last name. If the user omitted either or both names, the relevant error messages are added to the error variable, which I chose to create as a list (you could just as easily store the error messages in an array).

If, after all of the validation checks have been applied, there are no validation errors, the form information can be stored in the appropriate database table.

What happens next depends on whether or not the form was submitted via AJAX. If the value of the hidden form field "submitType" was changed to "ajax", that indicates that the form was submitted via AJAX. If there were no validation errors, a simple success message is generated and will be displayed in the "ajaxResult" <div> below the HTML form (as per the submitOptions attributes of the ajaxSubmit function in the submitDemo.js file). If there were validation errors, a list of the errors is generated using the <cfloop> block and that result is displayed in the "ajaxResult" <div>.

If, however, the form was submitted via a regular POST action, a different action takes place. In this case, a short error or success message is displayed as the visual output of the serverSubmit.cfm page itself, but you could just as easily redirect the user to another page and display the errors there.

The end result of all this, in a nutshell, is this...

If the user has JavaScript enabled:

  • The user enters the information into the form.
  • They click the submit button.
  • The submit button is disabled and the "Saving changes..." messages appears briefly below the submit button.
  • The server-side page processes the submitted data.
  • A message indicating a successful submission or a failed submission (with the reasons why it failed) is displayed, the "Saving changes..." message disappears, and the submit button is re-enabled.

If the user has JavaScript disabled:

  • The user enters the information into the form.
  • They click the submit button.
  • The server-side page processes the submitted data.
  • The server-side page displays the results of the form submission.

Again, this is a very simple example, but it demonstrates how you can write one set of validation code and write it in the server-side language you're most comfortable with.

 

Monday, December 10, 2007

My First AIR Application: colorPicker

In my most recent web application project, my clients asked for the ability to change the color of certain HTML elements without having to actually write or change any HTML code. So I used ColdFusion and the jQuery JavaScript library to create a color grid similar to the one that pops up in Adobe Dreamweaver when you type a color-related HTML or CSS attribute, allowing them to choose a color simply by clicking on it.

After I finished the grid, it occurred to me how I could use a similar tool for my coding work: CFEclipse doesn't have a selectable color grid (most likely a limitation of Eclipse itself), and it's a pain to open up Dreamweaver or Fireworks just to get a color. So I decided to try and make my color grid into an AIR application.

The result is colorPicker, a widget-like AIR application that lets you either select a color from a grid of "web-safe" colors or design a color using sliders to change the red, green, and blue values of the color. Once you have the color you want, you can click on the corresponding "Save to Clipboard" button to copy the hex color code to the clipboard and then paste it into your HTML code in your IDE of choice. It also saves all of the colors you've copied to the clipboard during your session so you can repeat a color.

It actually uses very little of the AIR API: just the clipboard copy function and the description file needed to run it. Everything else is done with JavaScript, HTML, and CSS.

You can view screenshots of colorPicker and download it from RIAforge.org at:

http://colorpicker.riaforge.org

Tuesday, December 4, 2007

Perfection Isn't Mandatory

I came across this blog post, and even the blog itself is geared towards the .Net crowd, I thought the message was true for all coders who strive to hone their craft:

You are NOT inadequate