How do I get PrimeFaces DataTable to sort? - jsf

I just can't get sorting working. I'm not sure if this should be posted in the Rain forums, because I am just using PrimeFaces for the first time, and purchased/installed the Rain layout. So I'm not sure whether Rain is causing this or not.
I define a standard p:dataTable and use:
<p:column headerText="Name" field="name" filterMatchMode="contains" />
And sort does not work.
Here is my p:dataTable definition:
<p:dataTable id="table" widgetVar="table" stripedRows="true" reflow="true"
value="#{viewBean.dtos}"
var="dto" selection="#{viewBean.dtos}" rowKey="#{dto.id}" paginator="true"
rows="10" rowSelectMode="add">
My PrimeFaces version:
<!-- https://mvnrepository.com/artifact/org.primefaces/primefaces -->
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>10.0.0-RC2</version>
</dependency>

You are using a PrimeFaces version that has some bugs related to sort/filter data tables.
Like this:
DataTable/TreeTable: sortBy not working with client saving state method
You can apply the workarond, but you may face other issues, so
it will be better if you switch to PrimeFaces 11, using the: PrimeFaces migration guide 10.0.0 -> 11.0.0

Related

Primefaces outputlabel behaves as escape = "false"

I am using primefaces 4.0 and I am having problems with p:outputLabel.
When It is mixed with any other primefaces component it behaves like escape="false"
This field is not processed even if I specify escape="true"
Example:
I have the following html code:
<h:form>
<p:outputLabel value="<b>TEXT</b>" escape="true"></p:outputLabel>
<h:outputLabel value="<b>TEXT</b> " escape="true"></h:outputLabel>
</h:form>
And for the Output I have this
<b>TEXT</b> <b>TEXT</b>
Which is expected behavior. (I am willing to see HTML tags as text).
But when I will add any other primefaces tag like in example:
<h:form>
<p:outputLabel value="<b>TEXT</b>" escape="true"></p:outputLabel>
<h:outputLabel value="<b>TEXT</b> " escape="true"></h:outputLabel>
<p:commandButton value="button"></p:commandButton>
</h:form>
Now even I have escape="true" I get
TEXT TEXT and then the button.
Does any one have experience with this how should I fix this.
Any suggestion.
I solved this issue.
I had this into my pom
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>2.1.12</version>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>2.1.12</version>
</dependency>
I just downgraded to 2.1.11 and everything works fine.

primefaces <p:datatable> <p:commandlink> fires another <h:link> accidentally

i got two cases of strange behaviour in my p:dataTable . First when i try to call the h:link with the f:param the link always sends the same id. Always the id from the first entry.
The bigger problem is when i push on the commandbutton the h:link gets called though this behavior was completely not expected. Especially without the right Parameters.
Is this a Bug or am i doing something wrong?
When i delete the h:link everything works like expected.
I would appreciate any help in this matter
My Primefaces Version is 3.5 and im working with Liferay 6.1 on Tomcat 7. With the newest FacesBridge
<h:form id="serviceForm">
<p:dataTable id="newServicesTable" var="service" value="#{cloudServicesBean.newServices}" rowKey="service.serviceId" selection="#{cloudServicesBean.selectedService}">
<p:column headerText="Servicename">
<h:link outcome="/views/cloudservice/overview.xhtml" includeViewParams="true" value="#{service.serviceName}">
<h:outputText value="#{service.serviceId}"/>
<f:param name="selectedServiceId" value="#{service.serviceId}" />
</h:link>
</p:column>
<p:column headerText="Provider">
<h:outputText value="#{adminBean.getOrganizationNameForId(service.providerId)}" />
</p:column>
<p:column headerText="Datum">
<h:outputText value="#{service.createDate}" />
</p:column>
<p:column headerText="Aktionen" rendered="#{adminBean.isUserAdministrator()}">
<p:commandButton icon="ui-icon-check" action="#{cloudServicesBean.setServiceApproved}" update=":serviceForm">
<f:setPropertyActionListener value="#{service}" target="#{cloudServicesBean.selectedService}" />
</p:commandButton>
</p:column>
</p:dataTable>
I had exactly the same problem. I run Primefaces 3.5 with Liferay 6.0.11 on Tomcat 7. When I switched the Liferay JSF dependencies from version 3.1.2.ga3 to 3.1.3-ga4 the issue was resolved.
<dependency>
<groupId>com.liferay.faces</groupId>
<artifactId>liferay-faces-alloy</artifactId>
<version>3.1.3-ga4</version>
</dependency>
<dependency>
<groupId>com.liferay.faces</groupId>
<artifactId>liferay-faces-bridge-impl</artifactId>
<version>3.1.3-ga4</version>
</dependency>
<dependency>
<groupId>com.liferay.faces</groupId>
<artifactId>liferay-faces-portal</artifactId>
<version>3.1.3-ga4</version>

