Primefaces datatable, update row oncelledit - jsf

I have primefaces datatable and i want to update specific column or entire row on cell edit. Value in edited cell determines value in other column in the same row.
I tried to update component from onCellEdit method but no success:
String targetTypeColumn = ((DataTable)event.getSource()).getClientId(FacesContext.getCurrentInstance()) +
":" + event.getRowIndex() + ":editor";
RequestContext.getCurrentInstance().update(targetTypeColumn);
Column have cell editor:
<p:column id="tgtType" styleClass="mapDetsTblColTypeTgt" headerText="Target Type">
<p:cellEditor id="editor" rendered="...">
<f:facet name="output">
<h:outputText value="..." />
</f:facet>
<f:facet name="input">
<p:inputText value="..." styleClass="mapDetsTblInput" onselect="this.value=this.value" />
</f:facet>
</p:cellEditor>
<h:outputText value="..." rendered="!..."/>
</p:column>
Any ideas?
I don't want to update whole datatable because this is waste of time.
Edit:
I tried to update datatable during on cell edit
<p:dataTable id="mapperDetailsTable" styleClass="mapperDetailsTable" widgetVar="mapperDetailsTable"
..... >
<p:ajax event="cellEdit" listener="#{bean.onCellEdit}" update=":mapperDetailsForm:growlMapper mapperDetailsTable"
oncomplete="handleCellEdit(args);" />
......
but no effect. Next cell not updated. Is it correct what i wrote? I'm using autoComplete in edited cell so i don't have update attribute.
<p:cellEditor rendered="#{guiUtils.isEditable(mapperCtrl, fieldMapping)}">
<f:facet name="output">
<h:outputText value="#{fieldMapping.fieldNameTgt}"/>
</f:facet>
<f:facet name="input">
<p:autoComplete value="#{fieldMapping.fieldNameTgt}" completeMethod="#{mapperCtrl.dmUtils.completeTargetFields}" >
<p:ajax event="itemSelect" listener="#{mapperCtrl.action}" process="mapperDetailsTable"/>
<p:ajax event="change" listener="#{mapperCtrl.action}" process="mapperDetailsTable"/>
</p:autoComplete>
</f:facet>
</p:cellEditor>
Edit2:
I checked and value is updated on the correct element in the list.
When i used solution from this thread(reload datatable): Updating entire <p:dataTable> on complete of <p:ajax event="cellEdit">
everything is ok. So value is updated correctly but how to refresh row or cell only?
Edid 3:
I found out that i can update cell using commandButton
<p:column>
.....
<p:commandButton value="updateTgtRow" id="updateTgtRow" process="#this" ajax="true" immediate="true" update="outputType inputType"/>
</p:column>
After click in button cell is updated without reload table. But how to call click on that button after cell edit? When i added oncomplete, cell edit don't work. Cells are read only. Any idea?
<p:ajax event="cellEdit" listener="#{mapperCtrl.onCellEdit}"
process="#this" oncomplete="#(updateTgtRow).click()"/>

I solve my problem using p:commandButton component
In cell i added
<p:commandButton style="display: none" value="updateTgtRow" id="updateTgtRow" process="#this" ajax="true" immediate="true" update="outputTgtType inputTgtType"/>
It updates fields from other cells (outputTgtType and inputTgtType). In bean i call click on that button
String componentId = ((DataTable) event.getSource()).getClientId(FacesContext.getCurrentInstance()) + ":"
+ event.getRowIndex() + ":updateTgtRow";
RequestContext.getCurrentInstance().execute("document.getElementById('" + componentId + "').click()");
It looks like hack but it works. This solution update specific cells in currently edited row.

Related

How to block a single datatable cell in primefaces with blockUI

