Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
557 views
in Technique[技术] by (71.8m points)

validation - Using validator with a variable attribute in ui:repeat

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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:


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...