Question

TL;DR Is there something like composite's cc.clientId that will give me the id of a custom tag?

Details: I'd like a custom tag that will render a label, a value, and an icon. When the icon is clicked, a Bootstrap modal is supposed to open up that will edit the value.

<ui:composition>
  <div> #{field.label}: #{field.value} 
    <a class="icon-pencil" data-target="#editForm" data-toggle="modal">
  </div>
  <h:form id="editForm" class="modal hide fade" role="dialog" ...>
    ... there's an input here linked to field.value ...
  </h:form>
</ui:composition>

I can use the tag with <my:editor />. When I do so within a ui:repeat, an id is prepended to the editForm so that it renders with id j_idt104:editForm. So I need to modify the data-target to include the id.

This would be really easy with a composite component because I have access to the id via cc.clientId:

data-target="\##{cc.clientId}\:editForm"

However, I can't get it to work with a custom tag because I don't know of an EL expression (or something) that will give me access to the id. I could probably wait until after the page is loaded, then use jQuery to inspect the id and set the data-target after the fact, but I was hoping for a more pure-JSF solution.

I'm using JSF 2.1 and Bootstrap 2.3, at the moment.

Was it helpful?

Solution

Answer seems to be no. BalusC says you should replace things like custom tags with "normal" JSF components. In this case, that would mean using the composite component.

If you're deadset on using custom tag, I worked around the issue (with lots of help from the answer here) by using an index in the form's id:

I replaced the ui:repeat with a c:forEach that has access to the item's index:

<table>
<c:forEach items="#{bean.items}" var="item" varStatus="status">
  <my:editor index="#{status.index}" ... />
</c:forEach>
</table>

And in the custom tag, I used the index in the data-target:

<tr>
  <td>#{label}: #{value}</td>
  <td>
    <a data-target="\#editForm-#{index}" ... ></a>
    <h:form id="editForm-#{index}" ... >
      ...
    </h:form>
  </td>
</tr>

The only catch is that c:forEach is a build-time construct (see details in this answer), which is a problem if you need any render-time data (like if you build information up in preRenderView). If you do, then you're better off using ui:repeat with a custom component, and relying on the cc.clientId.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top