Using validator with a variable attribute in ui:repeat

痞子三分冷 提交于 2019-11-26 17:25:57

问题


I'm using com.sun.faces version 2.1.18. In my application I have a dynamic list of questions. I use <ui:repeat> to render each question. Depending on the type of question I render a type of input component and validation. In case of a number range question I use <h:inputText> with <f:validateLongRange>.

The problem I run into is that the minimum and maximum attributes on the <f:validateLongRange> are always set to the first question's minimum and maximum value. So, when you use the validator on any other then the first question it fails. Is that supposed to happen? Is there a way to get validation working on dynamically generated components? I hope it can be solved without switching to <c:forEach>.

Code snippet:

<ui:repeat value="#{questionnaire.questionsCollection}"
           var="question">
  ..
  <h:inputText value="..">
    <f:validateLongRange minimum="#{question.minimumValue}"
                         maximum="#{question.maximumValue}"/>
  </h:inputText>
  ..
</ui:repeat>

I've outputted #{question.minimumValue} and #{question.maximumValue}, and they have the correct values for my question.


回答1:


This is indeed specified/expected behavior. The attributes of taghandlers like <f:validateXxx> are evaluated during view build time. So they can't refer a variable which is only available during view render time like the currently iterated variable of <ui:repeat>. It would indeed work when you use an iterator which runs during view build time like JSTL <c:forEach>. A more elaborate explanation about view build time versus view render time is given here: JSTL in JSF2 Facelets... makes sense?

You have basically the same problem as explained in detail here: How to set converter properties for each row of a datatable? It outlines various solutions in detail. One of the solutions in your particular case would be using OmniFaces <o:validator> which enables render-time evaluation of all attributes, so that you can just replace

<f:validateLongRange minimum="#{question.minimumValue}"
                     maximum="#{question.maximumValue}" />

by

<o:validator validatorId="javax.faces.LongRange" 
             minimum="#{question.minimumValue}"
             maximum="#{question.maximumValue}" />

in order to get it to work as desired.

See also:

  • Setting a validator attribute using EL based on ui:repeat var


来源:https://stackoverflow.com/questions/15682196/using-validator-with-a-variable-attribute-in-uirepeat

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!