Row style in dataTable is not updated - jsf

I have a datatable with cell editing enabled. The table has a rowStyleClass that assigns background color based on a row status (INSERTED, UPDATED, DELETED or NONE). So when I edit a row, it gets an UPDATED status, when delete button is clicked, row gets a DELETE status,... Based on that status, row background should be properly coloured (green for UPDATED, red for DELETED, yellow for INSERTED).
My code:
<p:dataTable id="tblElement" var="eltItem" value="#{bean.elementList}" binding="#{bean.dtElements}" emptyMessage="No data to be displayed."
editable="true" editMode="cell" rowIndexVar="rowIndexElt" rowKey="#{eltItem.id}" resizableColumns="true" styleClass="eltStyle"
rowStyleClass="#{bean.elementRowStyle}">
<p:ajax event="cellEdit" listener="#{bean.doMarkRowAsUpdated}" update=":form1:tabView:tblElement" />
<p:column>
<p:commandButton id="btnMarkAsDeleted" icon="ui-icon ui-icon-trash" update="tblElement" action="#{bean.doBtnMarkAsDeleted}">
<p:confirm header="Confirm" message="Do you really want to delete an element?" icon="ui-icon-alert" />
</p:commandButton>
</p:column>
<p:column headerText="Key">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{eltItem.key}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{eltItem.key}" />
</f:facet>
</p:cellEditor>
</p:column>
<!-- some more columns -->
<p:dataTable>
When a cell is edited, doMarkRowAsUpdated method should be executed... and it is. Row status is set to UPDATED, so edited row background should be colored to green, but it is NOT. Note that rowStyleClass value is as it should be because the whole coloring thing works when table edit mode is set to 'row'. One more thing to mention... Let's say that I edit some row. As already mentioned, background color doesn't change. But if my next action is marking some other row as deleted, that row IS colored in red. And that's not all - previously edited row is ALSO colored in green! It's like after 'button click' method is executed, row style is updated, but after 'cellEdit' event method is executed, row style is not updated.
Any suggestion how to make row coloring work?
I'm using PF 5.1.

It should work when you embed the table in a form and update the form with a remoteCommand like this:
<p:remoteCommand name="onCellEdit" update="#form" />
<p:dataTable ... rowStyleClass="#{bean.elementRowStyle}">
<p:ajax
event="cellEdit"
listener="#{bean.doMarkRowAsUpdated}"
oncomplete="onCellEdit()"/>

Related

<p:commandButton> doesn't work inside of p:dataGrid when column = 4 row = 1

I just want to add p:commandButton for each item in list in p:dataGrid.
But, when I set columns = 4 and rows = 1 from properties p:dataGrid. I can't get value from commandButton anymore in rest of list (except for the first item in list).
Tried change into h:commandButton, p:commandLink, ajax= false;
<p:dataGrid var="list" value="#{myBean.listCompany}" columns="4" layout="grid"rows="1" paginator="true" paginatorPosition="bottom" paginatorTemplate="{PreviousPageLink} {NextPageLink} ">
<div class="card" style="height: 350px">
<p:column>
<p:panel>
<h:panelGrid columns="1">
<p:commandButton value="Choose" action="#{myBean.selectCompany(list.companyName)}">
</p:commandButton>
</h:panelGrid>
</p:panel>
</p:column>
</div>
</p:dataGrid>
Based on this , https://knowles.co.za/primefaces-actions-not-firing-in-last-rows-of-datagrid/
The quick fix is just to set the number of rows correctly, to fill the number of columns you have. As long as the number of rows is a multiple of the number of columns (eg, 2 columns, 6 rows) you should be fine.
But, this is not the solution that I want, I need to display p:dataGrid with 4 columns and 1 row.
If I get your intention right that you want to display 4 elements out of #{myBean.listCompany} in one row, you should set colums="4" and rows="4".
This way rows is a multiple of the number of columns with the multiplicator being 1.
Rows here seemes to be the total number of elements from #{myBean.listCompany} to display per page. If this does not match with a multiple of columns, there seemes to be some kind of mismatch between rendering and component input handling.
You can add a rowIndexVar="rowIndex" and output that with each element to make visible what one row is in a dataGrid.
<p:dataGrid var="list" value="#{myBean.listCompany}" columns="4"
layout="grid" rows="4" paginator="true" paginatorPosition="bottom"
paginatorTemplate="{PreviousPageLink} {NextPageLink} " rowIndexVar="rowIndex">
<div class="card" style="height: 350px">
<p:column>
<p:panel>
<h:panelGrid columns="1">
<p:commandButton value="Choose Row #{rowIndex}"
action="#{myBean.selectCompany(list.companyName)}">
</p:commandButton>
</h:panelGrid>
</p:panel>
</p:column>
</div>
</p:dataGrid>

