2

I'm using JSF 2.2 with Prime Faces 5.3.

I'm trying to create an html5 component with dynamic options. The goal is to create something similar to the f:selectItems tag

At the moment I've the following code(datalist.xhtml file) for the datalist tag

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns:cc="http://xmlns.jcp.org/jsf/composite">

<cc:interface></cc:interface>

<cc:implementation>
    <datalist id="#{cc.attrs.id}">
        <cc:insertChildren/>
    </datalist>
</cc:implementation>

</html>

and the following for the single option(option.xhtml file)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns:cc="http://xmlns.jcp.org/jsf/composite">

<cc:interface>
    <cc:attribute name="value" type="java.lang.String" default=""/>
    <cc:attribute name="label" type="java.lang.String" default=""/>
</cc:interface>

<cc:implementation>
    <option value="#{cc.attrs.value}" label="#{cc.attrs.label}"/>
</cc:implementation>

</html>

With this approach I can create something like this

<myTag:dataList id="test">
    <myTag:option value="1" label="label1"/>
    <myTag:option value="2" label="label2"/>
    <myTag:option value="3" label="label3"/>
</myTag:dataList>

But I need something that allows me have a dynamic list of options. I expect to write the following code(or similar)

<myTag:dataList id="test">
    <myTag:options value="#{myBean.myCollection}" var="mySingleObj" itemValue="mySingleObj.value" itemLabel="mySingleObj.label"/>
</myTag:dataList>

Can you help me? Thank you!

BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
Gavi
  • 872
  • 11
  • 25
  • Why are not using a simple h:selectOneMenu or something? You can use an ui:repeat in your cc to iterate over your options. Or you can copy some code of http://www.butterfaces.org/butterfaces-showcase/treebox.jsf to build a java component by yourself. – Lars Michaelis May 15 '16 at 08:49
  • Because, with the datalist you can use the autocomplete feature coming from html 5 – Gavi May 15 '16 at 11:18
  • So I would prefer to use ButterFaces or just copy the code. TreeBox supports lists, trees and autocomplete in a simple way. – Lars Michaelis May 15 '16 at 19:12

1 Answers1

4

You can use <ui:repeat> to iterate over a collection, here's a basic example.

<ui:repeat value="#{bean.options}" var="option">
    <option value="#{option.value}">#{option.label}</option>
</ui:repeat>

Only declaring its var in a composite gets tricky because a value expression is disallowed in var attribute. So you cannot do something like var="#{cc.attrs.var}". For that, you'd need to create a backing component, bind the <ui:repeat> to it and during postAddToView event manually evaluate the var attribute and set it on the component.

<cc:interface componentType="optionsComposite">
    <cc:attribute name="value" />
    <cc:attribute name="var" />
    <cc:attribute name="itemValue" />
    <cc:attribute name="itemLabel" />
</cc:interface>
<cc:implementation>
    <f:event type="postAddToView" listener="#{cc.init}" />

    <ui:repeat binding="#{cc.repeat}" value="#{cc.attrs.value}">
        <option value="#{cc.attrs.itemValue}">#{cc.attrs.itemLabel}</option>
    </ui:repeat>
</cc:implementation>

Note the componentType attribute of <cc:interface>. It must refer the @FacesComponent value.

@FacesComponent("optionsComposite")
public class OptionsComposite extends UINamingContainer {

    private UIComponent repeat;

    public void init() {
        repeat.getAttributes().put("var", getAttributes().get("var"));
    }

    public UIComponent getRepeat() {
        return repeat;
    }

    public void setRepeat(UIComponent repeat) {
        this.repeat = repeat;
    }

}

Now you can use it the same way as <f:selectItems>.

<myTag:dataList id="test">
    <myTag:options value="#{myBean.myCollection}" var="mySingleObj" itemValue="#{mySingleObj.value}" itemLabel="#{mySingleObj.label}" />
</myTag:dataList>

See also:

Community
  • 1
  • 1
BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
  • Hello BalusC. As usual your answers are like a charme. Just a quick question. I'm using netbeans as IDE. Why tell me that "var" is missing in the "ui:repeat" tag? It links an old JSF version? – Gavi May 16 '16 at 19:29