views:

455

answers:

1

hi there,

i am trying to get the client id of a component in a datatable. the problem is that jsf puts row index before the component id automatically, i.e.

   <a id="mappedidentifier_table:1:mappedidentifier_Update" href="#">Update</a>

for a link in the second row (index=1).

i am using the following methods to get the clientId

   public static String findClientId(String id) {
        FacesContext context = FacesContext.getCurrentInstance();
        UIViewRoot view = context.getViewRoot();
        if (view == null) {
            throw new IllegalStateException("view == null");
        }
        UIComponent component = findComponent(view, id);
        if (component == null) {
            throw new IllegalStateException("no component has id='" + id + "'");
        }
        return component.getClientId(context);
    }

    private static UIComponent findComponent(UIComponent component, String id) {
        if (id.equals(component.getId())) {
            return component;
        }

        Iterator<UIComponent> kids = component.getFacetsAndChildren();
        while (kids.hasNext()) {
            UIComponent kid = kids.next();
            UIComponent found = findComponent(kid, id);
            if (found != null) {
                return found;
            }
        }

        return null;
    }

however this returns

mappedidentifier_table:mappedidentifier_Update,

instead of

mappedidentifier_table:1:mappedidentifier_Update,

therefore it does not match any element cause the row index in id is missing.

i've read http://illegalargumentexception.blogspot.com/2009/05/jsf-using-component-ids-in-data-table.html

however i intend to have a simpler implementation, rather than TLD function or facelets like the author did.

does anyone have any thoughts ?

thanks,

dzh

A: 

however this returns mappedidentifier_table:mappedidentifier_Update instead of mappedidentifier_table:1:mappedidentifier_Update

This will happen if you resolve the clientId outside the context of a row. The row context is set up at each stage of the lifecycle by the UIData control.

It might also happen if you're using immediate evaluation instead of deferred evaluation in your EL expressions - ${} instead of #{}.

As an aside, and as noted in the article, that lookup algorithm will only work if the component identifier is unique to the view; the spec says it need only be unique to the NamingContainer; this need not be a problem if you are careful about using unique component IDs on your page.

McDowell