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
Related
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;
}
}
}
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.
Iam trying to update a panel based selected data using primefaces selectonemenu and ajax listener was taken care by updating the panels.But my panel was not updated and selected item was shown at console window.That means ,The ajax call was got into managed bean.but its not updated at faces pages and mentioned my code
<p:panelGrid columns="1" style="align:center;width:80%" styleClass="companyHeaderGrid">
<p:row>
<p:column><h:outputLabel for="runobject" value="Run Object: " /></p:column>
<p:column>
<p:selectOneMenu id="selectedState" value="#{TAScheduleBean.selectedRunObjectItem}" >
<p:ajax listener="#{TAScheduleBean.changePanelState}" render="#this" update=":form:displayDailyPanel"/>
<f:selectItem itemLabel="Select One" itemValue="Select One" />
<f:selectItems value="#{TAScheduleBean.runObjectsValue}" />
</p:selectOneMenu>
</p:column>
</p:row>
<p:row id="displayDailyPanel" rendered="#{TAScheduleBean.appSelectedRunObject eq 'Daily'}">
<p:column>
<p:outputLabel value=" N days" />
<p:outputLabel value="Days=" /><p:inputText id="s"/>
</p:column>
</p:panelGrid>
I read relevant issues in the same forums and other forums also. but the issue is not resolved.How can i resolve this.Please help me
Update :-
ManagedBean
public class TAScheduleBean extends TASBean {
private String selectedRunObjectItem="";
private String appSelectedRunObject="";
TAScheduleBean(){
}
public void changePanelState(){
String methodName="changePanelState";
setPanelIsVisible(true);
TALogger.log(Logger.INFO, className,
methodName, "---------"+getSelectedRunObjectItem());
setAppSelectedRunObject(getSelectedRunObjectItem().trim());
}
}
Thanks guys.I resolved the issue.when we are selected item up to that time the row was not created because we called 'rendered' attribute.So i created panel and mentioned below code
<p:panel id="toppanel"> <------- added panel
<p:panelGrid columns="1" style="align:center;width:80%" styleClass="companyHeaderGrid">
<p:row>
<p:column><h:outputLabel for="runobject" value="Run Object: " /></p:column>
<p:column>
<p:selectOneMenu id="selectedState" value="#{TAScheduleBean.selectedRunObjectItem}" >
<p:ajax listener="#{TAScheduleBean.changePanelState}" render="#this" update="toppanel"/> <------changed
<f:selectItem itemLabel="Select One" itemValue="Select One" />
<f:selectItems value="#{TAScheduleBean.runObjectsValue}" />
</p:selectOneMenu>
</p:column>
</p:row>
<p:row id="displayDailyPanel" rendered="#{TAScheduleBean.appSelectedRunObject eq 'Daily'}">
<p:column>
<p:outputLabel value=" N days" />
<p:outputLabel value="Days=" /><p:inputText id="s"/>
</p:column>
</p:panelGrid>
</p:panel>
then its working fine.
I created xhtml page with one inputText and one commandButton component. When I clicked on button is displaying overlayPanel with pickList and one commandButton under list. I want to get all target values and put it into inputText (this component must be only one). Can you help me how to do it?
Below is xhtml code that I wrote for now:
<h:panelGrid id="displayPlayers" columns="3">
<ui:repeat value="#{pickListBean.players.target}" var="player">
<p:inputText id="input2" value="#{player.name}" />
</ui:repeat>
<p:commandButton id="overPanBtn2" value="overPanBtn2" type="button" />
</h:panelGrid>
<p:overlayPanel id="chartPanel2" for="overPanBtn2" hideEffect="fade">
<p:pickList id="pickList4" value="#{pickListBean.players}" var="player" itemLabel="#{player}" itemValue="#{player}" converter="playerConverter">
<p:column style="width:75%;">
#{player.name}
</p:column>
<p:column style="width:75%;">
#{player.number}
</p:column>
</p:pickList>
<p:commandButton id="playerSubmit4" value="Ok" update="displayPlayers" style="margin-top:5px" />
</p:overlayPanel>
I will be grateful for help.
In your case it should be something like that, you only have to follow the showcase example:
XHTML
<p:pickList id="pickList4" value="#{pickListBean.players}" var="player" itemLabel="#{player}" itemValue="#{player}" converter="playerConverter">
<p:ajax event="transfer" listener="#{pickListBean.onTransfer}" update="msg" />
<p:column style="width:75%;">
#{player.name}
</p:column>
<p:column style="width:75%;">
#{player.number}
</p:column>
</p:pickList>
BACKING BEAN
String selectedPlayerNames;
//GETTER
public void onTransfer(TransferEvent event) {
selectedPlayerNames = "";
for (Player p : players.getTarget()){
selectedPlayerNames += p.getName() + " ";
}
}
Just call the event when transfer happens, and save the targeted values into the String. Then bind this String property to a p:inputText.