Reputation: 8879
I have a <h:dataTable>
that is populated from an Entity class and displays different products. I want to be able to click a <h:commandLink>
and edit row that the link belongs to. I have structured it mostly the same way as this nice example and article at mkyong.
The table (with some columns excluded):
<h:form>
<h:dataTable id="gnomeTable" value="#{gnome.productList}"
var="item"
styleClass="gnomeTable"
headerClass="gnomeTableHeader"
rowClasses="gnomeTableOddRow,gnomeTableEvenRow"
bgcolor="#F1F1F1" border="10" cellspacing="2"
rules="all" >
<f:facet name="header">
<h:outputText value="List of available gnomes for sale" />
</f:facet>
<h:column>
<f:facet name="header">
<h:outputText value="GnomeID" />
</f:facet>
<h:outputText value="#{item.id}"></h:outputText>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Name"/>
</f:facet>
<h:outputText value="#{item.name}" rendered="#{not item.editable}"></h:outputText>
<h:inputText value="#{item.name}" rendered="#{item.editable}"></h:inputText>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Available"/>
</f:facet>
<h:outputText value="#{item.available}" rendered="#{not item.editable}"></h:outputText>
<h:inputText value="#{item.available}" rendered="#{item.editable}"></h:inputText>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Edit"/>
</f:facet>
<h:commandLink value="Edit" action="#{gnome.editAction(item)}" rendered="#{not item.editable}" />
</h:column>
</h:dataTable>
<h:commandButton value="Save Changes" action="#{gnome.saveAction}" />
</h:form>
The Bean methods:
public String saveAction() {
for (Gnome g : productList) {
g.setEditable(false);
}
return null;
}
public String editAction(Gnome gnome) {
gnome.setEditable(true);
return null;
}
The property boolean editable
in the entity class is annotated as @Transient since it's not a part of the persistant data and I don't want the entity manager to touch it:
@Transient
private boolean editable;
I thought this would result in the boolean
variable being set to true when the Edit-button is clicked, the row re-renders with the fields now as <h:inputText>
, but nothing happens. I have debugged it and made sure that the variable is set to true, which it is.
I also found this SO question that I thought perhaps could be something similar to the problem I am experiencing. The difference though is that a refresh of the page doesn't change anything.
What am I missing?
Edit 1: In the first version of this question I had by mistake pasted the wrong code. The one that is included now is my current code, that in theory should work but does not.
Edit 2:
Initialization of productList
, where Gnome
is the entity class.
private List<Gnome> productList = new ArrayList<>();
public List<Gnome> getProductList() {
productList = gnomeFacade.findAll();
return productList;
}
public void setProductList(List<Gnome> productList) {
this.productList = productList;
}
Upvotes: 1
Views: 2387
Reputation: 8771
After testing your example, the only possible error is that you are using a RequestScoped
bean. In order to make it work, you need at least ViewScoped
or SessionScoped
. Ortherwise, the productList
changed content is lost at every requests (button action).
According to the edit, the second mistake is how data is took. You need to load your data somewhere else than getter like this :
@PostConstruct
public void init()
{
productList = gnomeFacade.findAll();
}
public List<Gnome> getProductList()
{
return productList;
}
Ortherwise, at every actions your list is reset.
Upvotes: 2