I'm creating a datatable with some some dynamically generated columns. In each of the cells of those columns, there's a button to refresh the data of that specific cell.
What I want is that the cell is blocked when the button on that cell is pressed.
Sample code:
<p:dataTable id="table" var="tableVar" value="#{tableValues}">
<p:columns id="column" var="columnVar" value="#{columnValues}">
<f:facet name="header">
<h:outputText value ="#{columnVar}"/>
</f:facet>
<h:outputText value="Some Text"/>
<p:commandButton value="Button Text"
id="button"
update="table"
actionListener="#{some.method()}"/>
<p:blockUI block="?????" trigger="button">
<p:graphicImage name="loading.gif"/>
</p:blockUI>
</p:columns>
</p:dataTable>
I don't know what should go in the block parameter to only block a cell. I also tried to just block="column", but even that wasn't blocking the column as I expected, instead it was just displaying the loading gif near the button but not blocking anything.
I have seen this question How update just specific cell in primefaces dataTable where the answers say it's not possible to specify a single cell, but it's from 2012, and the answers mention that it might get fixed on a later version.
After playing a bit, I found a solution.
You can define a <p:outputpanel id="cell"></p:outputpanel> surrounding the content of the cell, and then block it with block="cell" in the blockUI component.
The result would be something like:
<p:dataTable id="table" var="tableVar" value="#{tableValues}">
<p:columns id="column" var="columnVar" value="#{columnValues}">
<f:facet name="header">
<h:outputText value ="#{columnVar}"/>
</f:facet>
<p:outputpanel id="cell">
<h:outputText value="Some Text"/>
<p:commandButton value="Button Text"
id="button"
update="table"
actionListener="#{some.method()}"/>
<p:blockUI block="cell" trigger="button">
<p:graphicImage name="loading.gif"/>
</p:blockUI>
</p:outputpanel>
</p:columns>
</p:dataTable>

ajax update row while using the rowStyleClass of p:datatable

i have a p:datatable of 30 sets of rows with each row can have different colors(rowStyleClass) based on the values chose in one of the column with ajax update table.
however, this give me problem with unsaved values in other columns of input text where everytime i change the value ajax, the table gets repopulated thus resetting every field to the saved original values.
how do i update only the row, but also use the p:datatable rowStyleClass?
eg. of code
<p:datatable id="dtable" var="tbl" value="#{bean.list}"
rowStyleClass=" #{tbl.column.value eq 'a' ? 'yellowColored' : ''}
#{tbl.column.value eq 'b' ? 'greenColored' : ''}
#{tbl.column.value eq 'c' ? 'kindaBlueColored' : ''}">
<p:column id="column" >
<f:facet name="header">
<h:outputText value="column" />
</f:facet>
<p:selectOneMenu id="selColumn" value="#{tbl.column}" var="t" >
<p:ajax partialSubmit="true" event="change" process="#this"
update="tsheet" listener="#{bean.onTypeChange}" />
<f:selectItems value="#{bean.typeList}" var="type"
itemValue="#{type}" itemLabel="#{type.description}" />
</p:selectOneMenu>
</p:column>
</p:datatable>

Primefaces dataTable reRender column is not working

I am using Primefaces 5.1 in my page I use dataTable inside another dataTable.In add button press add new bean for salList and check salList not null to rendered header column.But sal column not rendered.
<p:dataTable id="mainTable" value="#{employee.employeeList}" var="emp" ..>
<p:columnGroup type="header">
<p:row >
<p:column headerText="Name"/>
</p:column headerText="value" **rendered="#{emp.salList ne null and not empty emp.salList}**/>
....
<p:column>
<f:facet name="header"><p:commandButton value="add button" action="#{employee.addButton}" update="mainTable"/>
</f:facet>
</p:column>
</p:row>
</p:columnGroup>
<p:column>
<p:dataTable value="#{emp.salList}" var="sp">
<p:column></p:column>
..
</p:dataTable>
</p:column>
</p:dataTable>
My doubt is when I press add button to add new list salList bean and it add new bean and show component in inside dataTable.But in header column salary column is not rendered i.e header column not updated it will not rendered the specify header column.

How to get multiple h:selectOneMenu values inside h:dataTable [duplicate]

