This question already has an answer here:
How to show details of current row from p:dataTable in a p:dialog and update after save
(1 answer)
Closed 6 years ago.
The following code implements a datatable inside a layout, in the datatable i added an edit button in each row
<p:dataTable id="tbl" var="person" value="#{mybean.listPersons}" >
<p:column>
<f:facet name="header">
<h:outputText value="Name " />
</f:facet>
<h:outputText value="#{person.name}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Age :" />
</f:facet>
<h:outputText value="#{person.age}" />
</p:column>
<p:column>
<p:commandButton icon="ui-icon-pencil"
oncomplete="PF('dlg1').show();" action="mybean.setSelectedPerson(person)" />
</p:column>
</p:dataTable>
When i click on the edit button, the dialog box (code below) is shown but the inputs are empty, what i wanted is to show the infos of the row in the dialog bow, i'm still a beginner, i searched everywhere... but no results
<p:dialog header="Modify" widgetVar="dlg1" >
<h:form >
<p:growl id="msgs" showDetail="true" />
<h:panelGrid id="form2" value="#{myBean.person}" var="person">
<p:outputLabel value="Name :" />
<p:inputText value="#{person.name}" />
<p:outputLabel value="Age :" />
<p:inputText value="#{person.age}" />
<p:commandButton value="Submit" action="#{myBean.modifyPerson(person)}" />
</h:panelGrid>
</h:form>
</p:dialog>
#ManagedBean
#RequestScoped
public class muBean implements Serializable{
private Person selectedPerson;
//getter and setter
public void modifyPerson(Person p) {
this.selectedPerson = p;
}
}
i would be so grateful if anyone can help, i really need this
Change the command button to the following, use an actionlistener:
<p:commandButton icon="ui-icon-pencil" update=":persondlgid" oncomplete="dlg1.show();" actionListener ="mybean.findSelectedPerson">
<f:param name="personalid" value="#{person.id}" />
<p:commandButton/>
This is the dialog, add the id property to it. Then change the value of the panel grid to selectedPerson because this corresponds to the correct object in the managedbean:
<p:dialog header="Modify" widgetVar="dlg1" id="persondlgid" >
<h:form>
<p:growl id="msgs" showDetail="true" />
<h:panelGrid id="form2" value="#{myBean.selectedPerson}" var="person">
<p:outputLabel value="Name :" />
<p:inputText value="#{person.name}" />
<p:outputLabel value="Age :" />
<p:inputText value="#{person.age}" />
<p:commandButton value="Submit" action="#{myBean.modifyPerson(person)}" />
</h:panelGrid>
</h:form>
</p:dialog>
The managed bean function should look as follows. This action listener is called when the button is clicked and it then retrieves the id of the selected person and loops through the list of persons to find the one you are looking for:
public void findSelectedPerson(ActionEvent event){
if(event.getComponent().getAttributes().get("personid") != null){
Map<String,String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
int personid = (params.get("personid")!= null) ? Integer.parseInt(params.get("personid")) : -1;
// Loop through the persons array
for(Person p : listPersons){
if(p.getId() == personid){
selectedPerson = p;
break;
}
}
}
Related
This question already has an answer here:
Ajax update/render does not work on a component which has rendered attribute
(1 answer)
Closed 7 years ago.
I have an inputText and a selectOneRadio component, when form load selectOneRadio should be hidden. When user select inputText, I want to show the selectOneRadio component. I have made the selectOneRadio hidden in #PostConstruct, which should be display on select inputText.
<h:panelGrid id="panelgrid">
<p:panel id="panel" >
<h:outputLabel value="Name: " for="name" />
<p:inputText id="name" value="#{userBean.name}" immediate="true">
<p:ajax event="onselect" update="city" listener="#{userBean.showName}" />
</p:inputText>
<p:selectOneRadio id="city" value="#{userBean.city}" layout="grid" columns="3" rendered="#{userBean.displayName}" >
<f:selectItems value="#{userBean.cities}" var="c" itemLabel="#{city}" itemValue="#{city}" />
</p:selectOneRadio>
</p:panel>
</h:panelGrid>
The bean code is like:
#PostConstruct
public void init() {
displayName = false;
}
public boolean isShowName() {
return true;
}
...
But some how this is not working. I'm using JSF2.0 with primefaces 5.2.
I found the solution.
<h:form id="frm">
<h:panelGrid id="panelgrid">
<p:panel id="panel" >
<h:outputLabel value="Name: " for="name" />
<p:inputText id="name" value="#{userBean.name}" immediate="true" onkeypress="#{userBean.showName}">
<p:ajax event="change" update="frm:panelgrid" listener="#{userBean.inputcangeeListener}" />
</p:inputText>
</p:panel>
<p:panel id="p2" rendered="#{userBean.displayName}">
<p:selectOneRadio id="city" value="#{userBean.city}" layout="grid" columns="3">
<f:selectItems value="#{userBean.cities}" var="c" itemLabel="#{city}" itemValue="#{city}" />
</p:selectOneRadio>
</p:panel>
</h:panelGrid>
</h:form>
And my managed bean looks like-
#PostConstruct
public void init() {
displayName = false;
}
public boolean isShowName(){
return displayName;
}
public void inputcangeeListener(javax.faces.event.AjaxBehaviorEvent changeEvent){
setDisplayName(true);
cities = new ArrayList<>();
cities.add("pune");
cities.add("KOL");
}
Thanks for your response.
I'm trying to update a dateTable from calendar dateSelect event.
I'm a newbie using PrimeFaces and Tomcat.
This is my code
index.xhtml
<h:body>
...
<h:form id="cites">
<p:calendar id="calendari" value="#{indexBean.calendari}" mode="inline" locale="va">
<p:ajax event="dateSelect" listener="#{indexBean.onDateSelect}" update="taulaHores"/>
</p:calendar>
<p:dataTable id="taulaHores" var="hores" value="#{indexBean.hores}"
widgetVar="taulaHores" emptyMessage="Sense resultats"
filteredValue="#{indexBean.horesFiltrades}" style="width:1000px"
selection="#{indexBean.horaSeleccionada}" rowKey="#{hores.hora}">
<p:column selectionMode="single" style="width:16px;text-align:center"/>
<p:column id="horaCol" headerText="Hora">
<h:outputText value="#{hores.hora}">
<f:convertDateTime type="time" pattern="HH:mm"/>
</h:outputText>
</p:column>
<p:column id="numeroHistoriaColBis" headerText="NHC" >
<h:outputText value="#{hores.nhc}" rendered="#{not null}" />
<h:outputText value="Lliure" rendered="#{hores.nhc eq null}" />
</p:column>
<p:column id="nomColBis" headerText="Nom" >
<h:outputText value="#{hores.nom}" rendered="#{not null}" />
<h:outputText value="" rendered="#{hores.nom eq null}" />
</p:column>
<p:column id="lliangesColBis" headerText="Llinages" >
<h:outputText value="#{hores.llinages}" rendered="#{not null}" />
<h:outputText value="" rendered="#{hores.llinages eq null}" />
</p:column>
</p:dataTable>
</h:form>
</h:body>
IndexBean.java
public IndexBean() {
omplirHores(new Date(System.currentTimeMillis()));
}
public void onDateSelect(SelectEvent event) {
omplirHores((Date)event.getObject());
}
private void omplirHores(Date dia){
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
this.hores = GenericDAO.sql("SELECT Hores.hora as hora, Hores.numeroHistoria as nhc, Persona.nom as nom, Persona.llinages as llinages " +
"FROM Hores LEFT JOIN Persona ON Hores.numeroHistoria=Persona.numeroHistoria " +
"WHERE hora>='"+dateFormat.format(dia)+" 00:00:00' AND hora<='"+dateFormat.format(dia)+" 23:59:59'" +
"ORDER BY Hores.hora ASC;");
System.out.println("llistahores " + this.hores.size());
}
Then, when index.xhtml is loaded, dataTable 'taulaHores' is filled right. The problem is when I select a date in calendar, then the rows on dataTable disappear and is not updated with the new values from sql query.
For more information, I see in the log that the size of 'hores' is right.
Please, any ideas?
Thanks in advance
Solved just removing filteredValue="#{indexBean.horesFiltrades}" property
After updating datatable you have to invoke it's client side filter() method.
<p:calendar id="calendari" value="#{indexBean.calendari}" mode="inline" locale="va">
<p:ajax event="dateSelect" listener="#{indexBean.onDateSelect}" update="taulaHores" oncomplete="PF('taulaHores').filter()"/>
</p:calendar>
So, I have a form which basically makes a team
<h:form id="AddTeam">
<p:growl id="growl" showDetail="true"></p:growl>
<table>
<tr><td><p:outputLabel for="TeamName" value="Enter New Team Name"></p:outputLabel></td><td><p:inputText style="width:100%" id="TeamName" required="true" value="#{teamMaintainanceController.teamName}"></p:inputText></td></tr>
<tr><td><p:outputLabel for="TeamDesc" value="Enter New Team's Description"></p:outputLabel></td><td><p:inputText style="width:100%" id="TeamDesc" required="true" value="#{teamMaintainanceController.teamDesc}"></p:inputText></td></tr>
<tr><td><p:outputLabel for="TeamProj" value="Assign a preexisting project"></p:outputLabel></td><td><p:selectOneMenu style="width:100%" id="TeamProj" value="#{teamMaintainanceController.teamProject}">
<f:selectItem style="width:100%" itemLabel="Select One" itemValue="" />
<f:selectItems style="width:100%" value="#{projectMaintainanceController.allProjects}"/>
</p:selectOneMenu></td></tr>
<tr><td><p:outputLabel for="teamMemb" value="Select Team Members"></p:outputLabel></td><td><!-- <p:selectCheckboxMenu id="teamMemb" value="#{teamMaintainanceController.teamMemb}">
<f:selectItems value="#{employeeMaintainanceController.possibleManagerList}"></f:selectItems>
</p:selectCheckboxMenu> --><p:button value="Select Team Members" id="teamMemb" onclick="teammembers.show();return false;"></p:button></td></tr>
<tr><td><p:commandButton id="applyBtn" value="Add" ajax="true" actionListener="#{teamMaintainanceController.addTeam}" update=":AddTeam:growl"/></td></tr>
</table>
</h:form></center>
<p:dialog header="Select Team Members" widgetVar="teammembers" modal="true">
<h:form>
<p:dataTable var="user" rowKey="#{user.id}" value="#{employeeMaintainanceController.userList_ALL}" selection="#{teamMaintainanceController.selectedUsers}" selectionMode="multiple">
<p:column headerText="id">
<h:outputText value="#{user.id}"></h:outputText>
</p:column>
<p:column headerText="First Name">
<h:outputText value="#{user.firstName}"></h:outputText>
</p:column>
<p:column headerText="Last Name">
<h:outputText value="#{user.lastName}"></h:outputText>
</p:column>
</p:dataTable>
<p:commandButton actionListener="#{teamMaintainanceController.check}" ajax="true"/>
</h:form>
</p:dialog>
Now It takes Team Name, A description, A project from the list. Then we are supposed to click on a button that opens a dialog box which has a datatable with multiple rows selection option and a submit button which will submit and save the list in a variable and then the form behind the modal box can be clicked and the entire data at once.
private List<UserDto> userList_ALL;
private UserDto selectedUsers[];
public UserDto[] getSelectedUsers() {
return selectedUsers;
}
public void setSelectedUsers(UserDto[] selectedUsers) {
System.out.println(selectedUsers[0]);
this.selectedUsers = selectedUsers;
}
public List<UserDto> getUserList_ALL() throws IOException{
return userService.getUserList();
}
public void setUserList_ALL(List<UserDto> userList_ALL) {
this.userList_ALL = userList_ALL;
}
In my addTeam method I basically do System.out.println(selectedUsers[0].getId()); which throws NULL pointer Exception.
In my check() I basically start my conversation using conversation.begin()
Retrieve the list values in #postconstruct
Solution
In order to set this thread as resolved, let me write down what i changed in order to have my code working:
Changed bean to #ViewScoped;
Alter the id of Update="" for the id of the dialog form;
After looking for the error (Cannot find component with expression.." i've re-checked the generated HTML to confirm the id and it was much longer since ther are automatically generated. After replacing the id with the automatic one, everything was ok.
Thanks to #Jaqen H'ghar for the help :)
I have this panel to update a given table columns, and I want to do this using a dialog box, populated with each column data.
This is my page:
<h:form prependId="true" id="tableForm">
<h:panelGrid columns="2" columnClasses="gridLabel, gridEntry">
<h:outputText value="Table Name: " />
<h:inputText value="#{updObj.title}" />
</h:panelGrid>
<p:dataTable var="column"
value="#{tableBean.getTableColumns(updObj)}"
id="columnsTable">
<p:column headerText="Name">
<h:outputText value="#{column.title}" />
</p:column>
<p:column headerText="Type">
<h:outputText value="#{column.type}" />
</p:column>
<p:column headerText="Size">
<h:outputText value="#{column.size}" />
</p:column>
<p:column headerText="Not null">
<p:selectBooleanCheckbox value="#{column.notNull}" />
</p:column>
<p:column headerText="Primary key">
<p:selectBooleanCheckbox value="#{column.primaryKey}" />
</p:column>
<p:column headerText="Edit column">
<p:commandButton value="Edit column"
actionListener="#{tableBean.personalmethod(column)}"
update="updateColumnDialog:updateColumnGrid" icon="ui-icon-pencil"
title="Edit this column"
oncomplete="PF('updateColumnDialog').show();" />
</p:column>
</p:dataTable>
<p:dialog id="updateColumnDialog" widgetVar="updateColumnDialog"
header="Edit Column" height="200">
<h:panelGrid columns="2" id="updateColumnGrid">
<h:outputText value="Column name: " />
<h:inputText id="updateColName"
value="#{tableBean.updatedColumnName}" />
<h:outputText value="Column type: " />
<h:selectOneMenu id="updateSelectColumnTypes"
value="#{tableBean.selectedColumnType}">
<f:selectItems value="#{tableBean.columnTypes}"
var="columnType" itemLabel="#{columnType}"
itemValue="#{columnType}" id="updateSelectColumnType" />
</h:selectOneMenu>
<h:outputText value="Size: " />
<p:spinner id="updateSize"
value="#{tableBean.updatedColumnSize}" />
<h:outputText value="Not null: " />
<p:selectBooleanCheckbox id="updateNotNull"
value="#{tableBean.updatedColumnNotNull}" />
<h:outputText value="Primary Key: " />
<p:selectBooleanCheckbox id="updatePrimaryKey"
value="#{tableBean.updatedColumnPrimaryKey}" />
</h:panelGrid>
</p:dialog>
</h:form>
TableBean:
private String updatedColumnName = "";
private String updatedColumnType = "";
private double updatedColumnSize = 0.0;
private boolean updatedColumnNotNull = false;
private boolean updatedColumnPrimaryKey = false;
private List<String> columnTypes = new ArrayList<String>();
public void personalmethod(ColumnDTO updateColumn) {
this.setUpdatedColumnName(updateColumn.getTitle());
this.setUpdatedColumnType(updateColumn.getType());
this.setUpdatedColumnSize(updateColumn.getSize());
this.setUpdatedColumnNotNull(updateColumn.isNotNull());
this.setUpdatedColumnPrimaryKey(updateColumn.isPrimaryKey());
}
public List<ColumnDto> getTableColumns(TableDTO contextTable) {
List<ColumnDto> contextTableColumns = new ArrayList<ColumnDto>();
for (ColumnDto myColumnDto: contextTable.getColumns().values()) {
contextTableColumns.add(myColumnDto);
}
return contextTableColumns;
}
From what I tried: put ID on the datagrid on the dialog, namings like <form:datagrid> and #RequestScoped but I can only have the dialog poping up, but with the form all blank.
Can you help me figuring out what's missing?
Kind regards,
Sam
You should set a property when h:commandButton is fired as explained in this article and the pass it to dialog.
As mentioned by Jaqen H'ghar, me either would switch to #ViewScoped and would use two different form and put the second one inside dialog.
Following XHTML code for primefaces datatable.
<h:panelGroup id="mode">
<p:panelGrid columns="2">
<p:panelGrid columns="2">
<p:outputLabel style="font-weight: bold;"
value="Mode Of Payments" />
<p:selectOneRadio value="#{invoiceBean.modeOfPayment}"
layout="pageDirection">
<f:ajax render="mode" />
<f:selectItem itemLabel="Cash" itemValue="Cash" />
<f:selectItem itemLabel="Cheque" itemValue="Cheque" />
</p:selectOneRadio>
<p:outputLabel value="Enter Bank Name :" />
<p:inputText value="#{invoiceBean.bankName}"
disabled="#{invoiceBean.modeOfPayment == 'Cash'}" />
<p:outputLabel value="Enter Cheque Number :" />
<p:inputText value="#{invoiceBean.chequeNumber}"
disabled="#{invoiceBean.modeOfPayment == 'Cash'}" />
<p:outputLabel value="Enter Amount :" />
<p:inputText value="#{invoiceBean.chequeAmount}" />
</p:panelGrid>
<p:panelGrid columns="1">
<p:dataTable id="transactionTable"
value="#{invoiceBean.transactions}" var="transaction">
<p:column headerText="Mode Of Payment">
<p:outputLabel value="#{transaction.modeOfPayment}" />
</p:column>
<p:column headerText="Bank Name">
<p:outputLabel value="#{transaction.bankName}" />
</p:column>
<p:column headerText="Amount">
<p:outputLabel value="#{transaction.chequeAmount}" />
</p:column>
<p:column headerText="Balance">
<p:outputLabel value="#{transaction.balance}" />
</p:column>
<p:summaryRow>
<p:column colspan="3">
<p:outputLabel value="Remaining Balance" />
</p:column>
<p:column>
<p:outputLabel value="#{transaction.balance}" />
</p:column>
</p:summaryRow>
</p:dataTable>
</p:panelGrid>
</p:panelGrid>
</h:panelGroup>
<p:commandButton value="Save New Invoice"
action="#{invoiceBean.addRow}"
update=":form:invoiceTable :form:transactionTable growl"
process="#form invoiceTable" onclick="PF('addInvoice').hide();">
<f:ajax render=":form:transactionTable" />
<f:ajax render=":form:invoiceTable" />
</p:commandButton>
Following managed beans code for transactionTable :
#PostConstruct
public void init() {
session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(true);
transactionDao = new TransactionDao();
invoiceDao = new InvoiceDao();
invoices = invoiceDao.getInvoiceData(invoiceNumber);
transactions = transactionDao.getTransactions(invoices.get(0).getId());
invoiceProductsServicesDetails = invoiceDao
.getInvoiceProductsServicesDetailDatas();
}
When I add new record in HTML table it will display in transactionTable when click on "Save New Invoice".
Its work first time properly but when I click on radio button and select "Cheque" option new data not display and its replace old data.
You're not supposed to perform business logic in getters/setters.
A normal getter/setter pair looks like this (exactly like as the average IDE would autogenerate for you):
public List<Transaction> getTransactions() {
return transactions;
}
public void setTransactions(List<Transaction> transactions) {
this.transactions = transactions;
}
You should never change them unless you really know what you're doing. In your particular case, the <p:dataTable> calls the getter on every iteration round. You're basically calling the DAO for every single row. This doesn't make sense. This has a huge performance impact if there are lots of records.
In order to preload the data for view, one of the ways is a #PostConstruct method (the bean should preferably be #ViewScoped for this kind of view):
#PostConstruct
public void init() {
transactions = transactionDao.getTransactions(invoices.get(0).getId());
}
In order to save/update the data after edit, just use the action(listener) method.
See also:
Why JSF calls getters multiple times