Editing rows in p:dataTable - jsf

I try to update a datatable row with PrimeFaces 3.1.1 but it makes all values null.
public void onRowEdit(RowEditEvent event) {
Client us= (Client) event.getObject();
System.out.println("event edit"+us);
clientService.editClient( us );
FacesMessage msg = new FacesMessage("Client modifié", ((Client) event.getObject()).getName_customer());
FacesContext.getCurrentInstance().addMessage(null, msg);
}
This is my page xhtml:
<h:form>
<p:dataTable var="client" value="#{clientBean.clients}" widgetVar="clientTable" emptyMessage="No customers found with given criteria" filteredValue="#{clientBean.filteredClients}" paginator="true" rows="10" rowsPerPageTemplate="5,10,15" editable="true" id="testContainer">
<p:ajax event="rowEdit" update="#this" listener="#{clientBean.onRowEdit(event)}" />
<f:facet name="header"><p:outputPanel><h:outputText value="Recherche d'un client:" /> </p:outputPanel>
</f:facet>
<p:column filterBy="#{client.user.username}" headerText="Collaborateur" filterMatchMode="contains">
<h:outputText value="#{client.user.username}" />
</p:column>
<p:column filterBy="#{client.name_customer}" headerText="Nom" filterMatchMode="contains">
<f:facet name="output">
<h:link outcome="CustomerDetails?faces-redirect=true&includeViewParams=true" value="#{client.name_customer}" >
<f:param name="idCustomer" value="#{client.costumer_id}"></f:param>
<f:param name="nameCustomer" value="#{client.name_customer}"></f:param>
</h:link> </f:facet>
<f:facet name="input"><p:inputText value="#{client.name_customer}"/></f:facet>
</p:cellEditor>
</p:column>
<p:column filterBy="#{client.statut}" headerText="Statut" filterMatchMode="contains">

the problem is that your object Client us is null , try to display a property from your object us if is null so that will confirm that you don't get your object from your page correctly . So i suggest you to replace that :
<p:ajax event="rowEdit" update="#this" listener="#{clientBean.onRowEdit}" />
with that
<p:ajax event="rowEdit" update="#this" listener="#{clientBean.onRowEdit(event)}" />
Note that i just added the event property to onRowEdit.

Related

How to call <p:ajax> from <p:commandLink> in JSF inside Editable Datatable

I have the following code
<p:ajax id="rowEditInit" event="rowEditInit"
listener="#{assignIssueController.onEditInit}" />
<p:commandLink id="linkId" action="#{assignIssueController.initMethod}" >
<p:rowEditor>
</p:rowEditor>
</p:commandLink>
This is part of my editable datatable is there any way I can call my ajax event "rowEditInit" after commadlink is called?
Following is my Datatable
<h:form id="formId">
<p:dataTable id="dTable" var="il"
value="#{assignIssueController.issueList}" editable="true"
style="margin-bottom:20px">
<f:facet name="header">
Assign Issues
</f:facet>
<p:ajax event="rowEdit"
listener="#{assignIssueController.onRowEdit}" />
<p:ajax event="rowEditCancel"
listener="#{assignIssueController.onRowCancel}" />
<p:ajax id="rowEditInit" event="rowEditInit"
listener="#{assignIssueController.onEditInit}" />
<p:column headerText="Issue Number">
<h:outputText value="#{il.issueNumber}" />
</p:column>
<p:column headerText="Issue Discribtion">
<h:outputText value="#{il.issueDescribtion}" />
</p:column>
<p:column headerText="Assign To">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{il.assignToUserId}" id="userId" />
</f:facet>
<f:facet name="input">
<p:autoComplete id="assignUserId" multiple="true"
value="#{assignIssueController.selectedUserList}"
completeMethod="#{assignIssueController.complete}" var="usr"
itemLabel="#{usr.userId}" itemValue="#{usr}"
converter="#{userConverter}">
</p:autoComplete>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Updated By">
<h:outputText value="#{il.updatedByUserId}" />
</p:column>
<p:column headerText="Issue Type">
<h:outputText value="#{il.issueStatus}" />
</p:column>
<p:column style="display: none">
<f:facet name="output">
<h:outputText value="#{il.issueType}" />
</f:facet>
</p:column>
<p:column style="width:32px">
<p:commandLink id="linkId" action="#{assignIssueController.initMethod}">
<p:rowEditor>
</p:rowEditor>
</p:commandLink>
</p:column>
</p:dataTable>
</h:form>
And here are the methods that are called by ajax events
public void onEditInit(RowEditEvent event) {
System.out.println(event.getObject());
AssignIssueList obj = (AssignIssueList) event.getObject();
issueName = obj.getIssueNumber();
System.out.println(obj.getAssignToUserId().toString());
selectedUserList = usersBo.getUserNameList(obj.getAssignToUserId().toString());
}
public void initMethod() {
System.out.println("Hello world");
}

