3

I've the below data table:

<h:dataTable var="row" value="#{myBean.listOfStrings}">
    <h:column> 
         <h:inputText value="#{row}" />
    </h:column>
</h:dataTable>

Which is tied to a List<String>:

private List<String> listOfStrings = new ArrayList<String>();

public List<String> getListOfStrings() {
    return listOfStrings;
}

public void setListOfStrings(List<String> listOfStrings) {
    this.listOfStrings = listOfStrings;
}

When I enter a value in the field and save the form it is not passing the value to the field in the list, it is setting null, what am I doing wrong here?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Shahe
  • 964
  • 2
  • 13
  • 34

1 Answers1

5

The String class is immutable. It doesn't have a setter for the instance value. The getter is in this construct basically the Object#toString() method as implicitly called by EL, which coincidentally returns the string value itself.

You need to set the changed value as a new list item instead. You can do this via the brace notation on the list whereby you pass the list index: #{myBean.listOfStrings[index]}.

So, this should do, making use of UIData#getRowIndex() as list index:

<h:dataTable binding="#{table}" value="#{myBean.listOfStrings}" var="row">
    <h:column> 
         <h:inputText value="#{myBean.listOfStrings[table.rowIndex]}" />
    </h:column>
</h:dataTable>

(note: the value expression of binding is as-is! don't bind it to a bean property)

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • What if I have more than one table on my page? The binding won't work right? – Shahe Jan 27 '14 at 11:22
  • Of course not. Just give it a different name. `binding="#{table1}"`, `binding="#{table2}"`, etc or whatever is most self-documenting, e.g. `binding="#{listOfValuesTable}"` (expect that "listOfValues" is absolutely not self-documenting, think of `binding="#{productsTable}" value="#{bean.products}"`). – BalusC Jan 27 '14 at 11:23