3
votes

I have a problem with finding component in JSF tree. Suppose I have the following template:

<a4j:form id="someForm">
<a4j:outputPanel id="somePanel">
    <a4j:repeat id="people" value="#{bean.people}" rowKeyVar="_row" var="_data" stateVar="_state">
        <s:decorate id="personPanel" template="edit.xhtml">

            <h:outputLabel for="personAge" value="Choose your age:" />

            <h:selectOneMenu id="personAge" value="#{_data.age}">
                <s:selectItems var="_item" value="#{ageValues}" label="#{_item.description}" />
            </h:selectOneMenu>

        </s:decorate>
    </a4j:repeat>
</a4j:outputPanel>
</a4j:form>

Namespaces are defined as:

xmlns:a4j="http://richfaces.org/a4j"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:s="http://jboss.com/products/seam/taglib"

As you can see, there is a a4j:repeat tag, so there can be n rendered select inputs on the page. How can I find n-th component in JSF tree at the server side? At the client side, components are rendered like: someForm:somePanel:0:personPanel:personAge. I'm trying to find component this way:

UIViewRoot root = FacesContext.getCurrentInstance().getViewRoot();
UIInput ageInput = (UIInput) root.findComponent("someForm:somePanel:0:personPanel:personAge");

But it couldn't be find. I've checked tree, and it seems like component with that id doesn't exist.

So how can I obtain this component? Is there any way to achieve that?


EDIT:

I've found some workaround. Actually, I didn't need components, but their values. Values can be retrieved from request by their names. Following code:

FacesContext facesContext = FacesContext.getCurrentInstance();
String ageValue = facesContext.getExternalContext().getRequestParameterMap().get("someForm:somePanel:0:personPanel:personAge");

did the work.

1
Which tag library (which xml namespace) have you mapped as a:?meriton
I've updated post. It's xmlns:a="richfaces.org/a4j.Karol Lewandowski

1 Answers

3
votes

a4j:repeat isn't a tag handler that would create dedicated components for each iteration. Rather, it causes its child components to be visited repeatedly during each phase of the JSF lifecycle. That is, there isn't a dedicated component for each row.

For more information on the difference between tag handlers and components, see: https://rogerkeays.com/jsf-c-foreach-vs-ui-repeat

It can usually be avoided to lookup components by name on the Java side. If you told us why you're trying to do this, we might suggest alternatives.

Edit: Validation in JSF is usually done by a Validator or (for complex cases) in the action method by working directly on the data in the backing bean, putting FacesMessage into the FacesContext manually. I don't see why you'd need the component for validation?