Primefaces DataTable and button invocation issue - jsf

I have a DataTable that presnt a list of product :
<p:dataTable var="product" value="#{myModel.products}"
scrollable="true" id="productsTableId" liveResize="true"
resizableColumns="true">
<f:facet name="header">
List of products
</f:facet>
<p:column headerText="Id" sortBy="id">
<h:outputText value="#{product.id}" >
</h:outputText>
</p:column>
<p:column headerText="Name" sortBy="name">
<h:outputText value="#{product.name}" title="#{product.name}" />
</p:column>
<p:column headerText="Remove product">
<p:commandButton icon="ui-icon-close" title="delete product"
value="Disconnect"
action="#{controller.delete(product)}"
update="productTableId">
<p:confirm header="Confirmation"
message="Are you sure you want to delete this product"
icon="ui-icon-alert" />
</p:commandButton>
</p:column>
</p:dataTable>
but the problem comes when i try to sort the datatable, the rows change their diplay order but the buttons functionalities keep the initial order ,i.e. if i have for example two products :
Id Name Remove product
1 B Delete B
2 A Delete A
after sorting by name
Id Name Remove product
2 A Delete A
1 B Delete B
If i click 'Delete A' then the product B is removed , is this a bug in PrimeFaces or i'm missing something .
i'm using PrimeFaces 4.0 ,JSF Mojarra 2.1.20 on jetty-9.1.2.

I've found the source of problem, the bean myModel was set to a request scope, i've change it to view scope.
Explanation :
When we load the page for the first time one managed bean myModel is created and used, when we sort data , a second managed bean is created , when we click on delete button we ask server to delete the product that has to index order of the pressed button , the server try first to create instance of the managed bean myModel , then it look for the product with the index order posted and remove it. this senario cause the issue. to avoid this we use the view scope to keep using the sapce instance of myModel created when the page is loaded. with the view scope , only one instance will be created and used in the same senario specified here.

Related

How to enable and disable command link in jsf?

I am very new to jsf .I have created an arraylist in java class which contains 4 columns and 20 rows.There is a column which have further data linked to it when we click on that specific entry.I want to enable command link for those entries only and the rest of the data should be just displayed as it is as(command link should be disabled).I have tried them in different ways but I was getting both the output label and the command link at the same time(it means I am getting the data twice).But I need to show the data only once.Some one please suggest me a way to solve this.Below is my code where sampleMB is my managed bean and there is a column1 which has 20 rows where 4 rows have to be enabled with a command link on a condition that the data in those rows contains string "XYZ" and the rest 16 rows should be displayed as it is.
Any help will be really appreciated.
<p:dataTable id="table" value="#{sampleMB.List1}" var="cList" scrollable="true" scrollHeight="400">
<p:column headerText="column1" >
<h:outputLabel value="#{cList.column1 }" >
<p:commandLink value="#{cList.column1}" ajax="false" style="text-decoration:underline" rendered="#{cList.card_slot.contains('XYZ')}" /> </h:outputLabel>
</p:column>
</p:dataTable>
What about something like this:
<p:dataTable id="table" value="#{sampleMB.List1}" var="cList" scrollable="true" scrollHeight="400">
<p:column headerText="column1">
<h:outputLabel value="#{cList.column1 }" rendered="#{not cList.card_slot.contains('XYZ')}" />
<p:commandLink value="#{cList.column1}" ajax="false" style="text-decoration:underline" rendered="#{cList.card_slot.contains('XYZ')}" />
</p:column>
</p:dataTable>
If you just want to enable/disable command link, you should use disabled attribute instead of rendered and remove h:outputLabel.

Primefaces dataTable filter selectOneMenu not working

I am using PrimeFaces 5.1, In my project dataTable to filter used.In text filter is work fine but dropdown filter is not working properly (i.e) In dropdown I show department,First time I choose any value from dropdown is work fine anothertime I choose dropdown It not return any value show in dataTable.I choose select one first value from dropdown also throw null pointer exception.
<p:dataTable id="datalist" widgetVar="datalist" var="user" value=#{beanList.userList}>
<p:column headerText="Department" filterBy="#{user.deptname}"
filterMatchMode="exact" >
<f:facet name="filter">
<p:selectOneMenu onchange="PF('datalist').filter()">
<f:selectItem itemLabel="ALL" itemValue="#{null}"
noSelectionOption="true" />
<f:selectItems value="#{datalist.deptList}" />
</p:selectOneMenu>
</f:facet>
<h:outputText value="#{user.depatname}" />
</p:column>
</p:dataTable>
My doubt is default value ALL click and second time select any value return null or no data show in dataTable.
Since I don't know the scope of your Managed Bean: Try a scope longer than request (see PrimeFaces 5.1 User Documentation), and provide a value "filteredValue" for your table, like this:
<p:dataTable id="datalist" widgetVar="datalist" var="user"
value="#{beanList.userList}" filteredValue="#{beanList.filteredUserList}">
With that, you make sure to keep your filtered table/list in a field in your managed bean and the contents won't get lost.
Also, make sure your Managed Bean class is serializable (See this stackoverflow post)

Two buttons ( that generate inputtexts when clicked ) don't work on the same Facelet

