Primefaces datatable: partial processing on row selection - java

I have a primefaces datatable with ajax events to handle multiple row selection. Within the table I also have some in-place editing components. The problem is that whenever I select a row, the whole table gets processed, including the input components.
Is there a way to only process the row selections, not the inputs?
example xhtml...
<p:dataTable value="#{controller.data}" var="d" rowKey="#{d.id}"
selection="#{controller.selected}" rowSelectMode="add">
<p:ajax event="rowSelect" partialSubmit="true" process="#this"
update=":anotherComponent"/>
<!-- ...and other events -->
<p:column selectionMode="multiple"/>
<p:column>
<p:inplace editor="true" saveLabel="Apply changes" >
<p:inputText value="#{d.value}"/>
<p:ajax event="save" partialSubmit="true" process="#this"
listener="#{controller.saveChanges(d)}"/>
</p:inplace>
</p:column>
<!-- ...and other columns -->
</p:dataTable>

Unfortunately there is no official way to do this. I reported this to the PF team a half year ago and they promised that they will introduce something like process="#onlyThis", but there is no ETA for this enhancement.

Related

What is the equivalent of JSTL <c:forTokens> in JSF or PrimeFaces?

Assume we have the following JSP code:
<c:forTokens items="${someBean.aStringOfIntNumbersSeparatedBySemicolons}"
delims=";"
var="item"
varStatus="stat">
${item}
<c:if test="${!stat.last}">;</c:if>
<c:if test="${stat.count %5 == 0}">
<br/>
</c:if>
</c:forTokens>
Of which the output is rendered in rows with 5 columns each, like so:
How can I possibly do this with the JSF or Primefaces tags?
There is no direct equivalent, you should transform your token into a list in the managed bean and consume the list in the framework components.
List<String> tokens = Arrays.asList("car1,car2,car3,car4".split(","));
For such simple scenario you might not need the primefaces components. When you go for a Object Oriented model, you can take advantage of PF components to iterate through the list and present its fields using data binding. For instance:
DataList - For each Car type in the cars1 list, a line will be added in the list.
<p:dataList value="#{dataListView.cars1}" var="car" type="ordered">
<f:facet name="header">
Basic
</f:facet>
#{car.brand}, #{car.year}
</p:dataList>
DataTable - For each car in cars list, a row is added to the table component.
<p:dataTable var="car" value="#{dtBasicView.cars}">
<p:column headerText="Id">
<h:outputText value="#{car.id}" />
</p:column>
<p:column headerText="Year">
<h:outputText value="#{car.year}" />
</p:column>
<p:column headerText="Brand">
<h:outputText value="#{car.brand}" />
</p:column>
<p:column headerText="Color">
<h:outputText value="#{car.color}" />
</p:column>
</p:dataTable>
Using such component framework you might speed your development focusing on the business logic instead of UI design.
The only working solution I've found
For now, the only working solution I've found lies partly in the JSF and partly in the back-end code:
Edit the back-end code so that it adds a <br/> after every fifth element of that String field aStringOfIntNumbersSeparatedBySemicolons.
Add escape="false" to the <h:outputText> tag that holds the data on the front end. (The default value is escape="true", which renders <br/> as <br/>)

Error p:ajax update

In an edit screen, I'm using p:ajax to grab the selected value in an autocomplete field and fill in other fields in the form. But when ajax is running in question it is updating the information in the database table (update). How do I block this behavior? After all I should only do this when I clicked the save button.
Code:
<h:panelGroup>
<p:autoComplete id="demandaBeanDemandaLogradouroNome" value="#{demandaBean.demanda.logradouro}"
var="_item" minQueryLength="3" maxResults="15" required="true"
itemLabel="#{_item.nome}" itemValue="#{_item}" converter="#{logradouroBean.converter}"
completeMethod="#{logradouroBean.buscaLogradouro}" title="Busca pelo Logradouro">
<p:column>
<h:outputText value="#{_item.categoria.descricao}"/>
</p:column>
<p:column>
<h:outputText value="#{_item.nome}"/>
</p:column>
<p:ajax partialSubmit="true" immediate="true" event="itemSelect" update="demandaBeanDemandaBairro demandaBeanDemandaCruzamento"
listener="#{logradouroBean.buscaComplementoSelectEvent}"/>
</p:autoComplete>
<p:message for="demandaBeanDemandaLogradouroNome" styleClass="error"/>
</h:panelGroup>
I have found that what happens is that Hibernate synchronizes the persistent objects and if you change it it automatically updates in the database. To solve, I used an auxiliary object with the #Transient tag. Thanks.

