Passing a converter to a composite component - jsf

After some experimenting and reading up, I found the same solution as How to reference component inside a composite component when using a converter
The problem however is that I have two IDs for the valueholder and according to the documentation I could use id1,id2 as targets but that doesn't work.
This is my composite component:
<cc:interface>
<cc:attribute name="id" required="true"/>
<cc:attribute name="value" required="true"/>
<cc:attribute name="editable" required="true"/>
<cc:editableValueHolder name="element" targets="input,output"/>
</cc:interface>
<cc:implementation>
<h:inputText value="#{cc.attrs.value}" id="input" rendered="#{cc.attrs.editable}"/>
<h:outputText value="#{cc.attrs.value}" id="output" rendered="#{not cc.attrs.editable}"/>
</cc:implementation>
And this is how I intend to use the CC:
<r:inputText editable="#{registrationBean.editable}" id="dateOfBirth"
value="#{registrationBean.dateOfBirth}">
<f:convertDateTime pattern="dd-MM-yyyy" type="date" for="element" />
</r:inputText>
I originally tried inserting the converter via insertChildren and via a facet but none worked.

target needs to be space separated not comma separated
If present, this must be a space (not tab) separated list of client
ids (relative to the top level component) of components within the
section. Space is used as the delimiter for
compatibility with the IDREFS and NMTOKENS data types from the XML
Schema.
JSF2.2 docs

Related

JSF updating certain parts of a composite component

I want to develope a JSF composite component using PrimeFaces library.
Basically I want to update my composite component. I have read some SO questions about it (JSF updating a composite component or JSF Updating Composite Component (Primefaces)). But in this case I only want to update certain parts of the component.
Here is an example. My component should be a label/message/value-part of a <p:panelGrid /> to get rid of all the noise of the <p:column/>-tags.
<composite:interface>
<composite:attribute name="label" required="true" />
<composite:attribute name="value" required="true" />
</composite:interface>
<composite:implementation>
<p:column>
<!-- label -->
<p:outputLabel value="#{cc.attrs.label}" for="id_inputtext"/>
</p:column>
<p:column>
<!-- message -->
<p:message for="id_inputtext" />
</p:column>
<p:column>
<!-- inputtext -->
<p:inputText id="id_inputtext" value="#{cc.attrs.value}"/>
</p:column>
</composite:implementation>
To use this composite component I can simply put it in a panelgrid like so.
<p:panelGrid>
<p:row>
<mycomponent:columnSet id="c1" label="label" value="hello world"/>
<mycomponent:columnSet id="c2" label="label2" value="hello world2"/>
</p:row>
<p:row>
<mycomponent:columnSet id="c3" label="label3" value="hello world3"/>
<mycomponent:columnSet id="c4" label="label4" value="#{bean.someValue}"/>
</p:row>
</p:panelGrid>
In this case I can not surround the content of the component with an HTML container element like <div/> or <span/> like it is described in the above links. That would result in weird HTML because it would be within the generated table.
What I want to do in the example above is to update the <p:outputLabel/>, the <p:message/> and the <p:inputText/> from outside of the component. In a perfect world I want to update these three components independently from each other (but I guess that is even more complicated than updating all at once).
What I currently do to get this to work is kind of cheating. I create a <composite:attribute name="id" /> and give the three components fixed IDs based on a convention using the composite component id. That works but is pretty poor because using the composite component, one needs to know the inner implementation of the it.
Does anyone have an idea to solve this requirement in a nicer way?
<composite:interface>
<composite:attribute name="id" required="true" />
</composite:interface>
<composite:implementation>
<p:column>
<!-- label -->
<p:outputLabel id="#{cc.attrs.id}_label"/>
</p:column>
<p:column>
<!-- message -->
<p:message id="#{cc.attrs.id}_message" />
</p:column>
<p:column>
<!-- inputtext -->
<p:inputText id="#{cc.attrs.id}_value"/>
</p:column>
</composite:implementation>
EDIT
Thanks for the quick response in the comments.
As to the tag files: Indeed, I must admit that I avoided dealing with tag files because composite components are so much easier to handle, my bad.
Anyway, I just read some stuff, made a quick-and-dirty prototype, but came to the conclusion that (although it might be a good and proper way to use tag files in this label/message/input-situation) I have the same issue as with the composite component: To update the components inside the tag file I need to know the inner implementation of it (that is the same as described in my workaround).
I want to update the composite component/tag file from outside with a «single handle» and treat it as a black box.
If I could wish for a feature I want something to say «do the update» on the composite component/tag file. And within the composite component/tag file I can define which components should be updated if «do the update» is triggered. Something like three separate <div id="#{cc.clientId}"/> surrounding every component I want to update (which obviously is not possible like that).
Because I guess that this is nearly impossible, I would also be happy with a way to update a composite component/tag file as a whole, meaning to update every component within the black box.