I have two buttons that generate inputtexts when clicked. The problem is, when these two buttons are on the same xhtml, wichever is the first one, it is the only one that works.
If you need, here is an explanation on the Code 1 below:
It represents two inputtexts to get the name
and email of the author of a Document. moreAuthors represents
the method getMoreAuthors() that belongs to the Managed Bean inserirBean.
getMoreAuthors() returns a List<AuthorBean>.
The List<AuthorBean> is a property from the Managed Bean inserirBean.
The class AuthorBean creates the instances of Author, it has a property called
Author author.
AddAuthor() adds one more AuthorBean to the List<AuthorBean> in
Managed Bean inserirBean.
If you need, here is an explanation on the Code 2 below:
It follows the same structure from Code 1. Here, there's only one
inputtext that is used to get a subject of a Document.
moreSubjects returns a List<SubjectBean>. The class SubjectBean
creates the instances of the class Subjects.
SubjectBean has a property Subject sub,
and Subject has a property called String subject.
AddSubject() adds one more SubjectBean to the List<SubjectBean> in
Managed Bean inserirBean.
Code 1- If this is the only one on the xhtml, it works:
<h:form >
<h:dataTable value="#{inserirBean.moreAuthors}" var="authorBean">
<h:column>
Nome do Autor:
<h:inputText value="#{authorBean.author.name}" />
</h:column>
<h:column>
Email do Autor:
<h:inputText value="#{authorBean.author.email}" />
</h:column>
<f:facet name="footer">
<h:panelGroup>
<h:commandButton value="+" action="#{inserirBean.addAuthor()}" />
</h:panelGroup>
</f:facet>
</h:dataTable>
</h:form>
2- If this is the only one on the xhtml, it works too:
<h:form >
<h:dataTable value="#{inserirBean.moreSubjects}" var="subjectBean">
<h:column>
Palavras-chave:
<h:inputText value="#{subjectBean.sub.subject}" />
</h:column>
<f:facet name="footer">
<h:panelGroup>
<h:commandButton value="+" action="#{inserirBean.addSubject}" />
</h:panelGroup>
</f:facet>
</h:dataTable>
</h:form>
BUT, if I put these two blocks on the same xhtml, the one that appears first on the browser, always works, and the second, never - and I've already tried to change their position, but whichever I put first place on screen is the one that works.
What's causing this problem?
Thank you!
I just put the two datatables in code 1 and 2 inside the same <form> block and both worked.

Primefaces dataTable multiple selection same object

I'm having a problem with the dataTable multiple selection with checkbox (like the second one: http://primefaces.org/showcase/ui/datatableRowSelectionRadioCheckbox.jsf).
When I try to execute a method in my backingBean, the selected items always comes with the right size, but, with the same object.
Example: I select in my dataTable three Messages: Message 1, Message 2 and Message 3. When I execute my method in the JSF page my selected items comes like this:
Messages[0] = Message 1
Messages[1] = Message 1
Messages[2] = Message 1
Here is my JSF Page:
<p:dataTable id="mensagensLidas" var="msg" value="#{mensagensBean.msgGrupoModel}"
paginator="true" rows="10" selection="#{mensagensBean.selectedMsgsGrupo}">
<p:column selectionMode="multiple" style="width:2%"/>
<p:column headerText="Titulo:" style="width:49%">
#{msg.titulo}
</p:column>
<f:facet name="footer">
<p:commandButton id="multiViewButton" value="#{msgs.delete}" icon="ui-icon-trash" actionListener="#{mensagensBean.excluirMsgsGrupo}" update=":tabMain" ajax="true"/>
</f:facet>
</p:dataTable>
Your above code is working fine for me except that I'm using a rowKey.
Try using rowKey attribute in p:dataTable
<p:dataTable id="mensagensLidas" var="msg" value="#{mensagensBean.msgGrupoModel}"
paginator="true" rows="10" selection="#{mensagensBean.selectedMsgsGrupo}"
rowKey="#{msg.titulo}">
....
</p:dataTable>
Using rowKey is must and best practice when you have selection in Datables, it helps to map the selected <tr> to the POJOs that you're filling up with.
Usually its even better if your rowKey is unique propety, you can even put an integer variable in your #{msg} POJO as best practice.
I discovered the problem. My DataModel was with the getRowData returning always the same object. I was doing a wrong comparison. Thank you all!

Value of <h:selectBooleanCheckbox> inside <p:dataTable> remains false on submit

I have a primefaces datatable and inside the primefaces datatable, I have a column, which contains the . The issue is,I have set the default value for the as false. When I click/check the , its still retrieving the value as false. I tried it multiple times but not sure why its returning false. Please find the sample code below.
<p:dataTable id="review-table" var="item" value="#{demandBean.filterVOList}">
<p:column id="SelectallID" style="text-align: left; width:40px;" rendered="#{demandBean.screeRenderVo.selectAllRenderer}">
<f:facet name="header" >
<h:outputText id="selectId" value="#{demandBean.dmdScreenLabelVO.selectAll}" />
<div></div>
<h:selectBooleanCheckbox id="checkbox1" value="Select All" onclick="checkAll(this)"/>
</f:facet>
<h:selectBooleanCheckbox id="checkbox2" value="#{item.selected}"/>
</p:column>
Im getting the value as false, when I check the and click on the save button. I have written an Action listerner, below is the code corresponding to the actionListener
public void saveData(ActionEvent event)
{
System.out.println("Entering the Save :");
selected = isSelected();
System.out.println("value of Selected"+selected);
}
I have tried debugging the code as well, but not sure why the value for is getting displayed as false. Please Assist. Thanks in Advance
You seem to be binding the value of all checkboxes in the column to the one and same bean property. This way the value will ultimately end up to be the one of the last row in the column.
This is not how it's supposed to be used.
You basically need to bind the value of the checkbox to the property of the currently iterated row object (the one behind the var attribute of the datatable).
<p:dataTable value="#{bean.items}" var="item">
<p:column>
<p:selectBooleanCheckbox value="#{item.selected}" />
Alternatively, you could use the <p:column selectionMode="multiple" /> to use builtin multiple selection support of the PrimeFaces datatable (see also the showcase example).
<p:dataTable value="#{bean.items}" var="item" rowKey="#{item.id}" selection="#{bean.selectedItems}">
<p:column selectionMode="multiple" />

Resources