Use Enum for filtering in p:dataTable - jsf

How to use an Enum to filter in p:dataTable?
My approach looks like this:
<p:column filterBy="#{item.EMyEnum}" filterMatchMode="in" >
<f:facet name="filter">
<p:selectCheckboxMenu label="Select" onchange="PF('datatable').filter()">
<f:selectItems value="#{MyEnum.values()}" />
<p:ajax event="toggleSelect" onsuccess="PF('datatable').filter()"/>
</p:selectCheckboxMenu>
</f:facet>
<h:outputText value="#{item.EMyEnum}"/>
</p:column>
Everything looks fine, but when I select one item from the drop down, the whole content is filtered. When I deselect everything in the drop down, then the content comes up again, so basically the filter seems to work, but every comparison is evaluated to false. I do not understand why, as JSF has build in Enum-converters hasn't it? But what am I missing or doing wrong here?
I am working with PF 5.1 on Mojarra 2.1.29
I solved my problem with usage of a List of my Enum types in combination with the OmniFaces GenericEnumConverter. This works like charm, but I'd still like to know what exactly the problem with the previous solution is and how it could be fixed.

Related

Conditionally apply AJAX events to datatable rows

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>

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

JSF - Richfaces 3.3.3 rich datatable - Both sorting and filtering with two headers?

I'm trying to add a filter to the header of each column in an existing rich:datatable in JSF. I used the Exadel demo to add the filters, which worked out just fine, but it also removed the sort functionality from the upper header. I'd like to keep the sort function in the upper label header and filter on the second inputText header.
As a quick and dirty example, this is the basic structure:
<rich:dataTable id="thetable" value="#{stuff.list}" var="s">
<f:facet name="header">
<rich:columnGroup>
<rich:column sortBy="#{s.field1}">
<h:outputText="Field 1" />
</rich:column>
</rich:columnGroup>
</f:facet>
<rich:column>
<f:facet name="header">
<h:inputText value="#{stuffSorter.field1}">
<a4j:support event="onkeyup" reRender="thetable" ignoreDupResponses="true"
requestDelay="700" onComplete"setCaretToEnd(event);" />
</h:inputText>
</f:facet>
</rich:column>
</rich:dataTable>
There would be more columns, of course, and setCaretToEnd is just a Javascript function that keeps the caret at the end of the column filter. This is almost just right. I get two headers. The one at the top is the column label, the one just below is the filter, and the results are listed below that. I've built out the filtering class and it's working splendidly. However, I can't seem to find a way to get the sort function back into the topmost header. It does work if I put the "sortBy" field next to the filter box, but I'd much rather have it above, but it seems that the data being inserted in the filter column is preventing that.
Am I missing something here, or is this just not quite possible with a rich:dataTable? I'd be okay with the name + sort and then the filter on top of each other within the same header, but I'm not having luck with that, either. Trying to put both elements into the facet (outputText and inputText) never shows the outputText, even when wrapping them individually with an s:div. I'd use a bean for sorting, but strangely, the project I'm working in is using Richfaces 3.3.3 and lacks org.richfaces.component.SortOrder, although it has a number of other items within the richfaces-ui-3.3.3-final.jar.
In Richfaces 3.3, header and filter facet are supported. The content which you put in the header facet will appear at the top. Filter code you can place inside the filter facet which will appear below header. Please check this questions :Filter Facet is not working in Richface 4.3x, old format of richfaces 3.3 is shown there.
<f:facet name="filter">
</f:facet>

p:dataList inside of p:dataTable

I'm using <p:dataTable> to show the values of my files. Inside of each file is a list of metadates. I want to show each metadate as an own column beside the other columns of the file. (I excluded the other columns to make the code more readable).
So, my problem is, that with the <p:dataList> it does not show the columns. The name of the meta is the same in every metadata, if someone believes this to be the problem.
I already tried to use <p:dataTable> instead of <p:dataList>, but as my customer originally wanted to have the metadata shown as own column this would not be my preferred way, but on the other hand it is working.
<p:dataTable id="fileList" var="f" value="#{reader.files}" rendered="#{reader.showFileTable()}">
<p:dataList value="#{f.meta}" var="meta1">
<p:column>
#{meta1.value}
</p:column>
</p:dataList>
<p:column headerText="Metadaten">
<p:dataTable value="#{f.meta}" var="meta">
<p:column headerText="#{meta.name}">
#{meta.value}
</p:column>
</p:dataTable>
</p:column>
</p:dataTable>
I am really grateful for any help, how I could make the code work so that each metadate has it's own column in the fileList-dataTable.
P.S: I already tried c:forEach and ui:repeat which also didn't work.
P.P.S: I forgot to mention, that my customer sometimes don't want to see specific metadates, so it would be very nice when it is possible to do this with the suggested solution.
You can build columns dynamically in primefaces by using the <p:columns> tag see the vdl
check the primefaces showcase for an example
Suppose you have this code:
<p:dataList id="fileList" var="f" value="#{reader.files}">
<p:dataTable value="#{f.listItems}" var="meta1">
<p:column>#{meta1.value}</p:column>
<p:columns value="#{meta1.listItems}">...</p:columns>
</p:dataTable>
</p:dataList>
Dynamic columns in nested dataTable are not generated: it seems p:columns cannot refer var like "f" and "meta1".
I can understand "meta1" is not visible, because it's producing header's table, but I really can't understand why "f" is not visible at that time.
Any idea? Thanks.

What makes my richfaces combobox not working after first usage?

I'm currently using JSF 1.2, and Richfaces 3.3.3.
I get a quite strange bug with a combobox in a rich:datatable :
The first time I click and select a value, it's working, and via ajax:support, it updates the page as required. But then, if I try to change the value in the combobox, it seems "blocked"... field is not editable, and the arrow not "clickable". If I click on another field of the page, then come back, it usually works better (but not always).
Here is the code :
<rich:column style="border:none;" id="KitCol">
<f:facet name="header">
<h:outputText value="Kit"/>
</f:facet>
<rich:comboBox id="kit" value="#{deployItem.kit}"
directInputSuggestions="true" defaultLabel="Enter kit name >
<f:selectItems value="#{deployItem.kits}" />
<a4j:support event="onchange" action="#{deployItem.kitChanged}"
reRender="deployActions, deployTable">
<f:setPropertyActionListener value="true" target="#{deployController.atLeastOneItem}" />
</a4j:support>
</rich:comboBox>
</rich:column>
Would somebody have an idea about how to solve this issue ?
Thanks in advance.

Resources