Edit row using Radio button and commandButton - 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.

Related

Edit row in PrimeFaces dataTable does not update object

With a PrimeFaces dataTable I try to edit a row. But when I click on the 'Save Row' button, the old value is send to the bean.
I tried to copy the database object to a normal pojo, but still the old value is send to the bean.
I use PrimeFaces 12
XHTML:
<h:form id="form">
<p:growl id="msgs" showDetail="true"/>
<div class="container-fluid">
<h1><h:outputText value="#{txt['rider.title']}"/></h1>
<p:dataTable id="dt_riders" class="table table-striped" value="#{riderView.allRiders}"
var="rider" editable="true">
<p:ajax event="rowEdit" listener="#{riderView.onRowEdit}" update=":form:msgs"/>
<p:ajax event="rowEditCancel" listener="#{riderView.onRowCancel}" update=":form:msgs"/>
<p:column headerText="#{txt['rider.header.id']}">
<h:outputText value="#{rider.id}"/>
</p:column>
<p:column headerText="#{txt['rider.header.name']}">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{rider.name}"/>
</f:facet>
<f:facet name="input">
<p:inputText id="nameInp" value="#{rider.name}"/>
</f:facet>
</p:cellEditor>
</p:column>
<!-- and a few more -->
<p:column>
<p:rowEditor editTitle="Edit Row" cancelTitle="Cancel Edit" saveTitle="Save Row"/>
</p:column>
</p:dataTable>
</div>
</h:form>
The bean:
#ViewScoped
#Named("riderView")
public class RiderView implements Serializable {
private final RiderEjb riderEjb;
private final SecurityOfficer securityOfficer;
public RiderView() {
this(null, null);
}
#Inject
public RiderView(RiderEjb riderEjb, SecurityOfficer securityOfficer) {
this.riderEjb = riderEjb;
this.securityOfficer = securityOfficer;
}
public List<Rider> getAllRiders() {
return riderEjb.findAll(securityOfficer.getTeam());
}
public void onRowEdit(RowEditEvent<Rider> event) {
FacesMessage msg = new FacesMessage("Rider Edited", String.valueOf(event.getObject().getName()));
FacesContext.getCurrentInstance().addMessage(null, msg);
riderEjb.addOrUpdate(event.getObject());
}
public void onRowCancel(RowEditEvent<Rider> event) {
FacesMessage msg = new FacesMessage("Edit Cancelled", String.valueOf(event.getObject().getName()));
FacesContext.getCurrentInstance().addMessage(null, msg);
}
}
The Java object (getters and setters are generated by Lombok):
#Entity
#Getter
#Setter
public class Rider extends AbstractEntity {
#Id
private Long id;
private String name;
private Double weight;
private String gpxNames;
}
The problem was the method getAllRiders(). That calls the bean to gather the riders from the database. I changed it to retrieve all those riders from the database in a new #PostConstruct init() method.
Thanks to Jasper de Vries, I used the primefaces-test to pinpoint the problem.

getting null row key after using primefaces filter

