I have prepared just a simple example of shopping basket for the demonstration purpose only.
The XHTML page:
<p:dataTable id="cartDataTable" value="#{testManagedBean.qtyList}"
var="cart"
selection="#{testManagedBean.selectedQtyList}"
rowKey="#{cart.id}">
<p:column selectionMode="multiple" />
<p:column>
<h:outputText value="#{cart.id}"/>
</p:column>
<p:column>
<p:inputText value="#{cart.qty}"/>
</p:column>
</p:dataTable>
<p:commandButton value="Delete" process="@this cartDataTable"
actionListener="#{testManagedBean.delete}"/>
The managed bean:
@ManagedBean
@SessionScoped
public final class TestManagedBean implements Serializable
{
private List<Cart>qtyList; //Getter only.
private List<Cart>selectedQtyList; //Getter and setter.
private static final long serialVersionUID = 1L;
@PostConstruct
public void init()
{
qtyList=new ArrayList<>();
qtyList.add(new Cart(1, 1));
qtyList.add(new Cart(2, 1));
qtyList.add(new Cart(3, 2));
qtyList.add(new Cart(4, 1));
qtyList.add(new Cart(5, 3));
}
public void delete()
{
for(Cart cart:selectedQtyList) {
System.out.println(cart.getId()+" : "+cart.getQty());
}
System.out.println("Perform deletion somehow.");
}
}
This is a session scoped JSF managed bean holding a shopping cart. The class Cart
is quite intuitive with only two properties of type Integer
namely id
and qty
and a parameterized constructor.
When the given delete button is clicked, we need to set the selected rows to be deleted to the backing bean.
To set the selected rows, the process
attribute of <p:commandButton>
is set to @this
and cartDataTable
which sets the selected rows to the bean's property selectedQtyList
, when this button is pressed.
Since this a session scoped bean, if a user unknowing modifies the quantity in the cart in any row/s prior to pressing the delete button then, new value/s of quantity is/are set to list qtyList
.
This should happen only when updating the cart but certainly must not happen anymore while deleting row/s.
In real application, deletion is done in a separate view scoped bean.
If the process
attribute of <p:commandButton>
is set to @this
only (i.e process="@this"
removing cartDataTable
from this attribute) then, selected rows are not set to the managed bean property selectedQtyList
.
How to proceed with this?
As far as I understand, you basically want to prevent <p:inputText value="#{cart.qty}">
from being processed (updating the model value) when the delete button is pressed. Theoretically, it should work to only specify the selection column in the process
attribute, but unfortunately <p:dataTable>
didn't eat that. Also, immediate="true"
on the button won't help as the <p:column selectionMode>
doesn't support that.
Your best bet is making sure that rendered
attribute of the input field only evaluates true
if the delete button is not pressed or when JSF is rendering the response.
<p:inputText ... rendered="#{empty param[delete.clientId] or facesContext.renderResponse}" />
...
<p:commandButton binding="#{delete}" ... />
JSF namely won't process input components which aren't rendered. The bean scope is irrelevant in this case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With