<p:rowEditor display new values, even update db was not performed successfully

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.

Primefaces editable datatable inserting itself on row edit?

I am trying to put together a datatable to display some company information using Primefaces and java hosted with Tomcat7. Unfortunately due to sensitive information, I cannot give specifics about the data I'm working with. My code has been modified only to change variable names to more generic ones, and to remove business logic that doesn't touch the page.
I've got just about everything working, except when I try to add a new row to my datatable, it inserts the entire table into itself at the row that I was editing. This also happens when just cancelling the edit.
This is very confusing, considering I'm only inserting an item into a List object, which is in turn being fed into the table by Primefaces.
Here is the contents of my xhtml:
<h:form id="form">
<p:growl id="msgs" showDetail="true"/>
<p:dataTable var="object" value="#{page.objectList}" id="tableName"
scrollable="false"
liveResize="true"
resizableColumns="true"
editable="true"
sortMode="multiple"
reflow="true"
paginator="true"
rows="20"
paginatorTemplate="{CurrentPageReport} {PreviousPageLink} {PageLinks} {NextPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="10,20,50,100">
<f:facet name="header">
Table Title
</f:facet>
<p:ajax event="rowEdit" listener="#{page.onRowEdit}" update=":form:msgs" />
<p:ajax event="rowEditCancel" listener="#{page.onRowCancel}" update=":form:msgs" />
<p:column headerText="col1">
<p:cellEditor>
<f:facet name="output"><h:outputText id="col1Output" value="#{object.col1item}" /></f:facet>
<f:facet name="input">
<p:inputText id="col1Input" value="#{object.col1item}" style="width:100%" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="col2">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{object.col2item}" /></f:facet>
<f:facet name="input">
<h:selectOneMenu value="#{object.col2item}" style="width:100%">
<f:selectItems value="#{object.categories}" var="col2item" itemLabel="#{col2item}" itemValue="#{col2item}" />
</h:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="col3">
<p:cellEditor>
<f:facet name="output"><h:outputText id="col3Output" value="#{object.col3item}" /></f:facet>
<f:facet name="input">
<p:inputText id="col3Input" value="#{object.col3item}" style="width:100%" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="col4">
<p:cellEditor>
<f:facet name="output"><h:outputText id="col4Output" value="$#{object.col4item}" /></f:facet>
<f:facet name="input">
<p:inputText id="col4Input" converterId="com.gvea.utilities.business.Money" value="#{object.col4item}" style="width:100%" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="col5">
<p:cellEditor>
<f:facet name="output"><h:outputText id="col5Output" value="#{object.col5item}" /></f:facet>
<f:facet name="input">
<p:inputText id="col5Input" value="#{object.col5item}" style="width:100%" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column style="width:32px">
<p:rowEditor/>
</p:column>
</p:dataTable>
</h:form>
and the onRowEdit and onRowCancel:
public void onRowEdit(RowEditEvent event) {
/*-- modify object --*/
...
objectList.add(0, newObject);
/*-- Give success or failure message --*/
}
public void onRowCancel(RowEditEvent event) {
FacesMessage msg = new FacesMessage("Edit Cancelled", "");
FacesContext.getCurrentInstance().addMessage(null, msg);
}
The objectList.add(...) is the only place where I do anything that could potentially chance the page... and I've verified that "newObject" is in fact an instance of the right class. Yet still I end up getting this:
Thanks for any help!
As it turns out, I wasn't updating the datatable on the lines:
<p:ajax event="rowEdit" listener="#{page.onRowEdit}" update=":form:msgs" />
<p:ajax event="rowEditCancel" listener="#{page.onRowCancel}" update=":form:msgs" />
simply adding form to the update line fixed my issue. Like so:
<p:ajax event="rowEdit" listener="#{page.onRowEdit}" update=":form:msgs form" />
<p:ajax event="rowEditCancel" listener="#{page.onRowCancel}" update=":form:msgs form" />

