Conditionally apply AJAX events to datatable rows - jsf

I'm relatively new to JSF and Primefaces, but I've been tasked to try and reduce the amount of AJAX requests made in a legacy codebase. This question is from a particular example where we have a directory listing UI of files and folders.
<p:dataTable id="directoryTable" var="directoryObject" value="#{fileCabinet.folderContents}"
resizableColumns="true" scrollable="true"
rowKey="#{directoryObject}" selectionMode="single"
selection="#{fileCabinet.currentObject}" dblClickSelect="true"
sortMode="multiple" emptyMessage="This folder is empty"
sortFunction="#{dataTableUtil.sort}">
<c:if test="#{directoryObject.objectType eq 'DIRECTORY'}">
<p:ajax event="rowSelect" listener="#{fileCabinet.onRowSelect}"
update=":form:directoryTable :menu" />
</c:if>
I've excluded the rest of the datatable for brevity. With this code, the ajax event is never attached even though the 'test' expression evaluates perfectly fine in subsequent 'rendered' attributes of html elements later on. Unfortunately, p:ajax doesn't support 'rendered' conditionals.
I've also tried c:choose / c:when, to the same results.
This feels like something that should be really easy to do! I'm probably missing some simple syntax to make this work.
Thanks!

I fixed this by using the disabled attribute for <p:ajax> with my conditional as the value (negated of course).
<p:ajax event="rowSelect"
listener="#{fileCabinet.onRowSelect}"
update=":form:directoryTable :menu"
disabled="#{directoryObject.objectType ne 'DIRECTORY'}" />

Since 4.0 version, Primefaces datatable comes with a disabledSelection property.
<p:dataTable var="foo" value="#{bean.foos}" selection="#{bean.selectedFoo}" disabledSelection="#{foo.bar == 1}">
<p:column selectionMode="single" />
<p:column>
<h:outputText value="#{foo.bar}" />
</p:column>
<p:dataTable>

Related

p:datatable component is not sorting, only when I filter it before

Im trying to present my data from a mysql Database in a Datatable, and its all working, now i was trying to include a filter and sorting functionality, but when I test it and press the sorting arrows, nothing happens, only when I filter the datatable first, and then everything works fine.
I tried it with the primeface Attributes filterBy and sortBy, and because of the existing functionality I think it has something to do with a update-Problem
<p:dataTable id="test3" scrollable="true" scrollHeight="150" var="Foo" value="#{Foo.bar}">
<p:column headerText="#{msg['default-description-key']}"
sortBy="#{Foo.keyString}"
filterBy="#{Foo.keyString}">
<p:outputLabel value="#{Foo.keyString}"
style="float:center"/>
</p:column>
<p:column headerText="#{msg['default-description-count']}"
sortBy="#{Foo.count}" filterBy="#{Foo.count}">
<p:outputLabel value="#{Foo.count}"
style="float:center"/>
</p:column>
<p:column headerText="#{msg['default-description-register.key']}">
<p:commandLink value="#{msg['default-description-
register.key.link']}" action="#{Foo.bar(Foo.keyString)}"/>
</p:column>
</p:dataTable>
I want to be able to sort the datatable without the need of filtering it before
Create a separate list in your bean (don't forget getter and setter) and link it to the attribute filteredValue in the p:dataTable component
Place the table inside h:form
Use h:outputText instead of p:outputLabel

<rowExpansion> evaluated during JSF phases

I have a datatable using rowExpansion.
When the page is loaded, the rowExpansion is not evaluated, which is fine.
When the paginator is used to show the next results or if a submission is done - the rowExpansion evaluation is triggered.
Here is a XHTML example :
<h:form>
<p:dataTable var="data" value="#{bean.dataList}" paginator="true">
<p:column headerText="Details">
<p:rowToggler />
</p:column>
<p:rowExpansion>
<h:panelGroup rendered="#{not empty data.detail}">
<ui:include src="dataDetail.xhtml" />
</h:panelGroup>
</p:rowExpansion>
</p:dataTable>
<h:commandLink id="addData" value="Add data" action="#{bean.addData}" />
</h:form>
I've profiled this flow using visualVM, and used the debugger, to discover that the data.getDetail() method was called during the following JSF phases : (ApplyRequestValuesPhase, ProcessValidationsPhase, UpdateModelValuesPhase), when the paginator was used.
I've come to the deduction that the rowExpansion is part of the view, and is evaluated as a normal component.
Would you mind telling me if it is the expected behaviour for rowExpansion ?
Is there a correct way to prevent the evaluation of the rowExpansion content when using the paginator ?
Thanks for your answers.
NB : I'm using PrimeFaces 5.2.

Primefaces update table from another form

I want refresh my lazytable from another from. I have the following xhtml:
<h:form id="tableform">
<p:remoteCommand name="updateTable" update="table" />
<p:dataTable widgetVar="tableWidget" id="table"
selection="#{personBean.selectedPerson}" selectionMode="single"
lazy="true" paginator="true" var="person" rowKey="#{person.id}"
value="#{personBean.personModel}" paginatorPosition="bottom" rows="5"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}">
<p:column filterBy="#{person.name}" headerText="Names:"
sortBy="#{person.name}">
<h:outputText value="#{person.name}" />
</p:column>
</p:dataTable>
<p:commandButton value="buttonInForm2" update=":tableform" />
<p:commandButton value="buttonInForm" update="#form" />
</h:form>
<h:form>
<p:commandButton value="directUpdate" update=":tableform" />
<p:commandButton value="directUpdate" update=":tableform:table" />
<p:commandButton value="remoteCommand" oncomplete="updateTable()" />
</h:form>
The remoteCommand (my current solution) and the buttons in the from refresh the table right. But when i use the "directUpdate"- buttons the filtertext of the table disappear. But i dont understand why? (The filter value stays at the background but the text is empty)
I know that i can use widgetVar.filter() on table but than the paginator will be reseted. My solution is the remoteCommand with it all works fine and the table reloads with current page and filter. (Better solutions are welcome)
The question why reset directUpdate the text and an update in the form not?
Thanks for time.
The <p:dataTable> has its own hidden inputs for among others pagination, selection and filtering so that the server side knows the client side state. This way it can prepare and return the same state as it is in the client side.
If you submit a certain form, only the inputs contained in the particular form will be sent, not from other forms. This is not a JSF specific problem. HTML has always worked that way. The world wide web would otherwise have looked very different.
With invoking the <p:remoteCommand> from outside the form, you're basically submitting the "right" form, namely the one it is contained in which also covers the data table.
Do note that you don't need a <p:commandButton> for it per se, just a simple <p:button ... onclick="updateTable(); return false;"> is already sufficient. Even the whole second form is unnecessary for the job.

