Easy JavaScript Form Validation
November 7th, 2007 in tutorials | No Comments
I’ve noticed a lot of JavaScript form validation scripts out there, and I think they’re headed in the wrong direction. Anyone can disable JS, which inevitably leads to redundant validation code server-side and client-side. I’m going to share with you my method of validating forms I used in JibberBook. There were a couple conditions I wanted to meet that solved the problems above:
- Validation works with or without JavaScript
- Validation logic is not replicated client-side and server-side
So what was my solution? Validate only server-side, and use Ajax to send the form data and receive the response from the server. What I really want to do is isolate that method from JibberBook to create a reusable script, but for this tutorial, I’ll be using code from JibberBook.
Server-Side
First, we’ll start with the PHP:
function validateForm(&$formData){ global $ajax, $message, $value; // $ajax set in add.php $errornum = null; $errordesc = ''; if ($formData['website'] != '') { if (!preg_match('#((http://)|(www\.))+(([a-zA-Z0-9\._-]+\.[a-zA-Z]{2,6})|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(/[a-zA-Z0-9\&%_\./-~-]*)?#', $formData['website'])) { $errornum = '4'; $errordesc = 'Website is not a valid URL.'; } if (substr($formData['website'], 0, 7) != 'http://') { $formData['website'] = 'http://' . $formData['website']; } } if ($formData['name'] == '' || $formData['comment'] == ''){ $errornum = '3'; $errordesc = 'Name and Comment fields are required.'; } if ($formData['jbemail'] != ''){ // if this field is filled in, it's probably spam $formData['spam'] = 1; } unset($formData['jbemail']); } if ($formData['spam']) { $value = '2'; $message = 'This comment has been flagged as spam and has been added to the moderation queue.'; return; } // if there's an error, return json object or set session vars, and then stop further actions if (isset($errornum)) { if ($ajax) echo "{'value':'$errornum', 'message':'$errordesc'}"; else { $_SESSION['message_type'] = 'error'; $_SESSION['message'] = $errordesc; $_SESSION['form_name'] = $formData['name']; $_SESSION['form_website'] = $formData['website']; $_SESSION['form_comment'] = $formData['comment']; $url = "Location: ../" . JB_INDEX; header($url); } exit(1); } }
This is my form validation function. It’s not too complex because I don’t have a lot of fields to validate, but the same concept can be applied to more complex validating. Basically what happens is if there’s a validation error $errornum and $errordesc are set to contain the associated values. Spam works a bit differently, but that’s not relevant to this topic.
After the form data has been checked and there’s an error, what happens next depends on whether this was an Ajax request or a regular request. If it’s an Ajax request, a JSON object is returned that contains the error number and the error description. If it’s a regular request, session variables are set which show up when the page is redirected back to the form.
Client-Side
Here’s where the magic happens:
processAddResponse : function () { var response = Json.evaluate.attempt(this.ajaxReq.response.text); if (response) { if (response.value != '1') { this.showMessage(response.message, 'error'); if (response.value == '2') this.obj.form.reset(); } else { this.obj.commentWrapper.injectHTML(response.content, 'top'); var new_comment = this.obj.commentWrapper.getFirst(); if (this.obj.scroller == window) { this.fx.scroll.toElement(this.obj.commentWrapper).chain(function(){this.showMessage(response.message, 'confirm');}.bind(this)); } else { this.fx.scroll.toTop(); this.showMessage(response.message, 'confirm'); } this.obj.form.reset(); } } else this.showMessage('An error has occurred.', 'error'); this.loaded(); }
This function is called on completion of the Ajax request. If a valid JSON object is returned, it’s evaluated. If not (there was probably a PHP error) an error message is displayed. Then I just test for various error numbers and take the appropriate action.
I also came up with a nifty message function that you see called above. Here that is:
showMessage : function (text, type) { this.obj.messageWrapper.setStyles({ 'left': (window.getWidth() / 2 - 150), 'top': window.getScrollTop() + 30, 'opacity': 0 }) this.obj.messageWrapper.className = type; this.obj.messageWrapper.getFirst().setText(text); this.fx.message.start(0.9); }
This allows me to show any type of message as long as it’s defined in the CSS file. Very extensible.
Conclusion
By using the method above, you should be able to keep all of your validation logic in one place while still utilizing the instant feedback abilities of JavaScript. Keep in mind that the examples above were excerpted and won’t work as is. You can find everything in working order by downloading JibberBook.