When i am not using filter in primefaces datatable and try to select row then for example press edit it working well and takes the selected row.but when i use primefaces filter and then select the filtered row then edit
i got org.primefaces.model.SelectableDataModel when selection is enabled exception.
i know that mean i have a null row key but i don't know why.i am using a valid row key(id) the primary key of the datatable and when i use the debug i found that it get the id two times in the failure case,first time it got the right filtered id and the second time it get null id.
my question why it gets the rowkey id two times which get the null in the second time and cause the exception
<h:body>
<h:form prependId="false" id="growlForm">
<p:growl id="growl" showDetail="false" />
</h:form>
<h:form id="dataForm">
<p:panel id="ingerdientsTable">
<f:facet name="header">
<h:outputText value="Standard Food List" />
</f:facet>
<p:dataTable id="ingedientsTable" widgetVar="ingedientsTable" var="ingerdients" resizableColumns="true"
selectionMode="single" selection="#{mealBean.selectedStandardIngerdients}"
rowKey="#{ingerdients.getId()}" value="#{mealBean.allIngerdients}" rowsPerPageTemplate="5,10,25,50" rows="20"
paginator="true" style="padding-top:10px;padding-bottom:10px" tableStyle="table-layout: auto"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown} ">
<p:column headerText="Food Type" filterBy="#{ingerdients.name}"><h:outputText value="#{ingerdients.name}" /></p:column>
<p:column headerText="Protein(gm)" filterBy="#{ingerdients.containedProtiens}"><h:outputText value="#{ingerdients.containedProtiens}" /></p:column>
<p:column headerText="Carbs(gm)" filterBy="#{ingerdients.containedCarbs}"><h:outputText value="#{ingerdients.containedCarbs}" /></p:column>
<p:column headerText="Fats(gm)" filterBy="#{ingerdients.containedFats}"><h:outputText value="#{ingerdients.containedFats}" /></p:column>
<p:column headerText="Total Calories" filterBy="#{ingerdients.totalCalories}"><h:outputText value="#{ingerdients.totalCalories}" /></p:column>
<p:column styleClass="action-column">
<f:facet name="header">
<h:outputText value="Actions" />
</f:facet>
<p:commandButton id="addToMeal" value="Add To Meal" icon="ui-icon-create" update="addToMealDialog"
action="#{mealBean.showIngerdientsToMealDialog(ingerdients)}" immediate="true"
title="Add To meal" ajax="true">
</p:commandButton>
<p:tooltip for="addToMeal" value="Add To Meal"
showEffect="fade" hideEffect="fade" />
</p:column>
</p:dataTable>
</p:panel>
public class StandardIngerdients{
#Id
#Column(name="Id")
#GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
#ManyToOne
#JoinColumn(name="FolderPathId",referencedColumnName="Id",nullable=true)
private FolderPath folderPath;
#Column(name="Name")
private String name;
#Column(name="ContainedProteins")
#NotNull
private Double containedProtiens;
#Column(name="ContainedCarbs")
#NotNull
private Double containedCarbs;
#Column(name="ContainedFats")
#NotNull
private Double containedFats;
#Column(name="TotalCalories")
#NotNull
private Double totalCalories;
#Column(name="ImageName")
private String imageName;
public Integer getId() {
return id;
}
public void setId(Integer Id) {
this.id = Id;
}
public FolderPath getFolderPath() {
return folderPath;
}
public void setFolderPath(FolderPath folderPath) {
this.folderPath = folderPath;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getContainedProtiens() {
return containedProtiens;
}
public void setContainedProtiens(Double containedProtiens) {
this.containedProtiens = containedProtiens;
}
public Double getContainedCarbs() {
return containedCarbs;
}
public void setContainedCarbs(Double containedCarbs) {
this.containedCarbs = containedCarbs;
}
public Double getContainedFats() {
return containedFats;
}
public void setContainedFats(Double containedFats) {
this.containedFats = containedFats;
}
public Double getTotalCalories() {
return totalCalories;
}
public void setTotalCalories(Double totalCalories) {
this.totalCalories = totalCalories;
}
public String getImageName() {
return imageName;
}
public void setImageName(String imageName) {
this.imageName = imageName;
}
}
I was having the same problem. The thing is I make my class to implement Serializable which guarantee the "integrity" (so to speak) of data in order not to disappear hehe... so your class would be like this:
public class StandardIngerdients implements Serializable {
you can try below code i think solve it
rowKey="#{ingerdients.id}"

primefaces selectCheckboxMenu empty selected list

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 []

setCommand on a DefaultMenuItem does not work

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"
}

How to make one column editable in a readonly ace:datatable?

I have a readonly ace:datatable composed of 4 columns
I wish to make the fourth column "Process Limit" editable in this datatable
Can i do this ?
This is the xhtml code :
<ace:dataTable value="#{bankProcessLimitManagement.bankProcessLimitBean}"
var="name" style="width: 50% !important;" id="namesTable"
rowSelectListener="#{bankProcessLimitManagement.rowSelectListener}"
rowUnselectListener="#{bankProcessLimitManagement.rowDeSelectListener}"
selectionMode="single" paginator="true" rows="10">
<ace:column headerText="LatinName">
<h:outputText value="#{name.latinName}"></h:outputText>
</ace:column>
<ace:column headerText="Arabic Name">
<h:outputText value="#{name.arabicName}"></h:outputText>
</ace:column>
<ace:column headerText="Process Type">
<h:outputText value="#{name.processType}"></h:outputText>
</ace:column>
<ace:column headerText="Process Limit">
<h:outputText value="#{name.limit}"></h:outputText>
</ace:column>
</ace:dataTable>
This is the correspondent bean:
#ManagedBean(name="bankProcessLimitManagement")
#ViewScoped
public class BankProcessLimitManagement {
// Render for the datatable
private boolean renderTable = false;
// List linked to the datatable
private List<BankProcessLimitBean> bankProcessLimitBean;
// Selected Row
private BankProcessLimitBean selectedBankProcessLimit;
public void rowSelectListener(SelectEvent event) {
selectedBankProcessLimit = (BankProcessLimitBean) event.getObject();
}
public void rowDeSelectListener(UnselectEvent event) {
selectedBankProcessLimit = null;
}
// Getters
public List<BankProcessLimitBean> getBankProcessLimitBean() { return bankProcessLimitBean; }
public boolean isRenderTable() { return renderTable; }
public BankProcessLimitBean getSelectedBankProcessLimit() { return selectedBankProcessLimit; }
// Setters
public void setRenderTable(boolean renderTable) { this.renderTable = renderTable; }
public void setBankProcessLimitBean(List<BankProcessLimitBean> bankProcessLimitBean) { this.bankProcessLimitBean = bankProcessLimitBean; }
public void setSelectedBankProcessLimit(BankProcessLimitBean selectedBankProcessLimit) { this.selectedBankProcessLimit = selectedBankProcessLimit; }
}
Thanks in advance
As said in the documentation you should do:
<ace:column headerText="Process Limit">
<ace:cellEditor>
<f:facet name="output">
<h:outputText value="#{name.limit}"/>
</f:facet>
<f:facet name="input">
<h:inputText value="#{name.limit}"/>
</f:facet>
</ace:cellEditor>
</ace:column>
You need of course to add a form wrapping your table, and to include a button or a link in order to submit the data.

Resources