<p:dataTable multiple selection mode. How to assign values immediately? - jsf-2

I have a list of items, the problem is that after selection "mngr" bean property "selectedItems" doesn't get assigned with these selected items.
<p:dataTable id="tbl" var="item"
value="#{mngr.itemsTableModel}" widgetVar="tbl"
selectionMode="multiple" selection="#{mngr.selectedItems}">
<p:column headerText="Name">
<h:outputText value="#{item.name}"/>
</p:column>
</p:dataTable>
<p:commandButton value="Assign" process="tbl"/>
Selection fails even if "Assign" button is pressed and partial processing is completed.
Maybe there is ajax even for multiple selection?

Related

Calling listener in p:selectBooleanCheckbox without refreshing the whole dataTable in Primefaces

I have a Primeface selectBooleanCheckbox in a column of a DataTable. Inside there is a <p:ajax that on check calls the method in the listener (mybean.checkCell(cell.field2)) and saves the status of the checkbox.
My problem is that the entire p:dataTable is refreshed when I check.
How do I call mybean.checkCell(cell.field2) without refreshing the whole dataTable?
Here is my code:
<p:dataTable var="cell" value="#{mybean.mycells}" widgetVar="cell" emptyMessage="No cells" filteredValue="#{mybean.filteredCells}">
<p:column filterBy="#{cell.field1}" headerText="Field1" filterMatchMode="contains">
<h:outputText value="#{cell.field1}" />
</p:column>
<p:column headerText="Checkbox">
<p:selectBooleanCheckbox value="#{cell.check}" partialSubmit="true">
<p:ajax process="#this" partialSubmit="true" update=":form:messages" listener="#{mybean.checkCell(cell.field2)}" onstart="PF('statusDialog').show();" oncomplete="PF('statusDialog').hide();" />
</p:selectBooleanCheckbox>
</p:column>
</p:dataTable>
You are updating the component specified in update=":form:messages" everytime click the checkbox. I guess "messages" ID belongs to a container where the datatable is in. If it is not right, i don't understend why the databled gets updated. If it is right, just delete the update attribute or update something that does not contain the datatable inside.

How to dynamically get value of component p:inputText inside a datatable?

I have a primefaces Datatable:
<p:dataTable id="tabela" var="item"
value="#{myBean.lista}"
rowIndexVar="rowindex">
<p:column>
<p:inputText
required="true" id="inputAliquota" value="#{item.taxa}"
>
</p:inputText>
</p:column>
</p:dataTable>
In my backing bean I have a lista:
private List<Aliquota> lista;
And a Button to remove columns from my datatable:
<p:commandLink
immediate="true" id="botaoExcluir"
action="#{myBean.excluirAliquota}"
>
<f:setPropertyActionListener value="#{item}"
target="#{myBean.aliquota}" />
</p:commandLink>
When I start the bean I populate "lista" with 5 empty Aliquota objects.
In excluirAliquota method I get the object that has to be removed, compare with the values of the List and delete it. But I'm having problems. When the user change the value of inputText the change don't reflect the Aliquota object on list.
My question is how to set this value without submit it?
You cannot reflect the value on the backing bean without submitting it. However, you can submit it using Ajax by adding a listener to the input text. The listener method doesn't have to do anything, it can be empty, but it needs to be there for an Ajax submit. It can be something like that:
<p:dataTable id="tabela" var="item"
value="#{myBean.lista}"
rowIndexVar="rowindex">
<p:column>
<p:inputText
required="true" id="inputAliquota" value="#{item.taxa}"
>
<p:ajax listener="#{myBean.dummyListener()}"/>
</p:inputText>
</p:column>
</p:dataTable>
This will instantly reflect all changes in the inputText to the taxa field of the corresponding item. If that's what you want, you can use this method.

"DataModel must implement org.primefaces.model.SelectableDataModel when selection is enabled" even after adding rowKey value to dataTable

According to the accepted answer of the following question:
FacesException: DataModel must implement org.primefaces.model.SelectableDataModel when selection is enabled its required to implement SelectableDataModel or add the rowKey attribute to the dataTable to avoid that exception. Anyway I just added the rowKey attribute as you can see and the error still happening, hope someone can tell me why.
This is my dataTable:
<p:dataTable var="item" rowKey="#{item.id}" style="margin-top:5px" emptyMessage="Nenhum registro encontrado"
value="#{controller.entidade.ecfs}" rows="10" selectionMode="single"
paginator="#{ecfController.showPaginator()}" paginatorPosition="bottom">
<p:column headerText="Nº Série">
<p:outputLabel value="#{item.numeroSerie}"/>
</p:column>
<p:column headerText="Modulo">
<p:outputLabel value="#{item.modulo}"/>
</p:column>
<p:column headerText="Modelo">
<p:outputLabel value="#{item.modelo}"/>
</p:column>
<p:column headerText="GT Inicial">
<p:outputLabel value="#{item.gtInicial}"/>
</p:column>
</p:dataTable>
I found out that with the rowKey attribute you must assure uniquiness based on the rowKey, another point is that if you try to insert a new object with the rowKey attribute as null it will not work too.

