3
votes

I have been playing around with composite components and I ran into something I could not figure out. Without using a composite component I would have something like this:

<h:outputText value="Some Label:"/>
<h:selectOneMenu">
  <f:selectItem itemLabel="Item 1"/>
  <f:selectItem itemLabel="Item 2"/>
  <f:selectItem itemLabel="Item 3"/>
</h:selectOneMenu>

I essentially turned that snippet into a composite component:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"  
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:composite="http://java.sun.com/jsf/composite">

  <!-- INTERFACE -->
  <composite:interface>
    <composite:attribute name="label" required="true"/>
    <composite:attribute name="options" required="true"/>      
  </composite:interface>

  <!-- IMPLEMENTATION -->          
  <composite:implementation>
    <h:outputText value="#{cc.attrs.label}"/>
    <h:selectOneMenu style="width:140px;">
        <f:selectItem value="#{cc.attrs.options}" />
    </h:selectOneMenu>  
  </composite:implementation>
</html>

Now here is where I am stumped. I know I could put the list of items I want to use in the component in a backing bean and use it like this:

<util:dropdown label="Some Label:" options="#{backingBean.list}"/>

The real question is if there is a way to pass in the options without having to use a backing bean? I guess something like:

<util:dropdown label="Some Label:" options="Item 1, Item 2, Item 3"/>

or maybe

<util:dropdown label="Some Label:" options="#{backingBean.list}">
     <f:selectItem itemLabel="Item 1"/>
     <f:selectItem itemLabel="Item 2"/>
     <f:selectItem itemLabel="Item 3"/>
</util:dropdown>

Note: obviously those two do not work or I would not be asking the question.

1

1 Answers

2
votes

The real question is if there is a way to pass in the options without having to use a backing bean? I guess something like:

<util:dropdown label="Some Label:" options="Item 1, Item 2, Item 3"/>

You can use the JSTL fn:split() to split them into a String[]. The <f:selectItems> also accepts that as value. I'd only remove the spaces around the comma in the options attribute.

xmlns:fn="http://java.sun.com/jsp/jstl/functions"
...

<h:selectOneMenu>
    <f:selectItems value="#{fn:split(cc.attrs.options, ',')}" />
</h:selectOneMenu> 

or maybe

<util:dropdown label="Some Label:">
    <f:selectItem itemLabel="Item 1"/>
    <f:selectItem itemLabel="Item 2"/>
    <f:selectItem itemLabel="Item 3"/>
</util:dropdown>

You can use <composite:insertChildren> in the composite component to declare the location where the composite component's children have to be inserted.

<h:selectOneMenu>
    <composite:insertChildren />
</h:selectOneMenu>