3

I want to pass a list of strings as hidden input from a jsf page to the backing bean.

The backing bean is request scoped and needs to be it.

Trying to do it this way, but it doesn't seem to work. Any ideas how this can be done in a better way?

<ui:repeat value="#{bean.strings}" var="#{string}">
    <h:inputHidden value="#{string}"/>
</ui:repeat>
JavaBeginner
  • 81
  • 1
  • 3
  • 7

1 Answers1

4

Just use a converter for the list value:

<h:inputHidden value="#{bean.strings}" converter="myStringListConverter" />

Here is a converter that converts to/from a String using @@@ as separator:

@FacesConverter("myStringListConverter")
public class StringListConverter implements Converter {

    // this is used as a regex, so choose other separator carefully
    private static final String MY_SEPARATOR = "@@@";

    @Override
    public Object getAsObject(FacesContext context, UIComponent component,
            String value) {
        if (value == null) {
            return new ArrayList<String>();
        }
        return new ArrayList<String>(Arrays.asList(value.split(MY_SEPARATOR)));
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component,
            Object value) {
        if (value == null) {
            return "";
        }
        return join((List<String>) value, MY_SEPARATOR);
    }

    /**
     * Joins a String list, src: http://stackoverflow.com/q/1751844/149872
     * 
     * @param list
     * @param conjunction
     * @return
     */
    public static String join(List<String> list, String conjunction) {
        StringBuilder sb = new StringBuilder();
        boolean first = true;
        for (String item : list) {
            if (first) {
                first = false;
            } else {
                sb.append(conjunction);
            }
            sb.append(item);
        }
        return sb.toString();
    }

}

If you are using JSF 2, this should work for you already as it is.

In case you are using JSF 1.2, you just have to drop the @FacesConverter annotation and register the converter in the faces-config.xml like so:

<converter>
    <description>Simple String List Converer</description>
    <converter-id>myStringListConverter</converter-id>
    <converter-class>com.your.package.StringListConverter</converter-class>
</converter>
JavaBeginner
  • 81
  • 1
  • 3
  • 7
Elias Dorneles
  • 22,556
  • 11
  • 85
  • 107
  • 2
    Thanks! It worked. Although i changed "return Arrays.asList(value.split(MY_SEPARATOR));" to return new ArrayList(Arrays.asList(value.split(MY_SEPARATOR))); since the return type os the former was java.util.Arrays.ArrayList and not java.util.ArrayList. So I got the UnsupportedOperationException when i tried to "add" strings to my list after the conversion. – JavaBeginner Jan 31 '13 at 15:50
  • @JavaBeginner Good catch, the return of `Arrays.asList()` is immutable! – Elias Dorneles Jan 31 '13 at 17:17