What is the function of #this exactly?

As far as I know the #this is to denote the current component triggering the event, such as :
<p:commandButton process="#this" ... />
And in JSF 2 Ajax, the #this can also mean the encapsulating component, like :
<h:inputText ...>
<f:ajax execute="#this" ... />
</h:inputText>
And I have one case where using p:datatable, including or excluding #this can have a different impact upon Ajax partial submit
Here's the example, in this case, the process is using #this, and this works as expected, where when process happens first, and then followed by setPropertyActionListener and last, the action is executed :
<p:column>
<p:commandLink
value="#{anggaranDetail.map['code']}"
process="#this infoAnggaranForm:Anggaran"
update="detailDialogForm:Anggaran detailDialogForm:SubAnggaran"
oncomplete="infoAnggaranDialog.hide()"
image="ui-icon ui-icon-search"
action="#{tInputBean.updateAnggaranSubAnggaran}">
<f:setPropertyActionListener value="#{anggaranDetail}"
target="#{infoAnggaranBean.selectedAnggaranDetail}" />
</p:commandLink>
</p:column>
But when I omit the #this from this example, the setPropertyActionListener and the action are never executed, as if they're not there.
I wonder why ? Perhaps #this has some other meaning other than the current component, perhaps the current record in this example ?
Im using tomcat 7, and these are my dependencies :
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>2.0.4-b09</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>2.0.4-b09</version>
<scope>compile</scope>
</dependency>
The PrimeFaces process and standard JSF execute attributes should point to spaceseparated component identifiers of components which JSF should process during the entire JSF lifecycle upon an ajax request (get request parameters, validate them, update model, execute action). The process defaults to #form, the current form, and the execute defaults to #this, the current component. In command links/buttons this is mandatory to execute the actions associated with the link/button itself.
However, in your datatable you have process="#this infoAnggaranForm:Anggaran", thus two components to process. If you omit #this but keep the other component, then it will only process/execute the other component and not the link/button component. If you omit the process attribute it will default to #form. If you have more other input components in the same form, then they will also be processed.
Depending on the concrete functional requirement, you could just keep it process="#this infoAnggaranForm:Anggaran", or omit it. JSF will then process/execute at least both the button and the other component, exactly as you want.
See also:
Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes

Partial Rendering will only work with #form?

