Skip to content
Share this..

Custom JSF Input Validation Styling for any Component

2010 October 29
by Eddie

We didn’t have room on our pages for individual message boxes, and also had the need to style specific fields on our JSF pages whenever validation failed on the server, with user friendly field names in the message.

Example:  ”User Name is Required” , and the field for User Name is highlighted red.

jsf jquery validation 300x68 Custom JSF Input Validation Styling for any Component

Custom field styling and nicer field names for JSF validation

Unfortunately there are times when jsf insists on inserting field ids into the message.

1. Here’s the scenario;

  • If any jsf converter validation fails (like a string in an int field) JSF will throw a warning like “jid17:jid34: Values must be type numeric” – The form id and page id prepend any internal messages – gross.
  • If any page custom validation fails (like min and max lengths) JSF will throw our custom message
  • If custom validators fail(like the format of a zip code based on the province as US or CA) throw  a custom message
  • If any DB rule issues fail (like name in use by other user) then our Manager throws a custom message (but it is not hooked to any component)

The troubles is that without overriding JSF components or classes we do not have access to the component when every message is thrown, and would be unable to change its style class.

Rather than relying on some tricky JSF or Java code to intercept and update classes I decided to take a simpler approach (or so I think).  Using jQuery, the preprendId=”false” attribute, and specific Messages for every field we can do ANY custimaztion we want to ANY failed field, input, checkbox, etc on the page.

 1. Here’s the scenario;

 2. Here’s the Solution

 3. Hiding the default form ID in JSF

 4. Giving JSF Components User Friendly field names that include spaces

 5. Include field names when passing custom messages from Java code

 6. Give your Message components a specific ID

 7. jQuery code to cleanup JSF messages and apply field level styling

 8. What if I can’t use prependID=”false” ?

 9. Summary

2. Here’s the Solution

There is actually a few pieces to the puzzle, but all very simple.

  • Set prependId=”false” on the <h:form> elements of your page (optional  but must be consistent for all forms that will use this validation)
  • Give your fields User Friendly names (well sort of, we use JQuery to replace any “_” with spaces )
  • If your ever throwing a custom message, prepend the user friendly(almost) id to your message (we use jquery to strip it off)
  • Give your <h:messages /> element a specific ID.
  • Insert The jQuery client side fixer upper and styl-o-matic to your template. (its like 5 lines)

3. Hiding the default form ID in JSF

This is something you will only want to do if all forms can be treated equally in your code elsewhere. Other the id may be important. If you want to leave the form ID in tact, skip this section. But you will need to modify the steps below to accomidate

Hiding the form’s id is simple, just insert the attrinute prependID=”false” in your forms.

<h:form prependId="false">
... components, etc...
</h:form>

4. Giving JSF Components User Friendly field names that include spaces

By the law of html element ids must be alphanumeric, no spaces. So when you name a field “frstNme” in JSF, there’s a good chance a user will see it on some failed validation at some point.

To compensate, give all your fields nice names that would be pleasant to users, if only for spaces. “First_Name” is prettier, but not what the user will see. The jQuery code replaces all underscores with spaces, so the user would see “First Name….” You could also user hypens.

<h:inputText id="First_Name" value="#{bean.firstName}" required="true"
requiredMessage="First_Name:is required" 
size="19">
</h:inputText>

5. Include field names when passing custom messages from Java code

This one seems weird, but allows for the most consistency aligning our custom messages with JSF’s defaults.

In my managers I throw messages like this:

public String saveUserAction(){ 
	 ...
	if(searchString.length()>15)
	{
		addMessage("First_Name:Must be between 2 and 16 characters");
		return null;
	}
	...
	return navString;
}
 
private void addMessage(String messageStr){
	FacesMessage message = new FacesMessage( messageStr);
	FacesContext.getCurrentInstance().addMessage("errorTag", message);
}

6. Give your Message components a specific ID

All pages that you want to apply this to should have a message element like;

<h:messages id="messageList" />

We will need that so jQuery knows where to looks for messages.

7. jQuery code to cleanup JSF messages and apply field level styling

