0

How do I retrieve clientId for a facelet included with ui:include?

For a reusable component I use this syntax: cc.clientId.

EDIT1

The question is in the context of Determine absolute id. To include the dynamic editors I use a custom include.

The source code of DynamicInclude, DynamicIncludeComponent and DynamicIncludeHandler can be found at: http://pastebin.com/5e2dgR15. I had to remove the lines that tested the src for null in getSrc method of DynamicInclude and changed getFamily to return a not null value. It is the only implementation of a dynamic include that I could find and use in my case. At this moment, I don't have the knowledge to make a better one. Having a dynamic include is crucial to my project because it is used in lots of places(@BalusC: I would love to see such component being add in OmniFaces if it's possible).

My problems with the absolute client id are related with the way the id gets generated for the <custom:include>. In my case is tabs:0:editorsGroup:4:editor3. I have seen that naming containers, such as <p:dataTable> or <p:tabView>, add a number to the id(tabs:0, editorsGroup:4). I am not sure if this custom include is 100 % a NamingContainer. DynamicIncludeComponent implements NamingContainer, but I cannot use an absolute client id as :tabs:editorsGroup:editor.

For the organizationUnit editor from Determine absolute id, I have used a workaround in the update for absolute_id_of_organization_unit. With #{eval.getAbsoluteId(cc.clientId, 'organizationUnit'), the absolute client id was calculated, after some parts of the cc.clientId have been removed.

I have tried to do the update with the help of a <p:remoteCommand>, but it didn't worked. So I have thought I could do a similar workaround as for the organizationUnit editor. For this I had to obtain the parent id, the first parameter for the getAbsoluteId method.

These are the reasons from my strange request.

Community
  • 1
  • 1
Seitaridis
  • 4,459
  • 9
  • 53
  • 85
  • I have update my question with the concrete functional requirements. – Seitaridis Feb 09 '13 at 02:40
  • Apart from the concrete question, for which I need to wrap my head around first, does this component work in MyFaces? – BalusC Feb 11 '13 at 13:23
  • I can pass the needed id to the custom include with a ``, like this: ``, but I have problems using this value in the update attribute. The error is: SEVERE: javax.faces.FacesException: Cannot find component with identifier ":form:tabs:1:editorsGroup:1:editor2:roles" referenced from "form:tabs:1:editorsGroup:1:editor2:databases:0:j_id1533934859_460afa94". – Seitaridis Feb 11 '13 at 13:28
  • If I remove the numbers that the naming containers add to the id(for example :form:tabs:editorsGroup:editor2:roles), it works. – Seitaridis Feb 11 '13 at 13:29
  • I am using PrimeFaces 3.4.2, Spring Web Flow 2.3.1 and JSF Mojarra 2.1.13. – Seitaridis Feb 11 '13 at 13:37

1 Answers1

0

I have solved the issue by creating a function similar to #{p:component(componentId)}. It addition to returning the client id, it also removes the row index information from the generated client id.

The function is defined in WEB-INF/utils like this:

... doctype ommited
<facelet-taglib xmlns="http://java.sun.com/JSF/Facelet">
    <namespace>geneous.client.jsf/utils</namespace>
    <function>
        <function-name>absolute</function-name>
        <function-class>com.acme.util.ComponentUtils</function-class>
        <function-signature>java.lang.String getAbsoluteClientId(java.lang.String)</function-signature>
    </function>
</facelet-taglib>

Inside web.xml

<context-param>
    <param-name>javax.faces.FACELETS_LIBRARIES</param-name>
    <param-value>/WEB-INF/utils/utils.taglib.xml</param-value>
</context-param>

Sample code from function:

public static String getAbsoluteClientId(String id) {
    final String clientId = removeRowIndexFromClientId(id);
    FacesContext facesContext = FacesContext.getCurrentInstance();
    final char separator = UINamingContainer.getSeparatorChar(facesContext);        
    StringBuilder idBuilder = new StringBuilder();
    idBuilder.append(separator).append(clientId);
    return idBuilder.toString();        
}

public static String removeRowIndexFromClientId(String id) {
    String clientId = findComponentClientId(id);
    FacesContext facesContext = FacesContext.getCurrentInstance();
    final char separator = UINamingContainer.getSeparatorChar(facesContext);
    final String regex = String.valueOf(separator) + "[0-9]+";
    return clientId.replaceAll(regex, "");
}

The function is used as #{<utils:absolute('componentId')>}.

Seitaridis
  • 4,459
  • 9
  • 53
  • 85