0

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.

Filou
  • 490
  • 4
  • 17
  • If you assign an ID to our composite component like `` normally the inner implementation components should already get a `c1` added to their IDs even without ``. – Selaron Mar 13 '20 at 07:24
  • 1
    Please read https://stackoverflow.com/questions/6822000/when-to-use-uiinclude-tag-files-composite-components-and-or-custom-componen Think you should use a tag file for this, not a composite component – Kukeltje Mar 13 '20 at 07:42
  • Using the prefixed id's is not weird. PrimeFaces does it for all divs/spans/real inputs etc in components as well. Ok, these are plain html things then, agreed that is a difference. And I agree, this issue is independend of tag files or composite components. But your last statement confuses me. You say you want to update the cc/tag file as a whole but your title states differently. And what do you mean by _"As far as I just googled, that is not even possible with tag files."_ in relation to updating a s a whole – Kukeltje Mar 13 '20 at 10:19
  • You could also assign classes and use PrimeFaces selectors to select the right things to update. The real full usecase is sort of relevant. – Kukeltje Mar 13 '20 at 10:33
  • Yes sorry, I can see your confusion with my wording. I stated it more precisely. I will have a look in PrimeFaces selectors. Thanks! – Filou Mar 13 '20 at 11:03

0 Answers0