The jQuery snippet (well plain JS too) is where this all comes together. We iterate through all the

  • elements in the
      element with our messages ID. Each list item may be a field message, and have the format “field_name:message to show user”. We check for a colon, and if present split on that as a delimiter, getting an id in the first bucket, and the message in the second. We can then apply styling to a field matching that id before finally fixing the ID to contain spaces, and showing the complete message to user.

      $('#messageList li').each(function(i) { // for each li in ul 
              var id=$(this).text().split(':'); // split on colon
              if(id.length>1){ // if field id was present, go to work
      		$('#'+id[0]).css('color','red'); //make faulted field fonts red
                      $('#'+id[0]).css('border-color','red'); // make faulted fields border red
                      id[0]=id[0].replace(/_/g," "); // replace any "_" with spaces
                      $(this).text(id[0] + ' ' + id[1]); // make new message the nicer way
              }
      });

      8. What if I can’t use prependID=”false” ?

      IF you can’t or do not want to use that attribute, make the following changes:
      *Prepend the form’s Id to your messages (ex: “jidt23:First_Name:Message to user”)
      *Adjust jQuery to use buckets 1 and 2 sperated by a colon for the field id (jidt23:First_Name), and then discard 1, run replace on 2, and show 2 and 3 as the message (First Name is required).

      9. Summary

      That’s it! it turned out to be quite simple, and we were able to refactor our existing application of about 25 pages (cleaning up field ids and error messages) is less than 2 hours.

  • 16 Responses leave one →
    1. Mario permalink
      December 1, 2010

      Hi, thanks for sharing the code!

      I have a doubt , where must I put the Jquery script?

    2. Eddie permalink*
      December 15, 2010

      @Mario
      I stuck this code in my footer element. Any place after the html elements it effects should be fine.

    3. Sudda permalink
      February 13, 2011

      Given JQuery script will not fire after AJAX calls. Therefore validation failures after AJAX calls are not formatted.

      So how to handle AJAX related custom validation messages ?

    4. Eddie permalink*
      February 13, 2011

      @sudda
      That’s a great question.I’m not much of a jquery expert. off the top off my head though you would want top fall back on classic javascript timed listeners to checks for updates to call the jquery logic, in place off body load. Jquery does provide methods for checking ajax calls progress.

      Good luck, and let us know what you find out!

    5. Sai Pradeep permalink
      March 9, 2011

      Hi Eddie,
      Thanks for sharing the code. Really it helped me a lot for implementing the validation styling for components. But i got another easy way for implementing this. Looks like this is quite easier.

      We can directly relay on JSF implicit object “facesContext”, some thing like..

      where i can now define my custom css class in .errorInputBox{ border:1px;……}

      I hope this will be also helpful to others. :)

      Thanks,
      Sai Pradeep D.

    6. Sai Pradeep permalink
      March 9, 2011

      Sorry i think my code is not formatted.. correctly.. please check..

      
      <h:form id="manageLabForm" >
      
      <h:inputText id="labId" size="15"  styleClass="#{not empty facesContext.getMessageList('manageLabForm:labId') ? 'errorInputBox' : '' }"/>
      
      </h:form id="manageLabForm" >
      
    7. Eddie permalink*
      March 9, 2011

      @Sai Pradeep
      That’s a neat trick! And that works well for ajax enabled forms too, so you wouldn’t need jQuery to do any of the styling. Very nice.

    8. Vivek Madapura permalink
      March 22, 2011

      Hi I get a ELException on adding this to my form
      javax.el.ELException: Error Parsing: #{not empty facesContext.getMessageList(‘form.nameInput’) ? ‘red’ : ‘ ‘ }

      Could any of you help me in this regard?

    9. Eddie permalink*
      March 28, 2011

      @Vivek – Make sure you are using JSF 2, and have version 2 of the EL libraries available.

    10. Ashok permalink
      March 31, 2011

      @Eddie
      How to achieve this in JSF1.2 ,

    11. Eddie permalink*
      April 1, 2011

      @Ashok, you would only need to use the methods as I provide them, and not use Sai’s clever trick. If that doesn’t work for you, let me know what issues youn see.

      Also, just an opinion, JSF2.0 is well worth the effort to update as it brings a number of performance and maintainablility improvements.

    12. Ashok permalink
      April 4, 2011

      @Eddie Thanks for your reply.
      My case is, i have a <rich:tabPanel , which contains many <rich:tab components.
      Each tab contains many input components, while submitting i need to validate them. Since i have many tabs ,so user has to verify all tabs one by one to check any validation errors in that tab .

      I thought of changing style for those has validation errors, so i tried @Sai option which i can apply for my <rich:tab , unfortunately it doesn't work for jsf 1.2.

    13. Eddie permalink*
      April 4, 2011

      @Ashok

      OK, I understand the situation now. I think you can pull this off with JSF1.2 and jQuery..

      Follow the basic steps above to get each field styling itself, EXCEPT
      Instead of relying on for all messages, rely on on a per field basis instead.

      Finally, Modify jQuery loop to handle parent tabs

      The 3rd step is obviously the trickier one, but it should get you there.
      Start by looping the tabs, all jquery will need is a class assigned to all tabs, it will act like a label that tells jQuery, “yes, act on this tab”.
      For each iteration, you will have a sub loop that checks all children fields for the messages element, and if present it styles the current and parent element (tab).

      you may also need to grab a object reference for each tab in the top loop, depending on how deeply elements are nested.

      jQuery provides excellent looping and parent()/child() navigation.

      Hope that gets you started!

      -Eddie

    14. Martin permalink
      July 12, 2011

      Good job!

      But have a look at

      http://www.laliluna.de/articles/posts/jsf-2-evaluation-test.html

      for JS-less field-styling.

    15. Eddie permalink*
      July 12, 2011

      Looks like that uses primefaces, and it would still be some extra work to validate dependent fields based on other field’s values.

      But a great link, thanks Martin.

    Leave a Reply

    Note: You can use basic XHTML in your comments. Your email address will never be published.

    Subscribe to this comment feed via RSS