I have a datatable on jsf page with next columns: product name, price and input field for product amount. By click on the button I should load elements from datatable to collection where product amount is more than 0(method addCups).
How to create it?
Thank you.
Managed Bean
#ManagedBean
#SessionScoped
public class OrderBean extends SpringBeanAutowiringSupport {
#Autowired
private OrderDAO orderDAO;
#Autowired
private OrderPositionDAO orderPositionDAO;
private Map<Long, Integer> selectedItems = new HashMap<>();
private Integer quantityOfCups;
public Map<Long, Integer> getSelectedItems() {
return selectedItems;
}
public void setSelectedItems(Map<Long, Integer> selectedItems) {
this.selectedItems = selectedItems;
}
public Integer getQuantityOfCups() {
return quantityOfCups;
}
public void setQuantityOfCups(Integer quantityOfCups) {
this.quantityOfCups = quantityOfCups;
}
public void addCups(Long id, Integer numOfCups){
if(numOfCups > 0){
selectedItems.put(id, numOfCups);
}
if(numOfCups == 0){
selectedItems.remove(id);
}
System.out.println(selectedItems);
}
JSF page
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:form>
<p:dataTable value="#{coffeeBean.allCoffee}" var="coffee">
<p:column>
<h:outputText value="#{coffee.coffeeName}"/>
</p:column>
<p:column>
<h:outputText value="#{coffee.costForCup}"/>
</p:column>
<p:column>
<p:inputText value="#{orderBean.quantityOfCups}"/>
</p:column>
</p:dataTable>
<h:commandButton value="add cups" action="#{orderBean.addCups(coffee.id, orderBean.quantityOfCups)}"/>
</h:form>
There are number of ways to achieve this but, with minimal modifications of your posted code, you can achieve it on following way:
add one hidden data table column with your coffee ID and define widgetVar property of data table ,
use JavaScript method to iterate through data table values and pick up coffee ID-quantity pairs,
use p:remoteCommand to send array of coffee cups as JSON string to backing bean
inside bean method parse passed JSON string and add/remove coffee cups to/from your order
Your xhtml page h:form would look like this
<h:form>
<p:dataTable widgetVar="dataTableWidget" value="#{coffeeBean.allCoffee}" var="cofee">
<p:column style="display:none">
<h:outputText value="#{coffee.id}"/>
</p:column>
<p:column headerText="name">
<h:outputText value="#{coffee.coffeeName}"/>
</p:column>
<p:column headerText="price">
<h:outputText value="#{coffee.costForCup}"/>
</p:column>
<p:column headerText="quantity">
<p:inputText/>
</p:column>
</p:dataTable>
<p:commandButton value="Add cups" type="button" onclick="collectOrderFromTable()"/>
<p:remoteCommand name="sendToOrderBean" actionListener="#{orderBean.addCups}"/>
</h:form>
with added java script
<script>
//<![CDATA[
function collectOrderFromTable() {
var coffeeCups = [];
//get table rows
var tableRows = PF('dataTableWidget').tbody[0].childNodes;
//loop through rows
for (i = 0; i < tableRows.length; i++) {
//get cells of current row
var cells = tableRows[i].cells;
//get value of hidden ID column
var id = cells[0].innerText;
//get quantity from input field
var quantity = cells[3].firstChild.value;
//add new item to array
coffeeCups.push({id: id, quantity: quantity});
}
console.log("Coffee cups", JSON.stringify(coffeeCups));
sendToOrderBean([{name: 'coffeeCups', value: JSON.stringify(coffeeCups)}]);
}
//]]>
</script>
Method addCups in your OrderBean would be like this:
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
//...
//...
public void addCups() {
//get string passed from xhtml page
String values = (String) FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("coffeCups");
//parse JSON string to List
List<CoffeeQuantity> coffeCups = (ArrayList<CoffeeQuantity>) new Gson().fromJson(values, new TypeToken<ArrayList<CoffeeQuantity>>() {}.getType());
for (CoffeeQuantity cq : coffeCups) {
System.out.println("Coffee id: " + cq.getId() + ", Quantity:" + cq.getQuantity());
if (cq.getQuantity()>0){
selectedItems.put(cq.getId(), cq.getQuantity());
}else{
selectedItems.remove(cq.getId());
}
}
}
where CoffeeQuantity is helper class to make JSON string parsing easier
public class CoffeQuantity {
int id;
Integer quantity;
//getters and setters...
}
Related
first of all, I am writing this because I am desperate. The thing is I was doing a simple Spring Boot CRUD with Primefaces. I used a bean called "carBean" to access the data in the index.xhtml file. Until there everything ok, things started to turn weird from now on. I tried to use a simple inputText to bind a text given in the UI to a property in the bean.
But I was constantly getting error 500, telling me that the property "marca" was not found in the bean, and I have checked 10000 times and everything is OK in there. So I started testing, and eventually I figured out that, the property that was working fine "carBean.cars" if I change the name to whatever I change (and obviously the methods liked to the property), It stop working. Is like the only property that works has to be named "cars". What I am missing here? Is driving me crazy, I promise this was my last resource. Thanks in advance .
carBean
package com.example.bean;
import java.io.Serializable;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.inject.Named;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import com.example.controller.CarController;
import com.example.dto.CarDTO;
import lombok.Data;
#Data
#Named("carBean")
#Scope(value = "session")
public class CarBean implements Serializable {
private static final long serialVersionUID = -8338541378806874723L;
#Autowired
CarController carController;
private List<CarDTO> cars;
private Integer id;
private String marca;
private String modelo;
private String precio;
private String bastidor;
private String potencia;
public String getMarca() {
return marca;
}
public void setMarca(String marca) {
this.marca = marca;
}
public List<CarDTO> getCars() {
cars = carController.getAllCars();
return cars;
}
public void delete(CarDTO car) {
carController.deleteCar(car.id);
cars = carController.getAllCars();
}
public void add() {
CarDTO newCar = new CarDTO();
newCar.marca = this.marca;
newCar.modelo = this.modelo;
newCar.precio = this.precio;
newCar.bastidor = this.bastidor;
newCar.potencia = this.potencia;
carController.create(newCar);
}
public String redirect() {
return "index.xhtml?faces-redirect=true";
}
}
index.xhtml
<!DOCTYPE xhtml PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:rich="http://richfaces.org/rich"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
<h3> REGISTRO DE COCHES </h3>
<h:form id = "tabla">
<div class="card">
<p:dataTable var="car" value="#{carBean.cars}">
<p:column sortBy="#{car.marca}" headerText="Marca">
<h:outputText value="#{car.marca}" />
</p:column>
<p:column sortBy="#{car.modelo}" headerText="Modelo">
<h:outputText value="#{car.modelo}" />
</p:column>
<p:column sortBy="#{car.precio}" headerText="Precio">
<h:outputText value="#{car.precio}" />
</p:column>
<p:column sortBy="#{car.bastidor}" headerText="Bastidor">
<h:outputText value="#{car.bastidor}" />
</p:column>
<p:column sortBy="#{car.potencia}" headerText="Potencia">
<h:outputText value="#{car.potencia}" />
</p:column>
<p:column>
<p:commandButton type="submit" value="Eliminar" actionListener="#{carBean.delete(car)}"
update=":tabla" />
<p:commandButton type="button" value="Editar"/>
</p:column>
</p:dataTable>
<p:commandButton value="Nuevo Coche" type="submit" oncomplete="PF('createModal').show();"/>
</div>
</h:form>
<p:dialog header="Agregar" widgetVar="createModal" id="createModal">
<h:form id="createDialog">
<p:panel header="Detalles del coche">
<h:panelGrid columns="1">
<h:outputLabel value="Marca:"/>
<h:inputText id="marca" value="#{carBean.marca}" required="true"> </h:inputText>
<h:outputLabel value="Modelo"/>
<h:inputText id="modelo"> </h:inputText>
<h:outputLabel value="Precio"/>
<h:inputText id="precio"> </h:inputText>
<h:outputLabel value="Bastidor"/>
<h:inputText id="bastidor"> </h:inputText>
<h:outputLabel value="Potencia"/>
<h:inputText id="potencia"> </h:inputText>
</h:panelGrid>
</p:panel>
</h:form>
</p:dialog>
</h:head>
</html>
Why I cannot used other property that isnĀ“t called "cars"?
Don't mess Lombok #Data autogenerated getters and setters with the one you've declared in the Bean.
You have used a getter as a method, which is not a good thing to do because it can be called multiple times, see: Why JSF calls getters multiple times
public List<CarDTO> getCars() {
cars = carController.getAllCars(); // remove business logic from getter
return cars;
}
Better initialize your private List<CarDTO> cars variable in a method annotated with #PostContruct
#PostConstruct
public void init() {
cars = carController.getAllCars();
}
For more check this example: PrimeFaces DataTable CRUD
I have a web app that uses dataTables in JSF and Primefaces features so that it may perform some more dynamic functions. In the dataTable I have rows that contain editable data. My ultimate goal is to have users be able to edit that data, click a save button, and update statements will be executed to replace what's present in the database. The problem is that at this time I do not know how to detect changes in objects within an arrayList.
I have made an example to see if anyone can solve my dilemma. Hear I have code that makes a dataTable and in the dataTable are objects from an ArrayList, each object containg three different strings. The objects are editable in the datatable. I need to be able to at minimum retrieve the ArrayList index of the object that is edited on the page. With that, I could form a new list of edited objects, and write up a method that executes a batch update on only the objects edited (an object in my scenario is equivalent to a row of data in the database) . My previous method was iterating through the entire ArrayList and updating all objects (rows), but, as the list grows large, this becomes very expensive to do. Right now I have a primefaces method onCellEdit, which tells me a previous value and the value it was changed to, but no way of pinpointing the object changed. Any help would be appreciated. The code below is set up so that it may be copied and pasted and executed.
Edit:
In my situation, I do not need to update the ArrayList. That is done automatically using the inputs on the pages and the getter and setters for the bean. What I need to do is know which objects (rows) are edited so that I may pull them aside and perform a database update, where i only update what is edited. The ArrayList is a mirror of what is in the database, but the goal here is to update the database to mirror the edited ArrayList, without having to iterate through the entire List.
Prod.java
public class Prod{
private String value1;
private String value2;
private String value3;
public String getValue1() {
return value1;
}
public void setValue1(String value1) {
this.value1 = value1;
}
public String getValue2() {
return value2;
}
public void setValue2(String value2) {
this.value2 = value2;
}
public String getValue3() {
return value3;
}
public void setValue3(String value3) {
this.value3 = value3;
}
}
Listen.java
import java.io.IOException;
import java.util.ArrayList;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import org.primefaces.event.CellEditEvent;
import com.product.inventory.beans.Prod;
#ManagedBean(name = "listen")
#SessionScoped
public class Listen{
private ArrayList<Prod> products;
boolean firstEdit = true;
public Listen(){
}
public ArrayList<Prod> setup(){
ArrayList<Prod> result = new ArrayList<>();
int numObject = 100;
int iterations = 0;
while( iterations < numObject){
Prod prod = new Prod();
prod.setValue1("A" + iterations);
prod.setValue2("B" + iterations);
prod.setValue3("C" + iterations);
result.add(prod);
iterations = iterations + 1;
}
return result;
}
public void onCellEdit(CellEditEvent event) {
Object oldValue = event.getOldValue();
Object newValue = event.getNewValue();
if(newValue != null && !newValue.equals(oldValue)) {
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO,
"Cell Changed", "Old: " + oldValue + ", New:" + newValue);
FacesContext.getCurrentInstance().addMessage(null, msg);
}
if(isFirstEdit()){
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(null, new
FacesMessage(FacesMessage.SEVERITY_INFO,
"Note", "To confirm changes, please select 'Save Changes'
or they will not be saved.") );
this.setFirstEdit(false);
}
}
public void goTest(){
System.out.println("Initializing...");
this.products = setup();
ExternalContext ec = FacesContext.getCurrentInstance()
.getExternalContext();
try {
ec.redirect(ec.getRequestContextPath()
+ "/test.xhtml");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Table Structure Made");
}
public boolean isFirstEdit() {
return firstEdit;
}
public void setFirstEdit(boolean firstEdit) {
this.firstEdit = firstEdit;
}
public ArrayList<Prod> getProducts() {
return products;
}
public void setProducts(ArrayList<Prod> products) {
this.products = products;
}
}
test.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
<h:form id="form" method="post">
<p:growl id="msgs" showDetail="true" sticky="false">
</p:growl>
<div >
<p:dataTable id="products" var="prod" value="#{listen.products}"
scrollable="true" scrollHeight="900"
editable = "true" editMode="cell" widgetVar= "prodCell">
<p:ajax event="cellEdit" listener="#{listen.onCellEdit}"
update=":form:msgs"/>
<p:column filterBy="#{prod.value1}" filterMatchMode="contains"
style = "width: 300px;" headerText="Name">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#
{prod.value1}" /></f:facet>
<f:facet name="input"><p:inputTextarea rows="2" value="#
{prod.value1}" style = "width: 96%"/></f:facet>
</p:cellEditor>
</p:column>
<p:column style = "width: 140px;" headerText="Vendor">
<p:cellEditor >
<f:facet name="output"><h:outputText value="#
{prod.value2}" /></f:facet>
<f:facet name="input">
<h:selectOneMenu value="#{prod.value2}"
style="width:100%">
<f:selectItem itemValue="Y" itemLabel="Yes"/>
<f:selectItem itemValue="N" itemLabel="No"/>
</h:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
<p:column style = "width: 275px;" headerText="Version Release">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#
{prod.value3}" /></f:facet>
<f:facet name="input"><p:inputTextarea rows="1" value="#
{prod.value3}" style = "width: 96%"/></f:facet>
</p:cellEditor>
</p:column>
<f:facet name="footer">
<div align = "left">
<p:commandButton value="post" action="#{tables.showChange}"
ajax="false"></p:commandButton>
</div>
</f:facet>
</p:dataTable>
</div>
<p:contextMenu for="products" widgetVar="pMenu">
<p:menuitem value="Edit Cell" icon="pi pi-search"
onclick="PF('prodCell').showCellEditor();return false;"/>
<p:menuitem value="Hide Menu" icon="pi pi-times"
onclick="PF('pMenu').hide()"/>
</p:contextMenu>
</h:form>
Index.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
<h:form method="post">
<h:commandButton value = "Contact Spreadsheet" ajax="false"
action="#{listen.goTest}" ></h:commandButton>
</h:form>
</h:body>
</html>
The solution you want is the PrimeFaces Extensions Sheet component for the behavior you are looking for.
Sheet fills a need that the PrimeFaces Datatable with in-cell editing does not fill. It can handle a large amount of data with editing single cells without submitting the entire sheet. Provides familiar spreadsheet navigation with TAB and SHIFT+TAB and familiar spreadsheet experience.
Features include:
Fast In-Cell Editing and Validation
Copy/Paste Range Selection including Copy/Paste and Fill
Sorting
Filtering
Fixed Columns and Rows
Resizable Columns and Rows
Movable Columns and Rows
Ajax Updates and Validation
Based on Handsontable by Handsoncode.
I would like to have a 'Show All' button for a primefaces datatable, however, I'm experiencing some trouble. Here's some test code that demostrates the problem:
Test.xhtml:
...
<h:form>
<p:selectBooleanCheckbox value="#{testBean.showAll}" itemLabel="Show All">
<p:ajax update="#form"/>
</p:selectBooleanCheckbox>
<p:panel id="test">
<p:dataTable id="values" var="value" value="#{testBean.fullList}" filteredValue="#{testBean.filteredList}" paginatorAlwaysVisible="false"
paginator="#{!testBean.showAll}" rows="#{!testBean.showAll ? 2 : null }" widgetVar="valuesTable"
emptyMessage="No records found.">
<p:column id="enum" sortBy="#{value.toString()}" filterBy="#{value.toString()}" filterMatchMode="contains">
<f:facet name="header">
<h:outputText value="Enum" />
</f:facet>
<h:outputText value ="#{value.toString()}"/>
</p:column>
<p:column id="name" sortBy="#{value.name}" filterBy="#{value.name}" filterMatchMode="contains">
<f:facet name="header">
<h:outputText value="Name" />
</f:facet>
<h:outputText value="#{value.name}" />
</p:column>
</p:dataTable>
</p:panel>
</h:form>
...
And here's TestBean.java:
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
#Named(value = "testBean")
#SessionScoped
public class TestBean implements Serializable {
public static enum Value {
ONE, TWO, THREE;
public String getName() {
return name().toLowerCase();
}
#Override
public String toString() {
return this.name();
}
}
/**
* Creates a new instance of TestBean
*/
public TestBean() {
}
private boolean showAll = false;
private List<Value> fullList = Arrays.asList(Value.values());
private List<Value> filteredList;
public boolean isShowAll() {
return showAll;
}
public void setShowAll(boolean showAll) {
this.showAll = showAll;
}
public List<Value> getFullList() {
return fullList;
}
public void setFullList(List<Value> fullList) {
this.fullList = fullList;
}
public List<Value> getFilteredList() {
return filteredList;
}
public void setFilteredList(List<Value> filteredList) {
this.filteredList = filteredList;
}
}
If I don't change tabs, the page works as expected: toggling the 'Show All' button updates the table to show all 3 values, or only two. However, if show all is not checked (only 2 rows are showing), and I click to the 2nd page of the table to view the third record, and then click 'Show All', the table does not update properly. It removes the paginator from the top of the table (as expected), but still only shows the 3rd record. And if I then uncheck show all and navigate back to the first page of the datatable, it is now broken too.
I've tried changing the ajax update statement to the id of the table, but that didn't change the results.
Am I doing something wrong? Thanks in advance.
You have to programmatically set the values you need directly on the DataTable component (I used explicit first and rows bean properties just for more readability):
<h:form>
<p:selectBooleanCheckbox value="#{testBean.showAll}" itemLabel="Show All">
<p:ajax update="#form" />
</p:selectBooleanCheckbox>
<p:panel id="test">
<p:dataTable id="values" var="value" value="#{testBean.fullList}"
filteredValue="#{testBean.filteredList}" paginatorAlwaysVisible="false"
paginator="#{!testBean.showAll}" first="#{testBean.first}" rows="#{testBean.rows}"
widgetVar="valuesTable" emptyMessage="No records found.">
<p:column id="enum" sortBy="#{value.toString()}" filterBy="#{value.toString()}"
filterMatchMode="contains">
<f:facet name="header">
<h:outputText value="Enum" />
</f:facet>
<h:outputText value="#{value.toString()}" />
</p:column>
<p:column id="name" sortBy="#{value.name}" filterBy="#{value.name}"
filterMatchMode="contains">
<f:facet name="header">
<h:outputText value="Name" />
</f:facet>
<h:outputText value="#{value.name}" />
</p:column>
</p:dataTable>
</p:panel>
</h:form>
and
#Named
#ViewScoped
public class TestBean implements Serializable
{
private static final long serialVersionUID = 1L;
public static enum Value
{
ONE, TWO, THREE;
public String getName()
{
return name().toLowerCase();
}
#Override
public String toString()
{
return name();
}
}
private boolean showAll = false;
private int first = 0;
private int rows = 2;
private List<Value> fullList = Arrays.asList(Value.values());
private List<Value> filteredList;
public boolean isShowAll()
{
return showAll;
}
public void setShowAll(boolean showAll)
{
this.showAll = showAll;
first = 0;
rows = showAll ? 0 : 2;
filteredList = null;
// get the FacesContext instance
FacesContext context = FacesContext.getCurrentInstance();
// get the current component (p:selectBooleanCheckbox)
UIComponent component = UIComponent.getCurrentComponent(context);
// find DataTable within the same NamingContainer
DataTable table = (DataTable) component.findComponent("values");
// reset first row index
table.setFirst(first);
// reset last row index
table.setRows(rows);
// reset filterd value
table.setFilteredValue(null);
}
// all other getters/setters
}
Tested on Wildfly 10.0.0.Final with JSF 2.3.0-m06 (Mojarra) and PrimeFaces 6.0.2
I had the same problem, was resolved by this steps:
Adding styleClass="all-paginator" to datatable
<p:dataTable id="values" var="value" value="#{testBean.fullList}"
filteredValue="#{testBean.filteredList}" styleClass="all-paginator"..>
Add a getter of number of all records in the controller (TestBean.java) like:
public int getRecordNumber() {
if(CollectionUtils.isEmpty(fullList)){
return 0;
}
return fullList.size();
}
Add the property of the recordNumber at the end of the datatable attribute "rowsPerPageTemplate"
<p:dataTable id="values" var="value" value="#{testBean.fullList}" filteredValue="#{testBean.filteredList}"
styleClass="all-paginator" rowsPerPageTemplate="20,30,40,50,#{testBean.recordNumber}"..>
I have this scenario that each row of datatable has checkbox.
if checkbox is selected you can delete multiple data and edit only one data.
I am successfully able to implement the delete but I got stuck with the edit cause checkedID will return the size of 0.
for the records I am following this example
below is my codes:
list.xhtml
<h:form>
<h:commandButton value="Edit" action="#{transportationController.prepareEdit()}"/>
<h:commandButton value="Delete" action="#{transportationController.delete()}">
<p:dataTable value="#{transportationController.items}" var="item" <p:column>
<f:facet name="header">
</f:facet>
<h:selectBooleanCheckbox value="#{transportationTypeController.checkedID[item.id]}"/>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Name"/>
</f:facet>
<h:outputText value="#{item.name}"/>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Remark"/>
</f:facet>
<h:outputText value="#{item.remark}"/>
</p:column>
</p:dataTable>
</h:form>
managedbean ---> transportationcontroller.java
transportationcontroller is a sessionscoped
private Map<Integer, Boolean> checkedID = new HashMap<Integer, Boolean>();
private List<Transportation> transportation = new ArrayList<Transportation>();
//setters and getters.
public List<Transportation> getCheckedTransportation() {
List<Transportation> checkedItems = new ArrayList<Transportation>();
for (Transportation trans : transportation) {
if (checkedID.get(trans.getId())) {
checkedItems.add(trans);
}
}
checkedID.clear();
return checkedItems;
}
//delete function
public String delete() {
List<Transportation> list = getCheckedTransportation();
if (list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
ejbFacade.remove(list.get(i));
}
return "List";
} else {
FacesMessage msg = new FacesMessage("Please select data", "Please select data");
JsfUtil.getCurrent().addMessage("warning-message", msg);
return null;
}
}
//edit function
public void prepareEdit() {
List<Transportation> list = getCheckedTransportation();
if (list.size() == 1) {
current = list.get(0);
} else {
FacesMessage msg = new FacesMessage("Please select at least one data", "Please select at least one data");
JsfUtil.getCurrent().addMessage("warning-message", msg);
}
}
public Transportation getSelected() {
if (current == null) {
current = new Transportation();
selectedItemIndex = -1;
}
return current;
}
entity class ---> Transportation.java
public class Transportation implements Serializable{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
//etc..
}
as I debug,the Map checkedID will always has size of 0 for edit but for delete it's working fine. I've been stuck on this for this hours now but I am not able to identify the problem as why checkedID always has size of 0 which is for edit only when it's working fine for delete. anyhelp would be appreciated. Thanks.
Note: i know that primefaces p:datatable has selectionMode="multiple"
and selections but I don't to use it. I only want to use primefaces
for it's pagination.
I have a datatable with each row having Edit and Delete buttons.
It is almost similar to http://www.primefaces.org/showcase-labs/ui/datatableRowSelectionByColumn.jsf datatable.
When I click on Edit button, if I display the selected row values using <h:outputText> the values are being displayed properly.
But If I want to display it in a input text field using <h:inputText value="#{userCRUDMB.selectedUser.userName}"/> it is throwing error saying selectedUser is resolved as null.
If I only use <h:outputText ...> then userCRUDMB.selectedUser() method is getting called properly.
But If I use <h:inputText ...> in the Dialog, the setter method is not at all getting called.
I am using Mojarra 2.1.6, PrimeFaces 3.0, Apache Tomcat7.0.32.
Any idea why it is happening?
Code: Code is same as http://www.primefaces.org/showcase-labs/ui/datatableRowSelectionByColumn.jsf, except in the dialogue box instead of displaying the text using I am trying to display in input textbox using .
public class User
{
private Integer userId;
private String userName;
private String password;
private String firstname;
private String lastname;
private String email;
private Date dob;
private String gender;
//setters/getters
}
package com.sivalabs.primefacesdemo.managedbeans;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import com.sivalabs.primefacesdemo.model.User;
import com.sivalabs.primefacesdemo.model.UserDataModel;
import com.sivalabs.primefacesdemo.service.SpringContainer;
import com.sivalabs.primefacesdemo.service.UserService;
#ManagedBean(name="UserCRUDMB")
#RequestScoped
public class UserCRUDMB
{
private UserDataModel userDataModel;
private User selectedUser;
private User[] selectedUsers;
public UserCRUDMB()
{
List<User> users = new ArrayList<User>();
for (int i = 0; i < 15; i++) {
User user = new User();
user.setUserId(i);
user.setUserName("userName"+i);
users.add(user);
}
this.userDataModel = new UserDataModel(users);
}
public UserDataModel getUserDataModel() {
return userDataModel;
}
public void setUserDataModel(UserDataModel userDataModel) {
this.userDataModel = userDataModel;
}
public User[] getSelectedUsers() {
return selectedUsers;
}
public void setSelectedUsers(User[] selectedUsers) {
this.selectedUsers = selectedUsers;
}
public User getSelectedUser() {
System.out.println("get-->"+selectedUser);
return selectedUser;
}
public void setSelectedUser(User selectedUser) {
System.out.println("set--->"+selectedUser);
this.selectedUser = selectedUser;
}
}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<body>
<h:form id="form">
<h:outputText value="PrimeFaces Demo - ShowUsers" />
<p:dataTable value="#{UserCRUDMB.userDataModel}" var="userObj"
selection="#{UserCRUDMB.selectedUsers}"
widgetVar="usersTbl">
<f:facet name="header">UserManagement</f:facet>
<p:column selectionMode="multiple"></p:column>
<p:column headerText="UserId">#{userObj.userId}</p:column>
<p:column headerText="UserName">#{userObj.userName}</p:column>
<p:column>
<p:commandButton value="Edit"
oncomplete="userEditDlg.show()"
update="form:userEditTbl">
<f:setPropertyActionListener target="#{UserCRUDMB.selectedUser}" value="#{userObj}"></f:setPropertyActionListener>
</p:commandButton>
</p:column>
<p:column>
<p:commandButton value="Delete" action="#{UserCRUDMB.deleteUser}"
update="usersTbl"
ajax="true">
<f:setPropertyActionListener target="#{UserCRUDMB.selectedUser}" value="#{userObj}"></f:setPropertyActionListener>
</p:commandButton>
</p:column>
<f:facet name="footer">
<p:commandButton value="Delete Selected" action="#{UserCRUDMB.deleteUsers}"
update="usersTbl"
ajax="true">
</p:commandButton>
</f:facet>
</p:dataTable>
<p:dialog widgetVar="userEditDlg" header="User Edit Form" hideEffect="explode"
minHeight="200" minWidth="300">
<h:panelGrid columns="2" id="userEditTbl" >
<h:outputLabel value="UserId" />
<h:outputText value="#{UserCRUDMB.selectedUser.userId}"/>
<h:outputLabel value="UserName" />
<h:inutText value="#{UserCRUDMB.selectedUser.userName}"/>
</h:panelGrid>
</p:dialog>
</h:form>
</body>
</html>
Thanks,
Siva
If you are using ajax, the request scope ist not the "ideal" scope since the bean will be recreated for each request. This can be the reason that selectedUser is null. Use the view scope (#ViewScoped) instead.