onclick client event handler in <p:commandButton> causes resubmit of page

I have strange problem with following code:-
<p:dataTable id="dataTbl_mnuItmList_id" rows="5"
paginator="true" paginatorPosition="top"
value="#{addMenuItemMB.menuItemList}" var="menuItem"
style="width:100%; height:100%">
<p:column headerText="Item Name" sortBy="itemName">
<h:outputText value="#{menuItem.itemName}" />
</p:column>
<p:column headerText="Created Date" sortBy="createdDate">
<h:outputText value="#{menuItem.createdDate}">
</h:outputText>
</p:column>
<p:column headerText="Modified Date" sortBy="modifiedDate">
<h:outputText value="#{menuItem.modifiedDate}" />
</p:column>
<p:column>
<p:commandButton id="cmdBtn_edit"
onclick="widVar_menuItem.unselectAllRows()"
update=":frm_addMnuItm_dlg:outPutPnl_addMnuItmDlg_id"
oncomplete="PF('dlg_addMnuItem_widVar').show()"
icon="ui-icon-pencil" title="Edit" value="Edit">
<f:setPropertyActionListener value="#{menuItem}"
target="#{addMenuItemMB.menuItemToEdit}" />
</p:commandButton>
</p:column>
</p:dataTable>
Following is the dataTable having widgetVar="widVar_menuItem"
<p:dataTable id="dataTbl_menuItem_id" rows="5"
paginator="true" paginatorPosition="top"
widgetVar="widVar_menuItem" editable="true" editMode="cell"
value="#{addMenuItemMB.mnuItmSpecDtlListModel}"
var="mnuItmSpecDtl" rowKey="#{mnuItmSpecDtl.id}"
selection="#{addMenuItemMB.selectedLabels}">
<f:facet name="header">
<p:outputLabel value="Specification Label" />
</f:facet>
<p:column selectionMode="multiple"
style="width:2%; display:none;" />
<p:ajax event="toggleSelect"
listener="#{addMenuItemMB.onToggleSelect}" />
<p:ajax event="cellEdit"
listener="#{addMenuItemMB.onCellEdit}" />
<p:column headerText="Label" style="width:31%">
<h:outputText value="#{mnuItmSpecDtl.labelName}" />
</p:column>
<p:column headerText="Price" style="width:25%">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{mnuItmSpecDtl.price}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{mnuItmSpecDtl.price}"
style="width:50px" />
</f:facet>
</p:cellEditor>
</p:column>
</p:dataTable>
Above code Having command button in datatable column which has the property f:setPropertyActionListener it is working fine. But when I added onclick client event handler the page get submitted and when I remove onclick attribute from command button it is working fine as expected. So my question is what is wrong with above code, or What I realized (it may be wrong) client side event handler are not property working with f:setPropertyActionListener attribute.
Please suggest me proper solution.
Thanks.

p:dialog shows empty values when when I go to the next page of the p:datatable using paginator

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());
}
}

Resources