Disable Autocomplete if completeMethod not set

I basically have this composite:
<cc:interface>
<cc:attribute name="value" />
<cc:attribute name="itemLabel" type="java.lang.String"/>
<cc:attribute name="itemValue" />
<cc:attribute name="completeMethod" method-signature="java.util.List oncomplete(java.lang.String))"/>
</cc:interface>
<cc:implementation>
<p:autoComplete
value="#{cc.attrs.value}"
completeMethod="#{cc.attrs.completeMethod}"
var="#{cc.attrs.var}"
itemLabel="#{cc.attrs.itemLabel}"
itemValue="#{cc.attrs.itemValue}"
pt:readonly="#{empty cc.getValueExpression('completeMethod')}" />
</cc:implementation>
I want to make sure that autocomplete is readonly when completeMethod is not defined. Doing this, it always returns true. I guess it is a problem about build/render time. I quote:
"Passthrough elements" is a JSF 2.2 specific term for declaring JSF
components as "plain" HTML5 elements which should be automatically
converted to real JSF components during view build time, when an
"identifying attribute" is present in the plain HTML5 markup.
Is there a way to work this around?

Reference dynamic Id in JSF composite components

I've been having some trouble to reference Id with composite components in JSF like the example:
`<composite:interface>
<composite:attribute name="id" required="true"/>
</composite:interface>
<composite:implementation>
<h:inputText id="#{cc.attrs.id}" value="Any"
</composite:implementation>
`
And when I try to pass the Id as param, I can't reference it from a "for" for example from an outputLabel, it seems this kind of composite components in JSF does not support dynamic Ids, what is the solution for it?
Thanks in advance.

how to awoid duplication ajax call in composite component

May be I make a fundamental mistake about jsf 2.2 specification, if so I would like to learn the correct solution of my problem. I use mojarra 2.2.9 immplementation, primemafaces 5.0.
I have a composite component with input, which always process on change event:
<cc:interface>
<cc:attribute name="value" type="java.lang.String" required="true"/>
<cc:clientBehavior name="change" event="change" targets="input"/>
</cc:interface>
<cc:implementation>
<span id="#{cc.clientId}">
<p:inputText value="#{cc.attrs.value}">
<p:ajax update="#this"/>
</p:inputText>
/* some ather component */
</span>
</cc:implementation>
And now in some cases I want to use additional listener and update some component outside cc, like clientBehavior solution:
<my:inp value="#{bean.value}">
<p:ajax event="change" listener="#{bean.listener}" update="someComponentOnPage" process="#this">
</my:inp>
Using that solution, I have 2 ajax call on 1 change event: first inside cc, second outside. Is there a solution to call ajax only once (if exist clientBehavior then not use ajax that inside)?
P.S.: sorry for my english...

Passing markup via composite components attributes

Is there a way to pass markup (in opposite to plain text) via composite
component's attributes? Simply <composite:insertChildren> won't suffice,
since the component rely on distinct text parameters. Passing tags via
attributes as described in Include sub-element inside JSF 2.0 component does not work (invalid attribute content).
You need to declare it as <cc:facet> and render it as <cc:renderFacet>:
<cc:interface>
<cc:facet name="foo" />
</cc:interface>
<cc:implementation>
<cc:renderFacet name="foo" />
</cc:implementation>
This way you can specify it using <f:facet>:
<my:composite>
<f:facet name="foo">
<p>Some <strong>HTML</strong> markup.</p>
</f:facet>
</my:composite>

Resources