6

can I pass expressions to JSF 2 passthrough-attributes? the following code is not working. expression #{country.isoCode} is not evaluated.

<h:selectOneMenu value="#{bean.selectedCountry}" styleClass="selectlist">
   <f:selectItems 
            value="#{bean.countries}" var="country"
            itemLabel="#{country.countryName}" 
            pt:data-icon="flag flag-#{country.isoCode}"/>                
</h:selectOneMenu>

I am using namespace

xmlns:pt="http://xmlns.jcp.org/jsf/passthrough"

and bootstrap-select. attribute "data-icon" is used to show an image. see:

http://silviomoreto.github.io/bootstrap-select/#data-icon

rendered output:

<i class="glyphicon flag flag-"></i> 
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Steve
  • 384
  • 1
  • 7
  • 17

1 Answers1

11

EL is basically supported/evaluated over all place in a Facelet template. Also outside tags/attributes. Even in HTML comments, where many starters then fall over. So that's not the problem.

Your particular case is, unfortunately, "by design". Before rendering the first <option> element, the <f:selectItems> is is wholly parsed only once and turned into an iterator during which all EL expressions will be evaluated. Then, the component will iterate over it while rendering <option> elements during which all passthrough attributes will be evaluated. However, as the var was already evaluated during creating the iterator, it isn't available anywhere during rendering the passthrough attributes and ultimately evaluates to an empty string.

Fixing that would require quite some changes in standard JSF implementation of <f:selectItems>. I'm not sure if JSF guys would be all ears for that, but you can always try to create an issue.

You can work around this by creating physically multiple <f:selectItem> instances during view build time, with help of <c:forEach>.

<h:selectOneMenu ...>
    <c:forEach items="#{bean.countries}" var="country">
        <f:selectItem 
            itemValue="#{country}" 
            itemLabel="#{country.countryName}" 
            pt:data-icon="flag flag-#{country.isoCode}" />   
    </c:forEach>             
</h:selectOneMenu>

See also:

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • 1
    ah, that works. i just had to to replace "value" with "items" you make my closing time beer tastes good :) thanks, also for the explanation behind! – Steve Apr 16 '15 at 14:15
  • Is there another solution @BalusC. Mixing c:forEach with h:selectOneMenu and f:selectItem causing lots of issue for me. One issue for me is that the loop much much more, like almost infinite loop. – Thang Pham Jul 20 '17 at 09:22