I have the CommandLink/CommandButton which is an element of the column in the dataTable. The dataTable is integrated with the lazy model. My code (not exactly my, because this is the primefaces showcase example) works perfect when the number of records in the table is divisible by the page size. For example the page size is 5 and the number of records is 60. But, when the number of records is 61, then when I reach the last record in the table, the action listener for every button is not called. I've tried to change p:commandlink to h:commandbutton/p:commandbuton. I've tried all the stackoverflow tips related to use update="#form" or immediate="true" or disable ajax requests by ajax="false", but the result is the same. For me it looks like a problem with dataTable rendering. Please look at the source code. This example is based on the primefaces showcase, I've added only a new column (this one with the commandlink).
xhtml page:
<h:form id="form">
<p:dataTable styleClass="test-class" id="data" var="car" value="#{tableBean.lazyModel}" scrollable="true" liveScroll="true" scrollRows="5" scrollHeight="200" lazy="true" >
<p:column headerText="Model">
<h:outputText value="#{car.model}" />
</p:column>
<p:column headerText="Year">
<h:outputText value="#{car.year}" />
</p:column>
<p:column headerText="Manufacturer">
<h:outputText value="#{car.manufacturer}" />
</p:column>
<p:column headerText="Color">
<h:outputText value="#{car.color}" />
</p:column>
<p:column headerText="Color">
<p:commandLink value="Test"
actionListener="#{tableBean.buttonListener()}" />
</p:column>
</p:dataTable>
</h:form>
datatable lazy model:
public class MyLazyModel extends LazyDataModel<Car> {
private List<Car> datasource;
public MyLazyModel(List<Car> datasource) {
this.datasource = datasource;
}
#Override
public Car getRowData(String rowKey) {
for(Car car : datasource) {
if(car.getModel().equals(rowKey))
return car;
}
return null;
}
#Override
public Object getRowKey(Car car) {
return car.getModel();
}
#Override
public List<Car> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String,String> filters) {
//rowCount
int dataSize = datasource.size();
this.setRowCount(dataSize);
//paginate
if(dataSize > pageSize) {
try {
return datasource.subList(first, first + pageSize);
}
catch(IndexOutOfBoundsException e) {
return datasource.subList(first, first + (dataSize % pageSize));
}
}
else {
return datasource;
}
}
}
DataTable bean:
#ManagedBean
#ViewScoped
public class TableBean {
private LazyDataModel<Car> lazyModel;
private Car selectedCar;
private List<Car> cars;
public TableBean() {
populateRandomCars(cars, 60);
lazyModel = new MyLazyModel(cars);
}
public void setSelectedCar(Car selectedCar) {
this.selectedCar = selectedCar;
}
public LazyDataModel<Car> getLazyModel() {
return lazyModel;
}
Related
I'm trying to get selected values from a selectCheckboxMenu, but always the selection list is empty. this's my jsf form:
<h:form id="form">
<p:dataTable id="singleDT" var="user" value="#{roleBean.users}"
rowKey="#{roleBean.users}" rows="12" paginator="true"
rowsPerPageTemplate="12,15,22" paginatorPosition="bottom"
emptyMessage="Aucun compte présent." reflow="true"
editable="false" selectionMode="single">
<p:column headerText="Login" filterBy="#{user.username}">
<h:outputText value="#{user.username}" />
</p:column>
<p:column headerText="Nom" filterBy="#{user.lastname}">
<h:outputText value="#{user.lastname}" />
</p:column>
<p:column headerText="Prénom" filterBy="#{user.firstName}">
<h:outputText value="#{user.firstName}" />
</p:column>
<p:column headerText="Email" filterBy="#{user.emal}">
<h:outputText value="#{user.emal}" />
</p:column>
<p:column headerText="Affécter Roles">
<p:selectCheckboxMenu id="menu" value="#{roleBean.rolesselected}"
label="Roles"
filter="false" filterMatchMode="startsWith"
panelStyle="width:135px" converter="#{roleconvertor}" immediate="true" >
<f:selectItems value="#{roleBean.roles}" var="n"
itemValue="#{n}" itemLabel="#{n.description}"
itemDescription="#{n.rolename}" />
</p:selectCheckboxMenu>
</p:column>
<p:column width="90">
<p:commandButton styleClass="ui-yelbutton" immediate="true" process="#form" value="Valider"
title="Remove"
ajax="true" action="#{roleBean.addrole(user)}" />
</p:column>
</p:dataTable>
</h:form>
Here's the managedBean related. when I run the jsf page I show the list of value and I can check it. also tne converter was worked but when I try to test a size of selectedrole it's always 0.
public class RoleBean implements Serializable {
#Autowired
UserCatalogueService userservice;
#Autowired
Roleservice roleservice;
List< Role> roles;
List<UserCatalogue> users ;
private static final long serialVersionUID = 1L;
String notification;
private List<Role> rolesselected = new ArrayList<Role>();
#PostConstruct
public void init() {
roles=roleservice.findAll();
}
public List<Role> getRolesselected() {
return rolesselected;
}
public void setRolesselected(List<Role> rolesselected) {
this.rolesselected = rolesselected;
}
public List<UserCatalogue> getUsers() {
List<UserCatalogue> users= userservice.findAll();
List<UserCatalogue> users1= userservice.findAll();
users1.clear();
for(int i=0; i< users.size(); i++)
{
if(users.get(i).getRoles().size()==0)
{
System.out.println(users.get(i).getFirstName()+ "est un nouvel utilisateur");
//users.remove(i);
users1.add(users.get(i));
}
}
return users1;
}
public String getNotification() {
notification=getUsers().size()+" Alerts";
return notification;
}
public void setNotification(String notification) {
this.notification = notification;
}
public void setUsers(List<UserCatalogue> users) {
this.users = users;
}
public List<Role> getRoles() {
return roleservice.findAll();
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
public void addrole( UserCatalogue user)
{
System.out.println("the size of list is "+rolesselected.size());
}
}
Try to change rolesselected from List to array using the []
I have a problem with using the setCommand() on a DefaultMenuItem in a p:megaMenu.
I want that when I click on an item in buttonTables.jsf the function afficherTable() will be excuted and redirect me to affichageTable.jsf. The problem is when I run the project my megaMenu filled, and when I click on an item, it redirect me to the other page, but the fuction afficherTable() passed in setCommand does not run. So my datatable in the other page is empty. In the console of eclipse I don't have any error. Thank you.
My bean:
public class MonBean implements Serializable{
private static final long serialVersionUID = -5773011533863117274L;
private GestionTableImpl gestionTable;
private Table table;
private List<Colonne> columns;
private DefaultMenuModel megaModel;
public void afficherTable(ActionEvent event){
MenuItem menuItem = ((MenuActionEvent) event).getMenuItem();
String nTable = menuItem.getParams().get("tableNom").get(0);
gestionTable=new GestionTableImpl();
columns=new ArrayList<Colonne>();
columns=gestionTable.afficherTable(nTable);
}
public DefaultMenuModel listTablesMenu() {
gestionTable=new GestionTableImpl();
List<Table> mesTables=gestionTable.getTables();
megaModel = new DefaultMenuModel();
DefaultSubMenu firstSubmenu = new DefaultSubMenu("Tables");
for(int i=0;i< mesTables.size();i++){
String tableNom=mesTables.get(i).getNomTable();
DefaultMenuItem item= new DefaultMenuItem(tableNom);
item.setUrl("//AffichageTable.jsf");
item.setIcon("ui-icon-document-b");
item.setParam("tableNom",item.getValue());
item.setCommand("#{monBean.afficherTable}");
firstSubmenu.addElement(item);
megaModel.addElement(firstSubmenu);
}
return megaModel;
}
//getters and setters
public static long getSerialversionuid() {
return serialVersionUID;
}
public void setModel(DynaFormModel model) {
this.model = model;
}
public Table getTable() {
return table;
}
public void setTable(Table table) {
this.table = table;
}
public List<Colonne> getColumns() {
return columns;
}
public void setColumns(List<Colonne> columns) {
this.columns = columns;
}
public GestionTableImpl getGestionTable() {
return gestionTable;
}
public void setGestionTable(GestionTableImpl gestionTable) {
this.gestionTable = gestionTable;
}
public DefaultMenuModel getMegaModel() {
return megaModel;
}
public void setMegaModel(DefaultMenuModel megaModel) {
this.megaModel = megaModel;
}
}
This is buttonTables.jsf
<body>
<p:megaMenu autoDisplay="false" styleClass="menu-bar" style="">
<p:submenu label="Maintenance Services" icon="ui-icon-check">
<p:column>
<p:scrollPanel style="height:200px;width:250px" mode="native">
<p:menu model="#{monBean.listTablesMenu()}" />
</p:scrollPanel>
</p:column>
</p:submenu>
</p:megaMenu>
</body>
This is AffichageTable.jsf
<h:form>
<p:outputLabel value="#{monBean.table.nomTable}"/>
<p:dataTable id="tbl" var="col" value="#{monBean.columns}"
paginator="true" rows="5" style="margin-bottom:20px">
<p:column>
<f:facet name="header">
<h:outputText value="Nom colonne" />
</f:facet>
<h:outputText value="#{col.nomColonne}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Type colonne" />
</f:facet>
<h:outputText value="#{col.typeColonne}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText />
</f:facet>
<p:commandButton icon="ui-icon-pencil" />
<p:commandButton icon="ui-icon-trash" />
</p:column>
</p:dataTable>
</h:form>
I had exact the same issue. I made it work by not combining setCommand and setUrl. When I use setUrl, setCommand is not triggered, but everything else gets executed. This is not clear from the primefaces user guide...
What you can do is use the method in you command to retun the xhtml that you want to redirect something like this:
public String afficherTable(){
MenuItem menuItem = ((MenuActionEvent) event).getMenuItem();
String nTable = menuItem.getParams().get("tableNom").get(0);
gestionTable=new GestionTableImpl();
columns=new ArrayList<Colonne>();
columns=gestionTable.afficherTable(nTable);
return "/AffichageTable.jsf"
}
Can I use radio button to select a single row then edit some of data on that row then use
commandButton to submit what I edit it in that row. I'm trying to edit username cell for now as test.
this a snap of my code:
Xadmin.xhtml
<h:form id="form" enctype="multipart/form-data">
<p:growl id="msgs" showDetail="true" />
<p:dataTable id="DT" value="#{Jadmin.messages}"
var="o"
selection="#{Jadmin.selectedUser}"
rowKey="#{o.id}"
style="margin-bottom:20px">
<f:facet name="header">
Users List
</f:facet>
<p:column selectionMode="single" />
<p:column>
<f:facet name="header">
<h:outputText value="id" />
</f:facet>
<h:outputText value="#{o.id}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="username" />
</f:facet>
<p:inputText value="#{o.username}" />
</p:column>
<f:facet name="footer">
<h:commandButton value="Update" action="#{Jadmin.update}" />
<p:commandButton value="Delete"
action="#{Jadmin.delete}"
ajax="false"
update=":form:msgs"/>
</f:facet>
</p:dataTable>
JadminBeans.java
#ManagedBean(name = "Jadmin")
#SessionScoped
public class JadminBeans implements Serializable {
private static final long serialVersionUID = 1L;
private JadminController selectedUser;
List<JadminController> userslist = new ArrayList<JadminController>();
public List<JadminController> getMessages() {
System.out.println("List<JadminController> getMessages()");
userslist = JadminDAO.getAllUsers();
return userslist;
}
public void delete() {
//System.out.println(usr);
//System.out.println(itemList.remove(item)+"!!");
System.out.println("JadminBeans >> delete() ---------- id= ");
JadminDAO.deleteUser(selectedUser);
}
public JadminController getSelectedUser() {
return selectedUser;
}
public void setSelectedUser(JadminController selectedUser) {
this.selectedUser = selectedUser;
}
public void update() {
//o=(JadminBeans) objct;
JadminDAO.updateUser(selectedUser);
}
}
JadminDAO.java
public static void deleteUser(JadminController user) {
try {
PreparedStatement preparedStatement = connection.prepareStatement("delete from users where id=?");
// Parameters start with 1
preparedStatement.setLong(1, user.getId());
preparedStatement.executeUpdate();
System.out.println("JadminDAO >> deleteUser ----------");
} catch (SQLException e) {
System.out.println("JadminDAO >> deleteUser----------- SQLException :(");
e.printStackTrace();
}
}
public static void updateUser(JadminController user) {
try {
PreparedStatement preparedStatement = connection.prepareStatement("update users username=?, password=?, permission=? where username=?");
// Parameters start with 1
//System.out.println(new java.sql.Date(user.getRegisteredon().getTime()));
preparedStatement.setString(1, user.getUsername());
preparedStatement.setString(2, user.getPassword());
preparedStatement.setString(3, user.getPermission());
//preparedStatement.setDate(3, new java.sql.Date(user.getRegisteredon().getTime()));
preparedStatement.setString(4, user.getUsername());
preparedStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
JadminController.java
public class JadminController implements Serializable {
private static final long serialVersionUID = 1L;
private String username, password, permission;
private long id;
// Getters and setters.
}
If you use Editable Datatable you don't need any command button to submit what you've edited.
As shown in the same link, inside in datatable is usually used a selectOneMenu instead of radioButton for making choices.
To use input element inside your datatable don't forget to put <f:facet name="output"></f:facet> and <f:facet name="input"></f:facet>
I hope it helps.
How would it be possible to retrieve an inputText value foreach row in JSF dataTable, since this data is not an attribute in the object on which we iterate in the loop.
(here 0 as default value). I can't change the Class properties (here Product)
<h:form>
<p:dataTable var="product" value="#{bean.products}">
<p:column headerText="Id">
<h:outputText value="#{product.id}" />
</p:column>
<p:column headerText="Name">
<h:outputText value="#{product.name}" />
</p:column>
<p:column headerText="Quantity">
<h:inputText size="3" value="0" />
</p:column>
</p:dataTable>
<h:commandButton value="Submit" action="#{bean.submit}"/>
</h:form>
Bean.class
#ManagedBean
...
public void submit() {
List<Product> products = this.getProducts();
for(Product product : list) {
System.out.println("Product.name : "+ Product.name );
System.out.println("Quantity : "+ ?? );
}
}
Bind it to a Map with Product (or its ID) as key.
E.g.
private List<Product> products;
private Map<Product, Long> quantities;
#EJB
private ProductService productService;
#PostConstruct
public void init() {
products = productService.list();
quantities = new HashMap<>();
}
public void submit() {
for (Product product : products) {
Long quantity = quantities.get(product);
System.out.println("Quantity: " + quantity);
}
}
// Getters (no setters necessary for those two properties)
with
<h:inputText size="3" value="#{bean.quantities[product]}" />
You can use the visitor pattern to get the values. Something like this:
table.visitTree(VisitContext.createVisitContext(faces),
new VisitCallback() {
#Override public VisitResult visit(VisitContext vc, UIComponent component) {
if (component.equals(quantity) && quantity.getValue() != null) {
cart.addItem(
(Product) table.getRowData(),
(Integer) quantity.getValue());
}
return VisitResult.ACCEPT;
}
});
I m trying to display data in jsf datable data from the database,ans in a same row i m displaying link for Edit. Now when user will clicked on edit button then it should be inputText from outputText. Here i have done coding for that but i can't change the textbox can u please help me? Thanks in advance.
ShowData.xhtml
<h:dataTable value="#{customerdata.customerList}" var="c"
styleClass="order-table" binding="#{customerdata.dataTable}"
headerClass="order-table-header" border="1" width="100%"
rowClasses="order-table-odd-row,order-table-even-row" rows="3">
<h:column>
<h:selectBooleanCheckbox></h:selectBooleanCheckbox>
</h:column>
<h:column>
<f:facet name="heder">User ID</f:facet>
<h:inputText value="#{c.cust_id}" size="10" rendered="#{c.editable}"/>
<h:outputLabel value="#{c.cust_id}" rendered="#{not c.editable}" />
</h:column>
<h:column>
<f:facet name="heder">User Name</f:facet>
<h:inputText value="#{c.cust_name}" size="10" rendered="#{c.editable}"/>
<h:outputLabel value="#{c.cust_name}" rendered="#{not c.editable}" />
</h:column>
<h:column>
<h:commandLink value="Update" rendered="#{c.editable}" action="#{customerdata.editAction(c)}" />
<h:commandLink value="Edit" action="#{customerdata.editAction(c)}" rendered="#{not c.editable}"/>
</h:column>
<h:column>
<h:commandLink value="Delete" action="#{customerdata.deleteAction(c)}" />
</h:column>
<!-- Footer Setting -->
<f:facet name="footer">
<h:panelGroup>
<h:commandButton value="prev" action="#{customerdata.pagePrevious}"
disabled="#{customerdata.dataTable.first == 0}" />
<h:commandButton value="next" action="#{customerdata.pageNext}"
disabled="#{customerdata.dataTable.first + customerdata.dataTable.rows
>= customerdata.dataTable.rowCount}" />
</h:panelGroup>
</f:facet>
</h:dataTable>
CustomerData.java
package model;
#ManagedBean(name="customerdata")
public class CustomerData implements Serializable {
private static final long serialVersionUID = 1L;
Connection con;
Statement smt;
HtmlDataTable dataTable;
//Customer cust=new Customer();
public List<Customer> getcustomerList() throws SQLException{
//System.out.println("in getcustomerlist");
List<Customer> list= new ArrayList<Customer>();
try{
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/openid","root","root");
smt = con.createStatement();
String query="select * from jsftable";
ResultSet rs= smt.executeQuery(query);
while(rs.next()){
Customer cust = new Customer();
cust.setCust_id(rs.getInt("cust_id"));
cust.setCust_name(rs.getString("cust_name"));
cust.setHas_attachment(rs.getBoolean("has_attachment"));
System.out.println("in cusotomer data"+cust.isEditable());
//store all data into a List
list.add(cust);
}
}
catch(Exception e){
e.printStackTrace();
}
return list;
}
public void pageFirst() {
dataTable.setFirst(0);
}
public void pagePrevious() {
dataTable.setFirst(dataTable.getFirst() - dataTable.getRows());
System.out.println("Prevoius"+dataTable.getFirst());
}
public void pageNext() {
dataTable.setFirst(dataTable.getFirst() + dataTable.getRows());
System.out.println("Next"+dataTable.getFirst());
}
public void pageLast() {
int count = dataTable.getRowCount();
int rows = dataTable.getRows();
dataTable.setFirst(count - ((count % rows != 0) ? count % rows : rows));
}
public HtmlDataTable getdataTable() {
return dataTable;
}
public void setdataTable(HtmlDataTable dataTable) {
this.dataTable = dataTable;
}
public void showRow(){
System.out.println(dataTable.getRows());
}
public String deleteAction(Customer customer) throws SQLException{
//list.remove(customer);
//System.out.println(customer.cust_id);
try{
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/openid","root","root");
smt = con.createStatement();
String query="delete from jsftable where cust_id="+customer.cust_id+"";
//ResultSet rs= smt.executeQuery(query);
smt.executeUpdate(query);
}
catch(Exception e){
e.printStackTrace();
}
return null;
}
public String editAction(Customer customer) {
//list.remove(customer);
System.out.println(customer.cust_id);
customer.setEditable(true);
return null;
}
}
Customer.java
public class Customer {
int cust_id;
String cust_name;
boolean has_attachment;
boolean editable;
String edit_value;
public String getEdit_value() {
System.out.println("in getter");
return edit_value;
}
public void setEdit_value(String editvalue) {
this.edit_value = editvalue;
}
public boolean isHas_attachment() {
System.out.println("in getter of has_attach");
return has_attachment;
}
public void setHas_attachment(boolean hasAttachment) {
has_attachment = hasAttachment;
}
public int getCust_id() {
System.out.println("in getter of cust_id");
return cust_id;
}
public void setCust_id(int custId) {
cust_id = custId;
}
public String getCust_name() {
return cust_name;
}
public void setCust_name(String custName) {
cust_name = custName;
}
public boolean isEditable() {
//System.out.println("in isEditable"+editable);
return editable;
}
public void setEditable(boolean editable) {
this.editable = editable;
//System.out.println("in set editable"+editable);
}
}
To be honest, I wonder how your code works at all. It has several major flaws.
You should start with
giving your managed bean a scope, the #ViewScoped seems the most appropriate (see here)
removing the database access from the getter method. Put it inside an #PostConstruct annotated method in your bean. Getter methods can be called several times during JSF lifecycle. The #PostConstruct method only after bean construction.
closing sql statement and connection when you are done (stmt.close() and con.close())
following bean field and method naming conventions: A private field xxx has a getter getXxx and a setter setXxx (the capitalization is important)
removing datatable binding. It is not necessary here.
I recommend to go through this simple CRUD example by BalusC and adapting it for your functional requirements.
Add id tag for datatable:
<h:dataTable value="#{customerdata.customerList}" var="c" id="customerDT"
styleClass="order-table" binding="#{customerdata.dataTable}"
headerClass="order-table-header" border="1" width="100%"
rowClasses="order-table-odd-row,order-table-even-row" rows="3">
Add in your edit CommandButton update tag:
But why you don't use the inplace component using primefaces? http://www.primefaces.org/showcase-labs/ui/inplace.jsf (need a save button)