Prevent state saving for specific element

I have the following scenario:
I have a dataTable in which I have a column with the following code
<f:facet name="header">
<h:selectBooleanCheckbox styleClass="checkall"
id="my-id-chk" />
<h:outputLabel for="my-id-chk" />
</f:facet>
<h:selectBooleanCheckbox rendered="#{row.selectable}" value="#{row.selected}"
styleClass="checkall_remover" id="row-chk" />
<h:outputLabel for="row-chk" />
When I want to select all rows and delete them:
1) I click on the h:selectBooleanCheckbox in the <f:facet name="header"> and with js I select all rows checkboxes
2) Click on delete button that execute that dataTable and deletes all rows on server , that delete button also renders the dataTable so the deleted rows will be removed from it
Now the thing is that the h:selectBooleanCheckbox in the <f:facet name="header"> keeps its state (checked state)
How can I make that h:selectBooleanCheckbox in the <f:facet name="header"> to be unchecked ?
The solution that I use right now is to render the dataTable from a "proxy" button that is located in other h:form <-- Using that technique causes the h:selectBooleanCheckbox in the <f:facet name="header"> not to remember its state.
But I prefer a cleaner solution without using additional h:form
(I use MyFaces 2.2.3 with Tomcat 7)
Just use plain HTML. JSF state is indeed saved on server side, but HTML state not.
<f:facet name="header">
<input type="checkbox" class="checkall"
id="my-id-chk" />
<label for="my-id-chk" />
</f:facet>
An alternative would be to create a custom component whereby getters/setters don't delegate to UIComponent#getStateHelper() but instead to local properties.

p:commandLink in p:dataTable does not invoke action on first click, but only on second click

I'm using primefaces commandLink in p:datatable and when user clicks on link. It's supposed to navigate to another page including specific info of object that is chosen from table. I don't use any ajax tags. Problem is when first time clicks on link it doesn't invoke action actually nothing happens and on second click it works. Here is my code :
JSF with Datatable
<h:form>
<h:outputText value="Nothing is found" rendered="#{searchView.citizenSearchList.rowCount==0}"/>
<p:dataTable var="cust" value="#{searchView.citizenSearchList}" dynamic ="true" paginator="true" rows="5" paginatorAlwaysVisible="false" style="width: 700">
<p:column>
<f:facet name ="header">
<h:outputText value="name "/>
</f:facet>
<h:outputText value="#{cust.name}"/>
</p:column>
<p:column>
<f:facet name ="header">
<h:outputText value="lastname "/>
</f:facet>
<h:outputText value="#{cust.citizenList.get(0).lastname}"/>
</p:column>
<p:column>
<f:facet name ="header">
<h:outputText value="Id "/>
</f:facet>
<h:outputText value="#{cust.registernumber}"/>
</p:column>
<p:column>
<f:facet name ="header">
</f:facet>
<p:commandLink value="See" action="#{customerView.prepareCitizenView()}"/>
</p:column>
</p:dataTable>
</h:form>
ManagedBean: customerView's action method
#ManagedProperty(...)
SearchView searchview;
public String prepareCitizenView(){
this.customer = (Customer) searchview.citizenSearchResultList.getRowData();
if(this.customer != null)
return "citizeninfo";
else
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "no data.", "no data"));
return null;
}
ManagedBean: searchView
DataModel citizenSearchResultList;
public DataModel getCitizenSearchResultList() {
return citizenSearchResultList;
}
You can return redirect to same page.
customerView.prepareCitizenView can retruns same page with redirect.
like
return "citizeninfo.jsf?faces-redirect=true";
this "jsf" changes according to what you use
As mehmet cinar stated, the solution is to use a redirect in your navigation outcome. I've had this problem myself.
return "citizeninfo.jsf?faces-redirect=true";
From what I was able to deduce, the reason is that the ajax submit will not contain a ViewState request parameter for the new page. Without the ViewState the first time, things break.
Once you perform a redirect, the redirect will correctly have a Viewstate parameter appended to the request, and buttons can be clicked the first time
If p:commandLink is included within two h:form then action will be invoked on second call.
Check the outer tags of p:commandLink

Resources