My question is related to this one Get all hidden input fields in JSF dynamically but it\'s not the same as I want to work with JSF and not plain HTML, and assuming that I h
You also need to iterate over children of children, and their children, etcetera. You see, it's a component tree.
Here's a kickoff snippet of an utility method which does exactly that using tail recursion:
public static <C extends UIComponent> void findChildrenByType(UIComponent parent, List<C> found, Class<C> type) {
for (UIComponent child : parent.getChildren()) {
if (type.isAssignableFrom(child.getClass())) {
found.add(type.cast(child));
}
findChildrenByType(child, found, type);
}
}
Here's how you could use it:
UIForm form = (UIForm) FacesContext.getCurrentInstance().getViewRoot().findComponent("formId");
List<HtmlInputHidden> hiddenComponents = new ArrayList<>();
findChildrenByType(form, hiddenComponents, HtmlInputHidden.class);
for (HtmlInputHidden hidden : hiddenComponents) {
System.out.println(hidden.getValue());
}
Or, better, use UIComponent#visitTree() which uses the visitor pattern. The major difference is that it also iterates over iterating components such as <ui:repeat>
and <h:dataTable>
and restores the child state for every iteration. Otherwise you would end up getting no value when you have an <h:inputHidden>
enclosed in such component.
FacesContext context = FacesContext.getCurrentInstance();
List<Object> hiddenComponentValues = new ArrayList<>();
context.getViewRoot().findComponent("formId").visitTree(VisitContext.createVisitContext(context), new VisitCallback() {
@Override
public VisitResult visit(VisitContext visitContext, UIComponent component) {
if (component instanceof HtmlInputHidden) {
hiddenComponentValues.add(((HtmlInputHidden) component).getValue());
return VisitResult.COMPLETE;
} else {
return VisitResult.ACCEPT;
}
}
});
for (Object hiddenComponentValue : hiddenComponentValues) {
System.out.println(hiddenComponentValue);
}
After all, it's probably easiest to just bind them to a bean property the usual way, if necessary inside an <ui:repeat>
:
<h:inputHidden id="name1" value="#{bean.name1}"/>
<h:inputHidden id="name2" value="#{bean.name2}"/>