Help

Built with Seam

You can find the full source code for this website in the Seam package in the directory /examples/wiki. It is licensed under the LGPL.

You may run into situations where JSF validation logic other than Hibernate Validator (or custom Hibernate Validator) is required. I have tried using Hibernate Validators (e.g. @org.hibernate.validator.Pattern) with SFSB/SLSB methods. This is not recommended or supported in the context of a Seam application.

An example I ran into recently is as follows:

1) user enters data into HtmlInputText in a HtmlForm 2) we require live validation using a4j:support (usually using onblur for HtmlInputText and onchange for HtmlSelectOneMenu)

We are performing live validation to check that the data the user entered is valid (i.e. already exists in a db table code column) as well as for duplicates. This validation requires a db read so therefore we will implement this validation using Seam validation.

This is implemented by adding a validator attribute to the HtmlInputText component. The value of the validator attribute should be the name of the Seam validator component (in this case JavaBean that implements javax.faces.validator.Validator and java.io.Serializable interfaces.) Also, the validator class should be annotated with @org.jboss.seam.annotations.faces.Validator. Note that with this single validator class, we can validate for three different scenarios. And the good thing is that this implementation supports re-usability, in case you have other use cases that require this business validation functionality. Enjoy!

Here's a partial code snippet:

@Name("seamValidatorProblemCodes") 
@Scope(ScopeType.CONVERSATION)
@org.jboss.seam.annotations.faces.Validator
public class SeamValidatorProblemCodes implements javax.faces.validator.Validator, java.io.Serializable
{
   @Logger
   Log log;

   //skipping instance variables for brevity...
      
   public void validate(FacesContext context, UIComponent cmp, Object value) throws ValidatorException 
   {	   
	   if (value != null)
	   {   
		   cmpId = cmp.getId();
		   log.info("validate(): cmpId = "+cmpId);
		   
		   clientId = cmp.getClientId(context);
		   log.info("validate(): clientId = "+clientId);
		   
		   String mode = "";
		   Boolean dupeExists = false;
		   
		   //validation for modalPanel (edit problem code in RepairCaseDetails)
		   if (value instanceof DropDownValue)
		   {
			   DropDownValue ddv = (DropDownValue)value;
			   problemCode = Integer.toString(ddv.getCode());	
			   mode = "edit";
			   
			   dupeExists = checkForDupes(cmp, value, mode);
			   
			   if (dupeExists)
			   {
				   disableSubmitButton = true;
				   throw new ValidatorException(new FacesMessage("this problem code already exists for this repair Id, please select a different one"));
			   }
			   else
				   disableSubmitButton = false;
			   
		   }
		   //validation for problem code adds (CreateRepairCase)
		   else		   
		   {
			   problemCode = (String)value;	
			   if (problemCode != null && !problemCode.equals(""))
			   {   
				   if (!validateProblemCodes(problemCode)) 
				   {   			   
				        throw new ValidatorException(new FacesMessage("invalid value"));  //doesn't apply to edit code b/c UI is dropdown...
				   }
				   mode = "add";
				   
				   dupeExists = checkForDupes(cmp, value, mode);
				   
				   if (dupeExists)
				   {				   
					   throw new ValidatorException(new FacesMessage("duplicates not allowed"));
				   }   
		   	   }			   
		   }
	   }
   }

In your xhtml, use something like this:

<s:decorate id="problemCode1" template="layout/edit.xhtml">
	<h:inputText id="_problemCode1"
		value="#{createRepairCase.problemCode1}"
		validator="seamValidatorProblemCodes">
		<a4j:support event="onblur" 
			     reRender="problemCode1"
			     bypassUpdates="true" 
			     eventsQueue="myQueue"
			     requestDelay="200" 
			     ignoreDupResponses="true"
			     oncomplete="setFocusProblemCodes();" />
	</h:inputText>

</s:decorate>