Primefaces Datable liveScroll + lazy loading - filter not working

Using PrimeFaces 5.0.
My datatable uses lazy loading and live scrolling and I try to filter both fields:
<p:dataTable id="eventsTable" value="#{eventController.eventModel}" var="event" lazy="true"
scrollRows="100" liveScroll="true" scrollable="true" scrollHeight="500">
<p:column headerText="EID" filterBy="#{enent.eid}">
<h:outputText value="#{event.eid}" />
</p:column>
<p:column headerText="Type" filterBy="#{event.type}">
<h:outputText value="#{event.type}" />
</p:column>
</p:dataTable>
The initial load retrieves data correctly, and live scrolling seems to work fine.
But when I try to filter one of the fields the datatable is completely emptied (It does not even show the "No records found" message). When I debug I can see that my queries are executed correctly and return data.
Also, If I switch using paging instead of liveScroll, pages are lazy loaded correctly and filters also work.
Any thoughts?
You must set the rows attribute of the datatable.

Filtering issues (no change in contents) in datatable primefaces 3.5, sorting works

Primefaces 3.5 doesn't seem to filter data at all from the datatable, oddly enough it somehow reorders them as I type, so, there must be some AJAX calls firing, but obviously not the right ones.
<h:panelGroup id="table-wrapper-component">
<prime:dataTable
rendered="#{artifactSelectionBackingBean.visibleComps}"
value="#{artifactSelectionBackingBean.components}"
var="tagInfoObject" emptyMessage="No tags found with given criteria"
filteredValue="#{artifactSelectionBackingBean.filteredComponents}">
<prime:ajax event="filter" global="false" />
<prime:column sortBy="#{tagInfoObject.tagId}"
headerText="Identifier" filterMatchMode="contains" filterBy = "#{tagInfoObject.tagId}">
<h:outputText value="#{tagInfoObject.tagId}" />
</prime:column>
<prime:column sortBy="#{tagInfoObject.type.tagTypeId}"
headerText="Tag Identifier" filterMatchMode="contains" filterBy ="#{tagInfoObject.type.tagTypeId}">
<h:outputText value="#{tagInfoObject.type.tagTypeId}" />
</prime:column>
<prime:column sortBy="#{tagInfoObject.title}" headerText="Title" filterMatchMode="contains" filterBy="#{tagInfoObject.title}">
<h:outputText value="#{tagInfoObject.title}" />
</prime:column>
<prime:column filterBy="#{tagInfoObject.description}"
filterMatchMode="contains" sortBy="#{tagInfoObject.description}"
styleClass="wrap" headerText="Component Description">
<h:outputText value="#{tagInfoObject.description}" />
</prime:column>
</prime:dataTable>
</h:panelGroup>
Any help is appreciated! All the Beans and method calls exist and return the appropriate data, just that the filtering doesn't seem to work at all.
Also, note that sorting functions properly only filtering does not!
The issue was that you always need to wrap any filtering/sorting attributes in a data table with an h:form tag. This is not explicitly specified in the documentation of PrimeFaces, however, it is in the showcase here. I wrapped the whole thing in form tags.
So, don't forget to wrap your data tables in a form if you want any type of interaction provided by primefaces.
Your managed Bean Code will do a lot of good
Post your managed bean code.
May be you have not set the value for artifactSelectionBackingBean.filteredComponents in the managed bean

Resources