I use component binding and clientId property to find components in my javascript code, something like this:
<div data-for="@parent" data-example="#{componentBindings.myInput.clientId}" />
...
<h:inputText binding="#{componentBindings.myInput}" value="#{myBean.myProperty}" />
The only problem with this, is that jsf sometimes doesnt render the id attribute of the inputText field, so even if i know the clientId in the js code, i cant find the element as it doesnt have the id attribute on the client side.
- Whats the requirement for rendering the autogenerated id tag?
- Is there any way to make jsf render all the cliendId-s automatically? (like a faces-config entry)
- Is there any way to ensure that the clientId of an individual element is rendered (without explicitly giving it an id)?
update
i found my way around using a trick:
<span id="#{componentBindings.myInput.clientId}">
<h:inputText binding="#{componentBindings.myInput}" value="#{myBean.myProperty}" />
</span>
Although in this case there are better ways, like using name as suggested, if its not an input field you wish to render with ajax, it can be useful. For example with facets:
<!-- myComponent.xhtml -->
<!-- ... -->
<cc:interface>
<cc:facet name="someFacet" required="true" />
</cc:interface>
<cc:implementation>
<h:form>
<cc:renderFacet name="someFacet"/>
</h:form>
</cc:implementation>
<!-- page.xhtml -->
<!-- ... -->
<my:myComponent>
<f:facet name="someFacet">
<h:inputText />
<!-- ... -->
</f:facet>
</my:myComponent>
If you look at the component tree, you will see, that the facet is not nested in the form, its a direct child of the cc. So it would be nice to execute the cc with ajax:
<!-- myComponent.xhtml -->
<!-- ... -->
<cc:interface>
<cc:facet name="someFacet" required="true" />
</cc:interface>
<cc:implementation>
<h:form>
<cc:renderFacet name="someFacet"/>
<h:commandLink>
<f:ajax execute=":#{cc.clientId}" render=":#{cc.clientId}" />
</h:commandLink>
</h:form>
</cc:implementation>
but this will throw a malformed xml exception, as there is no element with the requested id on the client side. With this trick, you can make it work:
<cc:interface>
<cc:facet name="someFacet" required="true" preferred="true"/>
</cc:interface>
<cc:implementation>
<span id=#{cc.clientId}>
<h:form>
<cc:renderFacet name="someFacet"/>
<h:commandLink>
<f:ajax execute=":#{cc.clientId}" render=":#{cc.clientId}" />
</h:commandLink>
</h:form>
</span>
</cc:implementation>
I am probably not the first one who found this workaround, but i decided to share it as i didnt find it anywhere