7

I'm trying to find out if this is a JSF/EL issue or something wrong here.

Basically, I wanted to pass an item object as a ui:param to a ui:composition and have a button inside (i.e. bootstrap buttons so they're actually html links hence the use of commandLink) and have it perform an action using the item param. Here's the ui:composition item.xhtml being passed some params.

<ui:include src="comp/item.xhtml">
    <ui:param name="item" value="#{itemVM.item}"/>
    <ui:param name="desc" value="#{true}"/>
</ui:include>

Now I want this button to be a composite component "bt:button", however it seems to be having a problem resolving the "item" parameter. To to confirm this I took the commandlink out of the component and put it on the page and sure enough it worked. Furthermore if I move the bt:button outside of the ui:composition it works there too. Lastly if I change item to be a string using single quotes like 'test' it works as well (For testing purposes my action method takes an Object). Based on these 3 cases it looks as though that as the composite component is having trouble resolving the item parameter being passed in to a composition.

Here's an example of the 1st test (i.e., the composite component verses the regular JSF commandlink) inside item.xhtml:

<!- This composite component doesn't Work -->
<bt:button id="cmpBtn" active="#{user.compares[item.id]}"
           disabled="#{user.compares[item.id] != null and itemsCtr.numOfCompares >= 100}"
           styleClass="btn-item-compare btn-small"
           style="margin-bottom:5px"
           action="#{itemsCtr.compare(item)}">
    <i class="#{user.compares[item.id] != null ? 'icon-minus' : 'icon-plus'}"/>
    <h:outputText value="#{user.compares[item.id] != null ? 'Comparing' : 'Compare'}"/>
    <f:ajax render="@this"/>
</bt:button>

<!-- This regular jsf component works -->
<h:commandLink action="#{itemsCtr.compare(item)}" value="Test">
    <f:ajax render="@this"/>
</h:commandLink>

And here's my composite component definition of bt:button:

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:cc="http://java.sun.com/jsf/composite"
      xmlns:f="http://java.sun.com/jsf/core">

<cc:interface componentType="LinkComponent">
    <cc:attribute name="action" targets="button"/>
    <cc:attribute name="value" type="java.lang.String"/>
    <cc:attribute name="active" type="java.lang.Boolean"/>
    <cc:attribute name="title" type="java.lang.String"/>
    <cc:attribute name="styleClass" type="java.lang.String"/>
    <cc:attribute name="disabled" type="java.lang.Boolean"/>
    <cc:attribute name="style" type="java.lang.String"/>
</cc:interface>

<cc:implementation>
    <h:commandLink id="button" binding="#{cc.link}"
                   styleClass="btn #{cc.attrs.active ? 'active' : ''} #{cc.attrs.disabled ? 'disabled' : ''} #{cc.attrs.styleClass}"
                   title="#{cc.attrs.title}" style="#{cc.attrs.style}" disabled="#{cc.attrs.disabled}" value="#{cc.attrs.value}">
        <cc:insertChildren/>
    </h:commandLink>
</cc:implementation>
</html>

My question is this a JSF issue or is there something wrong here? Perhaps in the composite component definition?

Jordan
  • 370
  • 3
  • 13
  • Which JSF version and implementation are you currently using? – maple_shaft Sep 10 '12 at 14:28
  • I'm using Mojarra 2.1.11 – Jordan Sep 10 '12 at 14:31
  • Where does the `#{item}` come from? From a repeating component? If so, which one? – BalusC Sep 10 '12 at 14:39
  • `#{item}` comes from the `#{itemVM.item}`. ItemVM is just a ViewScoped managed bean, and no ui:repeat is used in this case. I take that property and pass it in to the item.xhtml composition using `ui:param name="item" value="#{itemVM.item}"`. I've created a item.xhtml composition because I want to reuse that jsf/html code in a few pages so by passing in item as a ui:param it allows me to do that - until I ran into this issue of course. – Jordan Sep 10 '12 at 14:52
  • 1
    This seems to be the JSF bug [JAVASERVERFACES_SPEC_PUBLIC-1223](https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1223). The SO answer [JSF Combine ui:param with composite component](http://stackoverflow.com/questions/25142072/jsf-combine-uiparam-with-composite-component) describes a workaround. – Martin Höller Jun 11 '15 at 08:20

3 Answers3

0

I had the same need as you, and made a composite component in which I inserted children with view parameters as attributes just as you did, and the value was always null, so I think it's a JSF issue.

  • Yeah, given that my 2 other approaches work just fine with ui params, my suspicion is that it is a JSF issue pertaining to composite components and the evaluation of ui params. Good to hear I'm not the only one, wished it worked though. – Jordan Sep 25 '12 at 19:02
0

try replacing

disabled="#{user.compares[item.id] != null and itemsCtr.numOfCompares >= 100}"

with

disabled="#{user.compares[item.id] != null and itemsCtr.numOfCompares ge 100}"
kleopatra
  • 51,061
  • 28
  • 99
  • 211
  • Would you mind editing your answer to make it easier to understand? – tjons Jan 02 '14 at 16:12
  • Unfortunately, this is an old project and I no longer have the test above readily available. However I fail to see how replacing the '>=' with 'ge' will make any difference here. The problem is that the 'item' parameter was not being resolved, whereas the logical evaluation itself was working fine with '>='. – Jordan Jan 05 '14 at 01:54
0

i'm not sure, but i suppose you should try replacing

#{user.compares[item.id]}

with

#{user.compares[item]['id']}
scaleSpace
  • 31
  • 2