0

I'd like to change the "required" property of an InputText that is located within an ui:repeat, but I'm not able to access to the component from the ManagedBean:

<h:selectManyCheckbox id="required" value="#{test.required}"
    layout="lineDirection" converter="javax.faces.Integer">
    <f:ajax event="change" listener="#{test.update}" />
    <f:selectItems value="#{test.selectable}"></f:selectItems>
</h:selectManyCheckbox>
<ui:repeat value="#{test.names}" var="name" id="repeat">
    <h:panelGrid columns="3">
        <h:outputLabel id="nameLabel">name:</h:outputLabel>
        <h:inputText id="name" value="#{name}"
            validator="#{test.validateName}" />
        <h:message for="name"></h:message>
    </h:panelGrid>
</ui:repeat>

I'm trying to use the findComponent method, but it does not work:

public void update(AjaxBehaviorEvent event) {
    for(Integer i: selectable) {
        UIViewRoot vr = FacesContext.getCurrentInstance().getViewRoot();
        HtmlInputText input = (HtmlInputText)vr.findComponent("form:repeat:"+i+":name");
        input.setRequired(required.contains(i));
    }
}
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555

1 Answers1

1

The ui:repeat doesn't repeat the components in the view root, it repeats the component's output in the rendered HTML output.

There are several ways to achieve this properly. One of them is to use a value object instead and set the requireness there. E.g. a List<Item> wherein Item has the properties String name and boolean required.

<ui:repeat value="#{test.items}" var="item" id="repeat">
    <h:panelGrid columns="3">
         <h:outputLabel id="nameLabel">name:</h:outputLabel>
         <h:inputText id="name" value="#{item.name}" required="#{item.required}" validator="#{test.validateName}" />
         <h:message for="name"></h:message>
    </h:panelGrid>
</ui:repeat>

There are more ways, but since the JSF version you're using and the functional requirement is unclear, it's only guessing which way is the most applicable in your case.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • The functional requirement is that when you select an item clicking on a checkbox, the corresponding inputText must be required. – user532357 Dec 06 '10 at 15:21
  • Think of localizable data, the checkboxes would be locales, and the inputTexts the localized data for each locale. Only the inputTexts for the selected locales should be required. For example, if you want to add translated titles for a given book, but just add the languages into it has been translated. – user532357 Dec 06 '10 at 15:25
  • Requirement is sound. Are you open to replacing `h:selectManyCheckbox` by a `h:selectBooleanCheckbox` in 1st column of `h:panelGrid`? It's easier to have both the checkbox and inputtext in the same repetition. – BalusC Dec 06 '10 at 15:44
  • The code was just a use case, the real form is much more complex, and there is even jquery functionality to show/hide required fields. – user532357 Dec 06 '10 at 17:02
  • So the question is if there is any way to access to a HTMLInputText instance that there is within a UIRepeat from Java code in a ManagedBean or other components like Validators. – user532357 Dec 06 '10 at 17:04
  • something like findComponent. – user532357 Dec 06 '10 at 17:05