Simple client-side validation with JSF and Primefaces

The conventional wisdom for JSF seems to be that server-side form validation is good enough and client-side validation should be avoided. Even if your component library makes it relatively easy, raw javascript is hard to maintain in a jsf environment, an ajax update is fast enough, inputs will need to be validated on the server anyway, etc.

Seeing javascript in jsf templates may suggest to you ill-advised hacks and browser work-arounds that will be hard to support, but with javascript being used all over and frameworks like backbone.js and knockout.js getting popular, it’s hard to pass up the advantages that it can give you. It’s hard to justify making a call back to the server just to validate an email format or enable a button. Ajax requests can be pretty inexpensive and responsive to the user, but no request at all is even cheaper and more responsive.

Does mixing javascript and JSF really have to be such a burden to maintain? Primefaces provides a solid client-side api. It lets you define javascript event handlers (onblur, onclick, etc.) for many of its components and for some, extra client-side hooks and a widgetVar attribute for an id available directly in javascript.

Here are a few simple examples. The full code is available at https://github.com/thwick/clientside-jsf-validation.git.

You might have an email text field that you want to evaluate for validity and display a message if the field loses focus and the input is not valid.

<p:inputText id="emailInput" onblur="validateEmail();" />

And the function:

 function validateEmail() {
    var emailReg = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/;
    var email = $("#testForm\\:emailInput").val();
    if( emailReg.test( email ) ) {
       $("#emailInputValidation").text("valid!");
    } else {
      $("#emailInputValidation").text("invalid!");
   }
 }

where the emailInput field is in a form called testForm and it updates a span tag with the id emailInputValidation. Dealing with ids of JSF components can sometimes be painful, unfortunately, but Primefaces does let you define a simpler id in some cases.

For example, say you want to enable or disable a button depending on whether an input text field is empty or more than nine characters. Primefaces lets us define a ‘widgetVar’ value, which is the id of the component as it will appear on the html page, no generated id tacked onto the end. The button looks like this-

<p:commandButton id="button" widgetVar="buttonWidget" disabled="true" //>

The Primefaces commandButton lets us simply call enable/disable to alter its state directly without calling back to the server.

In your javascript, just call buttonWidget.enable(); to enable it:

function validateContent() {
    var currentValue = $("#testForm\\:nonNullInput").val();
    if (currentValue) {
      if (currentValue.length < 9) {
        $("#fieldInputValidation").text("");
        buttonWidget.enable();          		
      } else {
        $("#fieldInputValidation").text("Field must be 8 characters or less!");
        buttonWidget.disable();
      }
    } else {
      buttonWidget.disable();
    }
}

For important data, validation on the server will still be required. But for a lot of cases, using the clientside api can improve responsiveness without adding too much complication.

This entry was posted in software. Bookmark the permalink.

One Response to Simple client-side validation with JSF and Primefaces

  1. bhantol says:

    “The conventional wisdom for JSF seems to be that server-side form validation is good enough and client-side validation should be avoided”

    Conventional wisdom is wrong. Your UI will not be responsive. New wisdom is that you need both and use same code on both side :)

    “Primefaces provides a solid client-side api. ”
    Not sure what is there for PrimeFaces to do here … this is done via jQuery……not Primefaces. I believe it uses jQuery behind the scenes. Yeah it provides a hook which is nothin….

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>