Primefaces Dynamic Columns - how to set ID?

I have a dataTable with dynamic columns:
<p:columns value="#{dashboardEditionBean.columns}" var="column" columnIndexVar="colIndex" sortBy="#{deviceMock[column.property]}" filterBy="#{deviceMock[column.property]}">
<f:facet name="header">
<h:outputText value="#{column.header}" />
</f:facet>
<h:outputText value="#{deviceMock[column.property]}" />
</p:columns>
I wonder if there is a way to set ID of each column? I need this so I can retrieve the column ID at the backing bean. I know that PrimeFaces generate some ID's for these columns and add the column index to them, but since I want to be able to reorder these columns and store the changes I need some more descriptive information at the backing bean (custom ID or something else).

p:cellEditor in p:dataTable not working consistently

I wanted to create an editable table with JSF/PrimeFaces. Here is one column of the <p:dataTable> row:
<p:column>
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{onesubquestion.text.value}"/>
</f:facet>
<f:facet name="input">
<p:inputText value="#{onesubquestion.text.value}" style="width:96%"/>
</f:facet>
</p:cellEditor>
</p:column>
It worked well for most of table cells, but it did not work for some, e.g, click on the text of the cell and the input field did not show up and there were no error messages.
Any suggestions of hints are appreciated.

How to use ui:repeat in datatable to append columns?

I want to generate a list of tables. 1 table for each month. With 1 column for each day of the month. Here is the JSF piece I am using.
<ui:repeat value="#{worklogService.months}" var="monthnum">
<p:dataTable value="#{worklogService.getTableForMonth(monthnum)}" var="tabrow">
<p:column headerText="Name">
<h:outputLabel value="#{tabrow.get(0)}"></h:outputLabel>
</p:column>
<ui:repeat value="#{worklogService.getDaysOfMonth(monthnum)}" var="daynum">
<p:column headerText="#{daynum}">
<h:outputText value="#{tabrow.get(daynum)}"></h:outputText>
</p:column>
</ui:repeat>
</p:dataTable>
</ui:repeat>
#{worklogService.months} returns List<Integer>. One number per Month.
#{worklogService.getTableForMonth(monthnum)} returns List<List<String>>.
The first column for each table is the same. I want to generate all other columns depending on the month. The result is 12 Tables with only 1 column (the first). What could be the problem here? And how to solve it?
This construct fails because UIData components like <p:dataTable> only support UIColumn children which can in case of <p:dataTable> only be either <p:column> or <p:columns>.
In your particular case, you've 2 options:
Use <p:columns> instead of <ui:repeat><p:column>:
<p:columns value="#{worklogService.getDaysOfMonth(monthnum)}" var="daynum" headerText="#{daynum}">
#{tabrow.get(daynum)}
</p:columns>
Use <c:forEach> instead of <ui:repeat> (explained here):
<c:forEach items="#{worklogService.getDaysOfMonth(monthnum)}" var="daynum">
<p:column headerText="#{daynum}">
<h:outputText value="#{tabrow.get(daynum)}"></h:outputText>
</p:column>
</c:forEach>

Primefaces Datatable checkbox affecting ability to copy and paste

I have a primefaces table with a multiple checkbox column and the way it works currently is that any click on any part of a row selects the row
How can I change it so that the row is selected only by clicking within the checkbox?
I wan this change because it will allow data in other columns to be copied after highlighting.
The issue right now is that whenever I try to highlight data in a cell, the row I clicked in gets selected and I am unable to highlight the data(and therefore unable to copy the data).
Below is my primefaces table:
<p:dataTable id="abc" value="#{myBean.getRows()}" var="row" rendered="#{!myBean.getRows().isEmpty()}" lazy="false" paginator="true" paginatorAlwaysVisible="false" rows="20" selection="#{myBean.selectedRows}" rowKey="#{uiRow.id}">
<p:column selectionMode="multiple" style="float:center"/> <!--checkbox column-->
<p:column id="data_id" headerText="#{bundle.id}" sortBy="#{uiRow.id}" filterBy="#{uiRow.id}" filterMatchMode="contains" filterStyle="width: 60px">
<h:outputText value="#{uiRow.id} "/>
</p:column>
<p:column id="data_state" headerText="#{bundle.data_state}" sortBy="#{uiRow.stateRow}" filterBy="#{uiRow.stateRow}" filterMatchMode="contains" filterStyle="width: 60px">
<h:outputText value="#{uiRow.stateRow} "/>
</p:column>
<p:column>
....
You could make your own selection checkbox and add it as a column to the datatable.
<p:column id="select">
<p:selectBooleanCheckbox value="#{row.checked}"/>
</p:column>
And then you could iterate over all the checked objects in your backing bean and do whatever you want with them...
Set disabledTextSelection to false

Resources