My app needs to render a list of questions whose type is database-driven.  I'm 
using a few facelets TagHandlers to accomplish this.  The view looks like this:


  | <s:validateAll>
  | 
  |     <f:facet name="aroundInvalidField">
  |             <s:span styleClass="errors"/>
  |     </f:facet>
  | 
  |     <h:panelGrid id="questionPanel" columns="3">
  | 
  |     <crs:customQuestions
  |             registrationType="#{registrationType}"
  |             questionTextVar="questionText"
  |             questionNumberVar="i"
  |             requiredVar="required">
  | 
  | 
  |             <h:outputLabel for="answerInput#{i}" value="#{i}" 
id="questionNumber#{i}"/>
  | 
  |             <s:formattedText value="#{questionText}" id="questionText#{i}"/>
  | 
  |             <h:panelGroup>
  |                     <s:decorate>
  |                             <crs:isText>
  |                                     <h:inputText id="answerInput#{i}"
  |                                             
value="#{registrationProcess.pageAnswers[ i].valueString}"
  |                                             required="#{required}">
  |                                             <a:support event="onblur" 
reRender="questionErrors#{i}"/>
  |                                     </h:inputText>
  |                             </crs:isText>
  | 
  |                             <crs:isDate>
  |                                     <h:inputText id="answerInput#{i}"
  |                                             
value="#{registrationProcess.pageAnswers[ i].valueDate}"
  |                                             required="#{required}">
  |                                             <s:convertDateTime 
pattern="MM/dd/yyyy"/>
  |                                             <a:support event="onblur" 
reRender="questionErrors#{i}"/>
  |                                     </h:inputText>
  |                                     <s:selectDate for="answerInput#{i}">
  |                                             <h:graphicImage 
url="img/dtpick.gif" style="margin-left:5px"/>
  |                                     </s:selectDate>
  |                             </crs:isDate>
  | 
  |                             <crs:isBoolean>
  |                              <h:selectBooleanCheckbox
  |                                     id="answerInput#{i}"
  |                                     
value="#{registrationProcess.pageAnswers[ i].valueBoolean}"
  |                                     required="${required}"/>
  |                             </crs:isBoolean>
  | 
  |                             <br clear="none"/>
  |                             <a:outputPanel id="questionErrors#{i}">
  |                                     <s:message/>
  |                             </a:outputPanel>
  |                     </s:decorate>
  |             </h:panelGroup>
  | 
  |     </crs:customQuestions>
  |     </h:panelGrid>
  | </s:validateAll>
  | 

And the main taghandler (which I modeled after facelets' ForEachHandler) looks 
like this:

  | public class CustomQuestionTagHandler extends TagHandler {
  | 
  |     private final TagAttribute registrationType;
  |     private final TagAttribute questionTextVar;
  |     private final TagAttribute questionNumberVar;
  |     private final TagAttribute requiredVar;
  | 
  |     public CustomQuestionTagHandler(TagConfig config) {
  |             super(config);
  |             registrationType = getRequiredAttribute("registrationType");
  |             questionTextVar = getRequiredAttribute("questionTextVar");
  |             questionNumberVar = getRequiredAttribute("questionNumberVar");
  |             requiredVar = getRequiredAttribute("requiredVar");
  |     }
  | 
  |     @SuppressWarnings("unchecked")
  |     public void apply(FaceletContext faceletContext, UIComponent parent) 
throws IOException, FacesException,
  |                     FaceletException, ELException {
  |             RegistrationType registrationType = (RegistrationType) 
this.registrationType.getObject(faceletContext,
  |                     RegistrationType.class);
  |             assert registrationType != null;
  |             List<QuestionUsage> questionUsages = 
registrationType.getQuestionUsages();
  |             assert questionUsages != null;
  | 
  |             String questionTextVar = 
this.questionTextVar.getValue(faceletContext);
  |             String questionNumberVar = 
this.questionNumberVar.getValue(faceletContext);
  |             String requiredVar = this.requiredVar.getValue(faceletContext);
  | 
  |             VariableMapper variables = faceletContext.getVariableMapper();
  | 
  |             int i = 1;
  |             for (QuestionUsage questionUsage : questionUsages) {
  |                     Question question = questionUsage.getQuestion();
  |                     Integer questionNumber = new Integer(i);
  | 
  |                     ValueExpression questionNumberValueExpression = 
faceletContext.getExpressionFactory()
  |                             .createValueExpression(questionNumber, 
Integer.class);
  |                     variables.setVariable(questionNumberVar, 
questionNumberValueExpression);
  | 
  |                     ValueExpression questionTextValueExpression = 
faceletContext.getExpressionFactory().createValueExpression(
  |                             question.getText(), String.class);
  |                     variables.setVariable(questionTextVar, 
questionTextValueExpression);
  | 
  |                     Boolean required = questionUsage.isRequired();
  |                     variables.setVariable(requiredVar, 
faceletContext.getExpressionFactory().createValueExpression(required,
  |                             Boolean.class));
  | 
  | 
  |                     faceletContext.setAttribute("questionType", 
question.getType());
  | 
  |                     // execute body
  |                     this.nextHandler.apply(faceletContext, parent);
  | 
  |                     i++;
  |             }
  |     }
  | 
  | }
  | 

This renders fine.  But during the onblur ajax validation check, this occurs:


  | java.lang.NullPointerException
  |     at org.jboss.seam.core.Expressions.getValidator(Expressions.java:198)
  |     at org.jboss.seam.core.Expressions.validate(Expressions.java:182)
  |     at org.jboss.seam.ui.ModelValidator.validate(ModelValidator.java:25)
  |     at 
javax.faces.component._ComponentUtils.callValidators(_ComponentUtils.java:157)
  |     at javax.faces.component.UIInput.validateValue(UIInput.java:312)
  |     at javax.faces.component.UIInput.validate(UIInput.java:353)
  |     at javax.faces.component.UIInput.processValidators(UIInput.java:183)
  |     at 
javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:624)
  |     at 
javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:624)
  |     at 
javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:624)
  |     at 
javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:624)
  |     at javax.faces.component.UIForm.processValidators(UIForm.java:70)
  |     at 
javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:624)
  |     at 
javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:146)
  |     at 
org.ajax4jsf.framework.ajax.AjaxViewRoot.processValidators(AjaxViewRoot.java:389)
  | ...
  | 

It appears that Expressions.validate(...) is trying to evaluate 
#{registrationProcess.pageAnswers[ i].valueString}, which returns null. 

I don't know enough about EL to know why.  I suspect either I can't use model 
validation this way, or I need to do something special in my TagHandler.  Does 
anyone have any recommendations?

Also, a null-check should probably be put in Expressions.java (line 198ish) 
before calling getValidator().

Thanks!

View the original post : 
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4021364#4021364

Reply to the post : 
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4021364
_______________________________________________
jboss-user mailing list
[email protected]
https://lists.jboss.org/mailman/listinfo/jboss-user

Reply via email to