Search code examples
javaxpagesjavabeans

Trying to bind a multi-value field to a managed Java bean in XPages


I have developed a simply 'Configuration' custom control that has several fields bound to a managed Java bean. It all works really well, except for the multi-value field. That works fine IF I provide more than one value in the field. If I only supply ONE value, it fails.

The Java bean contains...

private Vector<String> acctTypes;

... and the getters/setters...

public void setAcctTypes ( Vector<String> content ) {this.acctTypes = content;} 
public Vector<String> getAcctTypes() {return acctTypes;}

In the custom control, I bind the field to the bean...

<xp:inputText id="inputAcctTypes" title="Account Types" value="#{config.acctTypes}"
multipleTrim="true" multipleSeparator=";">
</xp:inputText>

That totally fails if a single value is entered into the field. I tried making it a textarea as well, with no success...

<xp:inputTextarea id="inputAcctTypes" title="Account Types"
value="#{config.acctTypes}" rows="5" multipleTrim="true">
<xp:this.multipleSeparator><![CDATA[#{javascript:"\n"}]]></xp:this.multipleSeparator>
</xp:inputTextarea>

Forgive my ignorance... I know that XPages returns a string value when a single value is entered in a multi-value field, but for the life of me I can't figure out how to accommodate for that when binding to a managed bean.

Can anyone tell me where I'm going wrong here?


Solution

  • Use a converter:

    <xp:inputText id="inputText1" value="#{config.acctTypes}">
        <xp:this.converter>
            <xp:convertList delimiter=";" />
        </xp:this.converter>
    </xp:inputText>
    

    The converter provided by the framework is not "perfect", in the sense that it will convert an input empty value to a 1 value List where that value is "". From a certain perspective it makes sense but it might not be what you want. Otherwise you can extend or create your own converter in order to get what you want.

    This approach is best practice. You want your controller to receive the "treated" value instead of changing your method param to an all-you-can-eat object and then attempt to parse it accordingly. As much as it's possible the bean should be agnostic regarding how the data was converted from the POST phase. You achieve that with converters, that's their job.

    The benefits are several: you have cleaner code and you can get (use) the value elsewhere without having to cast it (suppressing warnings in the case of lists) any time you need it.