I have a strange situation where using #parent, or even explicit id-s dont work in the update attribute. But #form works fine.
I've made a very simple test case, that includes a simple grid whose behaviour is like this :
Every record inside the grid has a modify button
After the modify button is clicked, it'll modify the server data, and the button will be gone, since it'll be only rendered if the record has NOT been modified.
The modify button is like this :
<!-- this works, since it's using #form in the update attribute -->
<p:column>
<p:commandLink
value="modify record"
process="#this"
action="#{testUserBean.modifyRecord(user)}"
update="#form"
rendered="#{not testUserBean.isRecordModified(user)}" />
</p:column>
Notice that the update attribute makes use of #form which makes it work: when the modify button is clicked, it rerenders and disappears.
Substitute it with #this or #parent or the id of the grid, then it will NOT work. For me it's very logical to use the id of the grid in the update attribute, since i would like to refresh the grid after clicking on the buttton.
I tried making use of rowIndexVar="rowIndex" and myGridId:#{rowIndex}:link, but still aint working.
<!-- this does not work -->
<p:column>
<p:commandLink id="link"
value="modify record"
process="#this"
action="#{testUserBean.modifyRecord(user)}"
update="tblUser"
rendered="#{not testUserBean.isRecordModified(user)}" />
</p:column>
Here are the resources for this simple example :
The xhtml file
The JSF Bean file
The user POJO bean
Im using tomcat 7, and these are my dependencies :
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>2.0.4-b09</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>2.0.4-b09</version>
<scope>compile</scope>
</dependency>
Tried out primefaces 3.0.M1 also, but it got the same behavior also.
Please share your ideas. Is this a bug or i did something wrong ?
UPDATE
Hello,
I've just finished some testing, but all still fails.
Test 1 (making use of update=":gridRPBDetails") :
The JSF File :
<p:commandLink id="undoLink" value="Undo" process="#this"
action="#{tInputBean.actionUndoRemoveRecord(rpbDetail)}"
update=":gridRPBDetails"
rendered="#{tInputBean.isRemoveRecord(rpbDetail)}"
title="Batalkan buang data" />
The generated xhtml :
<a title="Batalkan buang data" onclick="PrimeFaces.ajax.AjaxRequest('/cashbank/faces/TInput.xhtml',
{formId:'j_idt38',async:false,global:true,source:'gridRPBDetails:0:undoLink',
process:'gridRPBDetails:0:undoLink',update:':gridRPBDetails'});"
href="javascript:void(0);" id="gridRPBDetails:0:undoLink">Undo</a>
Test 2 (making use of update=":gridRPBDetails:#{rowIndex}:undoLink") :
The JSF File :
<p:commandLink id="undoLink" value="Undo" process="#this"
action="#{tInputBean.actionUndoRemoveRecord(rpbDetail)}"
update=":gridRPBDetails:#{rowIndex}:undoLink"
rendered="#{tInputBean.isRemoveRecord(rpbDetail)}"
title="Batalkan buang data" />
The generated xhtml :
<a title="Batalkan buang data" onclick="PrimeFaces.ajax.AjaxRequest('/cashbank/faces/TInput.xhtml',
{formId:'j_idt38',async:false,global:true,source:'gridRPBDetails:0:undoLink',
process:'gridRPBDetails:0:undoLink',update:':gridRPBDetails:0:undoLink'});"
href="javascript:void(0);" id="gridRPBDetails:0:undoLink">Undo</a>
Both tests still fail in terms of clicking the undo button cannot refresh the record of the grid, or even the grid itself.
UPDATE
I've just updated my test using :
<p:commandLink
value="modify record"
process="#this"
action="#{testUserBean.modifyRecord(user)}"
update=":mainForm:tblUser"
rendered="#{not testUserBean.isRecordModified(user)}" />
Notice i used the :mainForm:tblUser, and i've tried the other options and still failed :
:mainForm:tblUser:
:tblUser (when i dont define the form name)
:mainForm:tblUser:#{rowIndex}:linkId
But 1 thing i notice is,nNo matter what i choosed for the update, the update always ends up as tblUser:0
<a onclick="PrimeFaces.ajax.AjaxRequest('/cashbank/faces/test.xhtml',
{formId:'mainForm',async:false,global:true,source:'tblUser:0:j_idt33',
process:'tblUser:0:j_idt33',
update:'tblUser:0'
});" href="javascript:void(0);" id="tblUser:0:j_idt33">modify record</a>
I tried modifying tblUser:0 on the fly using firebug to just tblUser, the partial rendering on the grid works fine.
Im beginning to think that this is a bug when trying to update a grid from inside a grid record.
This has been answered in here.
Here is the quote from the answer :
This is more like a mojarra issue, it should work fine with myfaces
without a wrapper. Workaround is to put a wrapper.
Code:
<h:form id="frm">
<p:outputPanel id="wrapper">
<p:dataTable id="tbl">
//...
<p:commandButton update=":frm:wrapper" />
//...
<p:dataTable>
<p:outputPanel>
</h:form>
Sorry for the late update !
Look at the generated HTML. Since the <p:commandLink> is placed in a <p:dataTable>, its generated client ID is something like this
<a id="someformid:tblUser:0:link">
The 0 is the table row index.
So when you use the relative identifier update="tblUser" on <p:commandLink>, then it will basically search for someformid:tblUser:0:tblUser to update. But this does not exist. You'd like to use an absolute identifier instead, starting with :.
<p:commandLink update=":someformid:tblUser">
<p:dataTable id="mytable"
value="#{dataTableWithLinkBean.list}" var="item">
<p:column>
<f:facet name="header">
Code
</f:facet>
<p:commandLink actionListener="#{dataTableWithLinkBean.viewDetail}"
oncomplete="dlg.show()" process="#this"
update=":mainform:dialog_content">
<h:outputText value="#{item.code}"/>
<f:param name="code" value="#{item.code}"/>
</p:commandLink>
</p:column>
</p:dataTable>
<p:dialog widgetVar="dlg" modal="true" id="dialog"
width="300" height="300">
<h:panelGrid id="dialog_content">
<h:outputText value="#{dataTableWithLinkBean.selectedCode}"/>
</h:panelGrid>
</p:dialog>
Above is the example of link in the datatable that render the dialog.
may be you can try to change
update=":mainform:dialog_content"
to
update=":mainform:mytable"
in this case my tag form is using id mainform, shown as below:
Please note that I've not been trying this. I just have used in my example above to rendering the dialog panel partially. Good luck
Update:
Well I give it a try like this, combine with your updated post
<p:dataTable id="mytable"
value="#{dataTableWithLinkBean.list}" var="item">
<p:column>
<f:facet name="header">
Code
</f:facet>
<h:outputText value="#{item.code}"/>
</p:column>
<p:column>
<p:commandLink value="Modify"
action="#{dataTableWithLinkBean.removeDetail(item)}"
process="#this"
update="mytable"
rendered="#{not dataTableWithLinkBean.isModifier(item)}">
</p:commandLink>
</p:column>
</p:dataTable>
And in the backing bean
public String removeDetail(ClassForTest item){
for(ClassForTest o: list){
if(o.equals(item)){
//do something update to database
item.setModified(true);
break;
}
}
return "";
}
public boolean isModifier(ClassForTest item){
return item.isModified();
}
And it's worked! after I click on the modify button, call the removeDetail method, do some actions, update the modified status. then do update="mytable", and the link modify is gone.
I'm using Mojarra 2.0.4 and primefaces 3.0.M2
FYI, I'm using DataModel in the backing bean, just a simple List
so no rowIndexVar. Maybe when using the DataModel, can produce this problem.

