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>
Related
I have a primefaces datatable which displays a list of cars. One of the columns of the datatable has a command button which when clicked opens a dialog box which displays information about the selected car. Everything works as expected until I default filter the datatable and select the command button of a filtered row. The details of the car is null in this case. How can I get the value (car object) of the selected row after filtering?
<h:form id="carView">
<h:panelGrid id="carPanelGroup" style="width:100%" styleClass="tblNowrap100pct">
`<p:dataTable value="#{carBean.carList}" var="car" id="carTbl" stripedRows="true" rendered="#{not empty carBean.carList}" showGridlines="true" styleClass="tblNowrap100pct" filteredValue="#{carBean.filteredValues}" rowKey="#{car.carId}">
<p:column headerText="Car Name" sortBy="#{car.carName}" filterBy="#{car.carName}" filterMatchMode="contains" >
<f:facet name="header">
<h:outputText value="Car Name" />
</f:facet>
<h:outputText value="#{car.carName}" />
</p:column>
<p:column headerText="Make" sortBy="#{car.make}" filterBy="#{car.make}" filterMatchMode="contains">
<f:facet name="header">
<h:outputText value="Make" />
</f:facet>
<h:outputText value="#{car.make}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Car Download" />
</f:facet>
<p:commandButton action="#{carBean.selectCar}" value="Download" styleClass="linkButton" process="#this" oncomplete="PF('carDownloadpanel').show();" update="#all">
<f:setPropertyActionListener value="#{car}" target="#{carBean.carDto}"/>
</p:commandButton>
</p:column>`
</p:dataTable>
</p:panelGrid>
</h:form>
<!-- ******** pop up -->
<p:outputPanel id = "downloadOutputPanel">
<p:dialog header="#{carBean.carDto.carName}" widgetVar="carDownloadpanel" width="500" height="400" id="dialogDetails" modal="true">
<f:facet name="header">
<h:panelGroup>
<h:outputText value="#{carBean.carDto.carName}" />
</h:panelGroup>
</f:facet>
<h:form id="carDetailView">
<p:panel>
<p:panelGrid id="carDetails" columns="2" styleClass="summaryTable"
columnClasses="colLabel, colNormalInputArea" rendered="#{not empty firmBean.firmDto}">
<h:outputText value="Car Name:" />
<h:outputText value="#{carBean.carDto.carName}" />
<h:outputText value="Firm Id:" />
<h:outputText value="#{carBean.carDto.carId}" />
</p:panelGrid>
</p:panel>
</h:form>
<h:form id="iwaInfo">
<h:panelGrid id="carReportInput" columns="2" styleClass="summaryTable" columnClasses="colLabel, colNormalInputArea">
<p:commandLink value="Download" id="downloadBtn"
action="#{carBean.downloadCar}" onclick="PF('carDownloadpanel').hide();">
</p:commandLink>
<p:commandLink value="Cancel" id="cancelBtn"
oncomplete="PF('carDownloadpanel').hide();" update=":carView:carPanelGroup" process="#parent"/>
</h:panelGrid>
</h:form>
</p:dialog>
</p:outputPanel>
Java method :
public String selectCar(){
if (this.carDto != null) {
carId = this.carDto.getCarId();
instanceId = this.carDto.getInstanceId();
if (carId!=null&&instanceId!=null){
CarDto dto = new CarDto();
List<CarDto> sLst = carService.searchCar(Long.parseLong(carId), Long.parseLong(instanceId));
if (sLst!=null&&sLst.size()>0){
dto= sLst.get(0);
}
setCarDto(dto);
}
}
return "";
}
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;
}
}
}
My web app is built on the Spring boot + JSF and Primefaces.
To update my dataTable I am using roweditor primefaces element.
Here is my dataTable:
<p:dataTable id="table" var="categoryLevel"
value="#{cardCategoryLevelController.categoryLevels}"
editable="true">
<p:ajax event="rowEdit"
listener="#{cardCategoryLevelController.onRowEdit}"
update=":categoryLevelForm:msgs" />
<p:ajax event="rowEditCancel"
listener="#{cardCategoryLevelController.onRowCancel}"
update=":categoryLevelForm:msgs" />
<p:column headerText="Id">
<h:outputText value="#{categoryLevel.id}" />
</p:column>
<p:column headerText="Category Name">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{categoryLevel.cardCategory.name}" />
</f:facet>
<f:facet name="input">
<h:selectOneMenu id="category"
value="#{categoryLevel.cardCategory}"
style="width:125px">
<f:selectItems value="#{cardCategoryLevelController.categories}"
var="category" itemLabel="#{category.name}"
itemValue="#{category}" />
<f:converter binding="#{categoryConverter}"/>
</h:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Level Name">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{categoryLevel.level.name}" />
</f:facet>
<f:facet name="input">
<h:selectOneMenu id="level"
value="#{categoryLevel.level}"
style="width:125px">
<f:selectItems value="#{cardCategoryLevelController.levels}"
var="level" itemLabel="#{level.name}" itemValue="#{level}" />
<f:converter binding="#{levelConverter}"/>
</h:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Card Drop Rate">
<h:outputText value="#{categoryLevel.cardDropRate}" />
</p:column>
<p:column headerText="Created Date">
<h:outputText value="#{categoryLevel.createdDate}">
<f:convertDateTime type="time" pattern="MM-dd-yyyy HH:mm:ss" />
</h:outputText>
</p:column>
<p:column headerText="Updated Date">
<h:outputText value="#{categoryLevel.updatedDate}">
<f:convertDateTime type="time" pattern="MM-dd-yyyy HH:mm:ss" />
</h:outputText>
</p:column>
<p:column headerText="Actions">
<p:rowEditor style="float:left; padding:5px;"/>
<p:commandButton styleClass="no-btn" icon="ui-icon-trash"
rendered="#{not empty categoryLevel}"
action="#{cardCategoryLevelController.delete(categoryLevel.id)}"
update="table">
<p:confirm header="Confirmation"
message="Are you sure you want to delete this card category level"
icon="ui-icon-alert" />
</p:commandButton>
</p:column>
</p:dataTable>
And roweditor method:
public void onRowEdit(RowEditEvent event) {
CardCategoryLevel cardCategoryLevel = (CardCategoryLevel) event.getObject();
cardCategoryLevel = cardCategoryLevelService.update(cardCategoryLevel);
if (cardCategoryLevel != null) {
FacesMessage msg = new FacesMessage("Card Category Level Edited", cardCategoryLevel.getId().toString());
FacesContext.getCurrentInstance().addMessage(null, msg);
} else {
FacesMessage msg = new FacesMessage("Such card category level already exists");
FacesContext.getCurrentInstance().addMessage(null, msg);
}
}
The problem is when I edit some dataTable row, and the update on the my db was not performed successfully, wrong values (instead of old ones) are displayed on the updated row.
How can I solved that?
Nice work around is to implement custom validator, which is called before back end logic. In case validation failed, the data table row becomes red, and appropriate message is displayed.
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.
I have been using onEdit in the p:datatable and it works fine.My data table has a pagintor and shows 5 records per page.so when I click on the onEdit in the first page event.getObject gets the changed value in the bean.Now when I go the next page the event.getObject does not work and returns the old value only.
Same with the dialog box.In the table I have a link when clicked opens a dialog box in whcih I am populating few fields with the values from the row selected.It works fine in the first page and When I navigate to other pages gives empty values.
Here is my jsf code:
<p:dataTable value="#{mybean.userList}"
var="item"
id="dataTab"
widgetVar="usersTable"
tableStyleClass="data" paginator="true" rows="5"
filteredValue="#{userController.filteredUsers}"
editable="true"
rowKey="#{item}"
>
<p:ajax event="rowEdit" listener="#{mybean.onEdit}" update=":userForm:growl" />
<p:ajax event="rowEditCancel" listener="#{mybean.onCancel}" update=":userForm:growl" />
<f:facet name="header">
<p:outputPanel>
<h:outputText value="Search all fields:" />
<p:inputText id="globalFilter" onkeyup="('usersTable').filter()" style="width:150px" />
</p:outputPanel>
</f:facet>
<p:column sortBy="#{item.firstName}" filterBy="#{item.firstName}"
filterMatchMode="startsWith">
<p:cellEditor>
<f:facet name="header">
<h:outputText value="First Name" />
</f:facet>
<f:facet name="output">
<h:outputText value="#{item.firstName}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{item.firstName}" style="width:100%"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column sortBy="#{item.lastName}" filterBy="#{item.lastName}" filterMatchMode="startsWith">
<p:cellEditor>
<f:facet name="header">
<h:outputText value="Last Name" />
</f:facet>
<p:column headerText="Update" style="width:6%">
<p:rowEditor />
</p:column>
</p:dataTable>
<p:dialog id="modalDialog"
header="Delete User?"
modal="true"
resizable="false"
draggable="false"
widgetVar="delUserConf"
>
<h:panelGrid id="display" columns="2" style="width: 150px;">
<h:outputLabel value="Firat Name" style="font-weight: bold"/>
<h:outputText value="Last Name" style="border: none"/>
</h:panelGrid>
</p:dialog>
Here is the code in my bean for the edit functionality:
public String onEdit(RowEditEvent event)
{
User user=(User)event.getObject());
user.getFirstName();
}
I did not add the link that I have in my form which pops up the dialog.Also I read that this might be because of Lazy loading and I am not sure about it.I am populating my table with a list and not the model.
Could you let me know what should I do to make it work?
maybe you should switch to SessionBean scope because the scope view is released when there are changes in the view. Try SessionBean. Also you can call from view scope any sessionbean like this, where controladorMB is a sessionbean
public void detallesPersona() {
try {
FacesContext ctx = FacesContext.getCurrentInstance();
ValueExpression vex = ctx.getApplication().getExpressionFactory().createValueExpression(ctx.getELContext(), "#{controladorMB}", ControladorMB.class);
ControladorMB gMB = (ControladorMB) vex.getValue(ctx.getELContext());
this.setSelectedPersona(gMB.getPersonaBean().detallesPersonas(this.selectedPersona.getIdPersona()));
} catch (Exception e) {
JsfUtil.addErrorMessage(e, "Error: " + e.getMessage());
}
}