Primefaces columnToggler remove item from checkbox list

I'm using a Primefaces columnToggler to dynamically hide/display columns in a data table. This is working as expected, however I would like to remove items from the togglers checklist, so the user cannot check/uncheck them.
relevant code:
button and columnToggler
<p:commandButton id="toggler"
type="button"
value="Columns"
title="Show/Hide columns"/>
<p:columnToggler datasource="my_datatable"
trigger="toggler" />
dataTable
<p:dataTable value="#{bean.foobars}" var="fb"
id="my_datatable"> ...
column to show (working as expected)
<p:column headerText="Data One" >
<h:outputText value="#{fb.data1}"/>
</p:column>
column to hide from columnToggler checklist (how do I do this?)
<p:column headerText="Always Available" >
<h:outputText value="#{fb.mustSeeField}"/>
</p:column>
I was hoping to find an attribute on p:columnToggler for 'locked' or 'always on' fields, or possibly an attribute on p:column to remove it from the columnToggler checklist. Unfortunately I'm not sure how to do this, or if it's possible. Thoughts? Solutions? thank you!
PrimeFaces has a toggleable attribute on the p:column as can be seen in the PrimeFaces 6.1 documentation on page 110. So
<p:column headerText="Always Available" toggleable="false">
<h:outputText value="#{fb.mustSeeField}"/>
</p:column>
Should do the trick

Primefaces datatable cell editing doesn't update

I have a primefaces datatable with cell editing which is toggled on a boolean variable in the view.
I have three issues:
In edit mode, I change a value and I click the save button on the page it doesn't keep the new value, If I click anywhere else first on the page then click save it will keep the value. I need it to keep the value if you click save first.
If I edit a cell which is an input text and I click out the field now is a output text until I click in there again. I want the field to look like a input text while in edit mode.
When the save button is clicked the backing method sets the editable boolean to false, and the rest of the page obeys, and the dataTable looks like it obeyed but if you click a cell it will let you edit it.
Here is the code:
<p:dataTable value="#{view.LineItems}" var="lineItem" rowKey="#{lineItem.lineItemId}"
resizableColumns="false" editable="#{view.editable}" editMode="cell"
editingRow="#{view.editable}" id="requestLineItemsTable">
<p:ajax event="cellEdit" listener="#{view.cellEdited}" immediate="true" update="#this" />
<p:column styleClass="centerColumnData" headerText="Item Name" style="width: 140px;">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{lineItem.title}"/>
</f:facet>
<f:facet name="input">
<h:inputText value="#{lineItem.title}"/>
</f:facet>
</p:cellEditor>
</p:column> ...
and this is the back end (not doing anything with this yet)
public void cellEdited(CellEditEvent event)
{
Object oldValue = event.getOldValue();
}
and here is the save and edit buttons on the same .xhtml page as datatable
<p:commandLink process="#this"
action="#{view.changeModeToEdit}"
update="#form"
rendered="#{!view.editMode">
<h:graphicImage library="images" name="edit20.png" title="#{__Common.edit}"
style="height: 15px; width: 15px;"/>
</p:commandLink>
<components:linkWithSpinner linkStyle="margin-right: 20px;" loadingImageStyle="margin-right: 20px;"
linkStyleClass="activeButton saveButtonRequestDetails" loadingImageStyleClass="saveButtonRequestDetails"
linkText="#{__CommonButton.save}"
process="#form" update="#form"
actionMethod="#{view.updateRequest()}"/>
view.updateRequest() sets the editable to false. I am using Primefaces 4.0
So I figured out a way around these issues. I was focused on using the built in edit table , but you can just have a normal datatable and the columns can contain input text fields. Then you don't have to worry about most of the issues in my question above. If you need to switch between edit and non-edit view then I still don't know how to fully fix it except have two datatables in your file with render tags, but then you are duplicating the table one with input text fields and one with output text fields, and that is not the best way to do it.

get row number in primefaces datatable by clicking button in row

how can I get row number in Primefaces (2.2) DataTable by clicking button in some row?
I need pass this number to javascript code with prompt() function.
1 solution
using WidgetVar.selection but in this case I use manually row selection and then click button -> bad scenario.
<p:column>
<p:commandButton id="someButton" value="Button"
actionListener="#{managedBean.someEvent}" onclick="return jsMethod(widgetVar.selection)" />
</p:column>
Thank You!
You can use UIData#getRowIndex() for this.
<p:dataTable binding="#{table}" ...>
<p:column>
<p:commandButton ... onclick="return jsMethod(#{table.rowIndex})" />
</p:column>
</p:dataTable>

Categories