This question already has answers here:
Input field in <h:dataTable> always receives value of last item in list
(3 answers)
Closed 7 years ago.
I'm using h selectOneMenu in a datatable and when user press the Set Fixture button i'm saving the value changed in the dropdown, for now i'm using a String variable to get the selected value but the issue is it have the selected value from only the last dropdown. My question is how to get list of all the dropdowns ?
<h:form id="chooseAlmFixtureForm">
<p:panel style="width:80%" header="Set Fixture for Alarms">
<p:dataTable id="tbsetFixtureTable" value="#{setAlmFixtures.alarms}" var="alarmvar" dynamic="false">
<p:column>
<p:commandLink value="View" update=":viewUnknownAlarm" immediate="true" oncomplete="viewDialog.show()">
<f:setPropertyActionListener target="#{currentalarms.viewAlarm}" value="#{alarmvar}"/>
</p:commandLink>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Alarm Time"/>
</f:facet>
<h:outputText value="#{alarmvar.recvTime}"/>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Alarm Type"/>
</f:facet>
<h:outputText value="#{alarmvar.alarmType}"/>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Controller Name"/>
</f:facet>
<h:outputText value="#{alarmvar.controllerName}"/>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Controller Type"/>
</f:facet>
<h:outputText value="#{alarmvar.controllerType}"/>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Choose Fixture"/>
</f:facet>
<h:selectOneMenu id="selectAlarmSite" value="#{setAlmFixtures.selectedFixture}">
<f:selectItems value="#{setAlmFixtures.fixtures}" />
</h:selectOneMenu>
</p:column>
</p:dataTable>
<p:commandButton value="Set Fixtures" actionListener="#{setAlmFixtures.setAlarmsFixtures}" action="#{horizontalmenu.actionCallAlarmsPage}" styleClass="dialogButton"/>
</td><td>
<p:commandButton value="Cancel" actionListener="#{setAlmFixtures.releaseAlarms}" action="#{horizontalmenu.actionCallAlarmsPage}" styleClass="dialogButton"/>
</p:panel>
</h:form>
Currently, your dropdown-value refers to a single variable in your bean (which seems to be selectedFixture of class SetAlmFixtures). How would a single variable represent a state (value) for multiple row (here: alarms)?
You need to link the selected value to the row (alarm) it refers to. To do so, you have several options, two approaches following:
Use the variable of your alarm-object, just the same way as you used them as outputvalues inside the other columns. This way, the alarm's fixture is set directly on value (form) processing. Currently, both of your buttons submit the form (type="submit" is default), depending on what your actionlisteners do, you might consider changing the Cancel-button's type to button.
Map the fixtures and alarms. You could use something like Map<Long, Fixture> fixturemap; mapping alarm-id's to their selected fixture, assuming all alarms have a non-null id. The map's value can be referred by setAlmFixtures.fixturemap['alarmvar.id']. Make sure you provide a getter for the map and the id. Also, you need to initialize the map with the initial fixture values for each alarm.

Dynamically adding a row to primefaces dataTable

I need to add a row to my datatable on click of a button - "Add Employee".
The datatable shows the records corresponding to a fixed list of Employees in the bean.
What I am doing is, on click of the "Add Employee" button , I am adding an empty record of Employee to the empList.
Is there any better way to do this?
Thanks.
Either you open a dialog or a popup when clicking the add button. Then fill in the required fields (attached to a employee object. And when saving/submit you add that object to your list of employee objects. And rerender the datatable.
Or you can initially add an empty emploee object to your list. Showing it in the datatable with inputfields. On add, you add the new employee to the list and rerender the list.
list_Recs is list of records and shown in the data table.
<p:dataTable id="myTable" value="#{myBean.list_Recs}" selectionMode="single" var="myTableVar" selection="#{myBean.currentRec}">
<p:ajax event="rowSelect" listener="#{myBean.handleRowSelect}" update=":myForm:myPanel"/>
<p:column>
<f:facet name="header">
<h:outputLabel value="Field 1" />
</f:facet>
<h:outputLabel value="#{myTableVar.Field1}"/>
</p:column>
<p:column>
<f:facet name="header">
<h:outputLabel value="Field 2" />
</f:facet>
<h:outputLabel value="#{myTableVar.Field2}" />
</p:column>
<f:facet name="footer">
<p:commandButton value="New" action="#{myBean.prepareForInsert}" update=":myForm:myPanel"/>
</f:facet>
</p:dataTable>
<h:panelGrid id="myPanel" columns="2" >
<h:outputLabel value="Field 1"/>
<p:inputText id="fld1" value="#{myBean.newRec.field1}" />
<h:outputLabel value="Field 2"/>
<p:inputText id="fld2" value="#{myBean.newRec.field2}" />
<p:commandButton action="#{myBean.createAction}" value="Submit" update="myGrowl myTable" />
</h:panelGrid>
When New button is clicked, create an emty instance of newRec in prepareForInsert routine of myBean. So that myPanel is filled with blanks in the fields. On Submit, add the newRec to
list_Recs and the new record is diplayed in the data table because of the update on myTable.
Hope this helps.
A different option would be to show an empty employee in the footer facet of your datatable and add it to your list if the user clicks the add button. With this you can ensure that only correctly filled employee objects/entities are added to your list.

Resources