JSF command button attribute is transferred incorrectly

I have following code in jsf page, backed by jsf managed bean
<h:dataTable value="#{poolBean.pools}" var="item">
<h:column>
<f:facet name="header">
<h:outputLabel value="Id"/>
</f:facet>
<h:outputText value="#{item.id}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputLabel value="Start Range"/>
</f:facet>
<h:inputText value="#{item.startRange}" required="true"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="End Range"/>
</f:facet>
<h:inputText value="#{item.endRange}" required="true"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Pool type"/>
</f:facet>
<h:selectOneMenu value="#{item.poolType}" required="true">
<f:selectItems value="#{poolBean.poolTypesMenu}"/>
</h:selectOneMenu>
</h:column>
<h:column>
<f:facet name="header"/>
<h:commandButton id="ModifyPool" actionListener="#{poolBean.updatePool}" image="img/update.gif" title="Modify Pool">
<f:attribute name="pool" value="#{item}"/>
</h:commandButton>
</h:column>
</h:dataTable>
This code fragment is dedicated to editing come collection of items. Each row of the table contains "edit" button that submits changed values of the row to the server. It has the item itself as an attribute. Submit is performed by calling actionListener method in the backing managed bean.
This code runs correctly on Glassfish v 2.1
But when the server was updated to Glassfish v 2.1.1, the attribute stopped to be passed correctly. Instead of passing edited item (when we change the values in table row, we are actually changing the underlying object fields), the source item is submitted to server, i.e. the item that was previously given to the page. All the changes that were made on the page are discarded.
I tried to update jsf version from 1.2_02 to 1.2_14 (we are using jsf RI), but it had no effect.
Perhaps anyone came across the same problem? Any help and suggestions will be appreciated.
Glassfish ships with bundled JSF. Glassfish v2.1.1 ships with Mojarra 1.2_13. You actually don't need to have your own JSF libs in the /WEB-INF/lib. I am not sure how this particular problem is caused, but to start, you need to ensure that you don't have JSF version collisions in the classpath.
That said, the preferred JSF 1.2 way of passing bean properties is using f:setPropertyActionListener.
<h:commandButton id="ModifyPool" actionListener="#{poolBean.updatePool}" image="img/update.gif" title="Modify Pool">
<f:setPropertyActionListener target="#{poolBean.pool}" value="#{item}"/>
</h:commandButton>
Update: I recall something; this problem suggests that you still have a JSF 1.2 version older than 1.2_05 around in the classpath. Handling of component attributes has changed as per this version in favour of performance enhancements. In a nutshell, if you have a jsf-api.jar of older than 1.2_05 in your classpath, while there's a jsf-impl.jar of 1.2_05 or newer in your classpath, you will experience exactly this problem.
The solution is obvious: cleanup your classpath to get rid of the older JSF version. Paths covered by the webapp's default classpath are under each /WEB-INF/lib, Appserver/lib (which is in case of Glassfish somewhere in Appserver/domains/domainname/*) and the JRE/lib and JRE/lib/ext. Keep in mind that Glassfish's javaee.jar includes JSF libraries as well, so you really need to ensure that you don't have that JAR (or any other appserver-specific JAR file) in your /WEB-INF/lib or somewhere else.
You can add JBoss EL and write:
#{poolBean.updatePool(item)}
You don't need the whole Seam for that, works fine with JSF RI.
Probably it has to do with the way JSF 1.2 implements actionListener.
In JSF 1.1 and until recent implementations of JSF 1.2 (Richfaces, Trinidad etc) the order was setPropertyActionListener (or Attribute) -> actionListener -> action.
In JSF 1.2 and now implemented in Richfaces and Trinidad (not sure about IceFaces) the order is actionListener -> setPropertyActionListener (or Attribute) -> action.
I know it is disturbing and very annoying...
Who thought of it? What did they have in mind?
Anyway, try using an action instead of an actionListener and see if it works.

Resources