0

I've made a composite component which seems to works fine if used in a "static" way but it doesn't work if I bind one of its attributes to an expression.

If I use my component like

<ez:indicadorEstadoSubsistema subSystemName="Server" status="someIntLiteral"/>

works fine but I need to use it in a more dynamic way, like

<ez:indicadorEstadoSubsistema subSystemName="Server" status="#{serverData.status}"/>.

I've read that JSTL tags run on view build time instead view rendering time, so thats maybe the reason I'm not getting the status expression bind evaluated at the right time, but I don't know how to workaround this.

My component is just an image with a tooltip. Both of them depend on the "status" attribute value.

Component

<cc:interface>
    <cc:attribute name="status" shortDescription="Represents the SubSystem status." required="true" default="1" type="java.lang.Integer"/>
    <cc:attribute name="subSystemName" required="true" type="java.lang.String"/>
</cc:interface>

<cc:implementation>
    <c:choose>
        <c:when test="#{cc.attrs.status eq 0}">
            <h:graphicImage id="icon" value="#{resource['images:delete.png']}" width="16" height="16"/>
            <c:set var="message" value="#{cc.attrs.subSystemName} subsystem doesn't responds."/>
        </c:when>
        <c:when test="#{cc.attrs.status eq 1}">
            <h:graphicImage id="icon" value="#{resource['images:delete.png']}" width="16" height="16"/>
            <c:set var="message" value="Unconsistent status."/>
        </c:when>
        <c:when test="#{cc.attrs.status eq 2}">
            <h:graphicImage id="icon" value="#{resource['images:warning.png']}" width="16" height="16"/>
            <c:set var="message" value="#{cc.attrs.subSystemName} system not working properly."/>
        </c:when>
        <c:when test="#{cc.attrs.status eq 3}">
            <h:graphicImage id="icon" value="#{resource['images:check.png']}" width="16" height="16"/>
            <c:set var="message" value="#{cc.attrs.subSystemName} system works fine."/>
        </c:when>
    </c:choose>
    <p:tooltip for="icon" value="#{message}" showEffect="fade" hideEffect="fade" />  
</cc:implementation>

Thank you.

Iván
  • 552
  • 8
  • 16
  • When do you set the value in #{serverData.status} ? – Adrian Mitev Mar 31 '14 at 10:14
  • In a method called `public void updateStatus()` which is called when the user presses a CommandButton. ` – Iván Mar 31 '14 at 10:18
  • Is this on the same page with ajax request or is performed on another page and the result of updateStatus() is navigation to the current page? – Adrian Mitev Mar 31 '14 at 10:20
  • It's called from the same page with Ajax request. – Iván Mar 31 '14 at 10:22
  • 1
    I don't think that could work, The reason is if you are using the component inside a datatable, the EL expression should be evaluated per row, but tags like c:if, c:set or c:choose work when the view is being built. You should refactor your code to use rendered property or add the condition inside an EL expression. You can use c:set to make the expression shorter if you want. – lu4242 Mar 31 '14 at 10:33
  • Yes I want to use them inside a datatable. I've tried the following pattern: ` ...` and it works well but it seems to be kinda tricky IMHO. Maybe using Composite Components it's not the correct approach in this particular case. – Iván Mar 31 '14 at 12:01

1 Answers1

2

Generally, it's not a good idea to use JSTL tags in JSF. Why don't you use <h:panelGroup>? Try something like this:

<h:panelGroup rendered="#{cc.attrs.status eq 0}">
    <h:graphicImage id="icon" value="#{resource['images:delete.png']}" width="16" height="16"/>
    <ui:param var="message" value="#{cc.attrs.subSystemName} subsystem doesn't responds."/>
</h:panelGroup>
<p:tooltip for="icon" value="#{message}" showEffect="fade" hideEffect="fade" />
Mr.J4mes
  • 9,168
  • 9
  • 48
  • 90
  • Yes it also works. The reason I didnt try something like that before is because I was looking for a more "elegant" solution. Thank you. – Iván Mar 31 '14 at 13:57
  • @Iván: I hope you've already read all the posts about why mixing is not a good idea. For example, your above component would cause `@ViewScoped` beans to be recreated on each request even on the same view. IMHO, the disadvantages may trump over the "elegant" aspect. Be careful :). – Mr.J4mes Mar 31 '14 at 14:14
  • I've read several posts about why including JSTL into JSF components is not a good idea. But I'm new at JSF and still learning lots of things about this framework. Guess I will take a pure JSF solution based on your replies. :) – Iván Mar 31 '14 at 15:11