p:dataTable sortBy not working - sorting

<p:dataTable value="#{externalUsersBean.usersList}" var="user" paginator="true" rows="25">
<p:column headerText="UID" sortBy="#{user.uid}">
<h:outputText value="#{user.uid}"/>
</p:column>
<p:column headerText="Username" sortBy="#{user.username}">
<h:outputText value="#{user.username}"/>
</p:column>
...
...
</p:dataTable>
I tried changing scope in the bean to ViewScoped, yet not working.
I tried using sortBy="uid" syntax, yet not working.
I can't understand what I'm doing wrong.

Related

p:datatable displayed wrongly after ajax update

I have problem with a primefaces datable, I have a filter on a column and before to filter the result my datatable is displayed properly like this:
When I choose a filter, the combobox of the filter is properly poulated:
A soon I choose the item for the filter, the results are properly filtered but I have a display of the datatable like this:
I just see the results who should be display in a datatable but the table is gone.
The code seems good and I don't see where is the problem:
<p:outputPanel autoUpdate="true" class="ui-g-12">
<div class="card">
<h1>Gestion des noeuds</h1>
<h:form>
<p:dataTable value="#{nodeController.nodes}"
var="node"
tableStyle="table-layout: auto;"
rowKey="#{node.nodeId}"
paginator="true"
paginatorPosition="bottom"
paginatorAlwaysVisible="false"
rows="15"
widgetVar="nodeTable"
filteredValue="#{nodeController.filterNodes}"
editable="true"
selection="#{nodeController.selectedNode}"
selectionMode="single"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}">
<p:column headerText="ID">
<h:outputText value="#{node.nodeId}"/>
</p:column>
<p:column headerText="Nom">
<h:outputText value="#{node.modeName}"/>
</p:column>
<p:column headerText="Description">
<h:outputText value="#{node.nodeDescription}"/>
</p:column>
<p:column filterBy="#{node.typeNodeId}" filterMatchMode="exact" headerText="Type">
<f:facet name="filter">
<p:selectOneMenu onchange="PF('nodeTable').filter()">
<f:selectItem itemLabel="filtre" itemValue="#{null}" noSelectionOption="true"/>
<f:selectItems value="#{nodeController.nodeTypes}"/>
</p:selectOneMenu>
</f:facet>
<h:outputText value="#{node.typeNodeId}"/>
</p:column>
<p:column headerText="IPv4">
<h:outputText value="#{node.ipv4}"/>
</p:column>
<p:column headerText="IPv6">
<h:outputText value="#{node.ipv6}"/>
</p:column>
<p:column headerText="powwo agent">
<h:selectBooleanCheckbox value="#{node.agentInstalled}"/>
</p:column>
<p:column headerText="Network status" style="text-align:center">
<p:graphicImage rendered="#{node.isconnected}" name="images/ConnectionStatus25.png" library="omega-layout" width="20"/>
<p:graphicImage rendered="#{!node.isconnected}" name="images/Siren-25.png" library="omega-layout" width="20"/>
</p:column>
<p:column>
<p:rowEditor/>
</p:column>
</p:dataTable>
<p:commandButton value="effacer"
update="msg"
actionListener="#{nodeController.deleteSelectedNode()}"
style="width:auto;margin-bottom:10px;margin-top: 10px"/>
</h:form>
</div>
</p:outputPanel>
Did you already meet this issue with the rendered of a datable? Any idea how to fix it?
Effectively, your title and first sentence are not correct. It is not a bug in the datatable but a 'bug' in your code. You should not use autoupdate="true" on the p:outputPanel in this case. It updates all its content on each ajax update that happens inside it, including an ajax update during filtering. This latter also updates the datatable which means two conflicting updates. Off-topic: If you'd created a Minimal, Complete, and Verifiable example , you'd have found this out during removal of code.
If you have this problem when you have an ajax listener on one of the filter/page/sort/... events on the datatable and you need the autoUpdate="true" on the panel for other events in the wrapping panel, you could also prevent the autoUpdate to happen for these specific events by adding a ignoreAutoUpdate="true" to the specific events. So e.g.
<p:ajax event="filter" ignoreAutoUpdate="true" ... />

p:dataTable sorting and filtering error

I've made globalFilter in the header of dataTable and then added sorting to columns. But there is a problem: the columns becoming sortable after the first time I use the filter.
So when the program starts user need to clear already empty filter control and after that can sort data in the table.
Please,could someone recommend me how to solve the problem?
I've made filter like in example on PrimeFaces showcase.
<p:dataTable id="dtParkType"
widgetVar="w_dtParkType"
var="parkTypeWeb"
value="#{parkTypeHolder.data}"
selectionMode= "single"
selection="#{parkTypeController.selectedItem}"
rowKey="#{parkTypeWeb.id}"
emptyMessage="#{msg['common.NoValue']}"
rowStyleClass="#{parkTypeWeb.isDeleted? 'colored' : null}"
filteredValue="#{parkTypeController.filteredData}"
scrollable="true"
scrollRows="27"
paginator="true"
rows="27"
resizableColumns="true">
<f:facet name="header">
<div align="right">
<p:outputPanel>
<h:outputText value="#{msg['edit.Search']}"/>
<p:inputText id="globalFilter"
onkeyup="PF('w_dtParkType').filter()"
style="width:150px;margin-left:5px;"
placeholder="#{msg['common.PlaceHolder.KeyWord']}"/>
</p:outputPanel>
</div>
</f:facet>
<p:ajax event="rowSelect"
listener="#{parkTypeController.onRowSelect}"
update=":rightForm:panelbtnParkType"/>
<p:ajax event="rowDblselect"
listener="#{parkTypeController.callEditForm}"
update=":formEditParkType:pnlEditParkType"/>
<p:ajax event="rowUnselect" update=":rightForm:panelbtnParkType"/>
<p:column filterBy="#{parkTypeWeb.longName}"
filterMatchMode="contains"
filterStyle="display:none"
sortBy="#{parkTypeWeb.longName}">
<f:facet name="header">
<h:outputText value="#{msg['column.Title.Full']}"/>
</f:facet>
<h:outputText value="#{parkTypeWeb.longName}"/>
</p:column>
<p:column filterBy="#{parkTypeWeb.shortName}"
filterMatchMode="contains"
filterStyle="display:none"
sortBy="#{parkTypeWeb.shortName}">
<f:facet name="header">
<h:outputText value="#{msg['column.Title.Short']}"/>
</f:facet>
<h:outputText value="#{parkTypeWeb.shortName}" />
</p:column>
</p:dataTable>

How to realize rowToggle in primefaces 3.3?

I'm now using primefaces 3.3, but this version doesn't support event="rawToggle" for datatable. So I chose to use the onExpandStart instead of rowToggle, but I met with another problem. Here I want to put another datatable as the expanded row, so everytime I toggle one row in nodetable, I need to pass the nodeId of that row to backingbean to get all the contents of that node. If I have event="rowToggle", I can do it without any problem! But if I use the attribute onExpandStart of the dataTable, I cannot get the somenode.nodeId in the backingbean, anyone knows how to solve it?
I've also tried to put a hidden input tag <input type="hidden" name="hidden" value="#{somenode.nodeId}"/> inside the rowToggler, but the value I get in backingbean is null.
Have been worked on it for several days, but still no ideas. Help please please please!
<p:dataTable id="nodetable" value="#{nodeedit.list}" var="somenode"
styleClass="datatable" editable="true"
onExpandStart="#{nodeedit.toggle(somenode.nodeId)}" >
<p:ajax event="rowEdit" listener="#{nodeedit.save('node')}"/>
<p:column style="width:4%">
<p:rowToggler>
<h:form>
<input type="hidden" name="hidden" value="#{somenode.nodeId}"/>
</h:form>
</p:rowToggler>
</p:column>
<p:column>
<f:facet name="header">ID</f:facet>
<h:form>
<h:commandLink action="nodeedit">#{somenode.norder}</h:commandLink>
</h:form>
</p:column>
<p:column headerText="Name">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{somenode.title}" />
</f:facet>
<f:facet name="input">
<p:inputTextarea value="#{somenode.title}" style="width:100%"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Edit" style="width:50px">
<p:rowEditor />
</p:column>
<p:rowExpansion>
<p:dataTable id="contentId" var="content"
value="#{nodeedit.contents}" id="contents" editable="true">
<p:ajax event="rowEdit" listener="#{nodeedit.save('content')}"/>
<p:column headerText="Text" style="width:450px">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{content.text}" escape="false" />
</f:facet>
<f:facet name="input">
<p:inputTextarea value="#{content.text}" style="width:100%"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Edit" style="width:50px">
<p:rowEditor />
</p:column>
</p:dataTable>
</p:rowExpansion>
</p:dataTable>
I have also tried another way. The Content of a Node is also an object, in the Node Class I have defined
List<LibContent> contents = new ArrayList<LibContent>();
so, like what siebzOr said, I wrote in my jsf something like:
<p:rowExpansion>
<p:dataTable var="content" value="#{somenode.content}">
**<p:ajax event="rowEdit" listener="#{nodeedit.save()}"/>**
<p:column>
<h:outputText value="#{content.someValue}" />
</p:column>
<!-- Other columns -->
</p:dataTable>
</p:rowExpansion>
and in backingbean nodeedit, I have
public void save() {
for (Content content : node.contents)
System.out.println("content.text");
}
I found that the content.text never changed no matter what I did in the page. But if I define List<Content> contents = new ArrayList<Content>() directly in nodeedit, it can get the new value!! That's why I tried to get the nodeId everytime I toggle the node-table and then update the contents in backingbean. Did I do something wrong with it?
p:rowExpansion is dynamic and loads it's data using AJAX. Something like this should work:
<h:form>
<p:dataTable value="#{nodeedit.list}" var="somenode" styleClass="datatable">
<p:column>
<p:rowToggler />
</p:column>
<!-- Your columns here -->
<p:rowExpansion>
<p:dataTable var="content" value="#{nodeedit.contentOf(somenode)}">
<p:column>
<h:outputText value="#{content.someValue}" />
</p:column>
<!-- Other columns -->
</p:dataTable>
</p:rowExpansion>
</p:dataTable>
</h:form>
In your backing bean you should have a method to get the content of a node, in my example contentOf(Node node)
#Named // or #ManagedBean
#ViewScoped // or some other scope
public class Nodeedit
{
private List<Node> list;
//Getters and Setters
public List<SomeClass> contentOf(Node node)
{
// get and return the content of the node
}
}
If your Node has a method to get the Content you can do something like this in stead:
<p:rowExpansion>
<p:dataTable var="content" value="#{somenode.content}">
<p:column>
<h:outputText value="#{content.someValue}" />
</p:column>
<!-- Other columns -->
</p:dataTable>
</p:rowExpansion>
If a Node's content isn't a Collection of some sort I'm not sure it will work in a p:dataTable as the value.
I don't know what your classes look like so the above is just an idea.
Note also that I have put a h:form around the p:dataTable in stead of putting multiple forms in the p:dataTable itself. This is needed for multiple things like AJAX, selection, etc. You cannot nest forms.

Unable to populate values obtained from ajax call using PrimeFaces

Hi
I have made an ajax call using primefaces [p:ajax]. The call to the listener was successful and it returned the required values. To update these properties in xhtml, I have checked the DOM source, to find out the exact ID of the column, using which the column or property would be updated. But, in this case the fields are not getting the values.
The code I used in this case is
<p:dataTable id="table1" var="recepit" rowIndexVar="rowIndex" value="#{ReceiptDetailsBean.iterativeList}" scrollable="true" height="120px" styleClass="leftTable">
<p:column style="background-color: #EFF2F9">
<f:facet name="header">
<h:outputText value="SL NO" />
</f:facet>
<h:outputText value="#{rowIndex+1}" />
</p:column>
<p:column >
<f:facet name="header">
<h:outputText value="Buss." />
</f:facet>
<h:selectOneMenu id="selectOneCb" value="#{ReceiptDetailsBean.bussCode}" >
<f:selectItem itemLabel="V_BUSS_CODE" itemValue=""/>
<f:selectItems value="#{ReceiptDetailsBean.rdetails}" var="model" itemLabel="#{model.buss}" itemValue="#{model.buss}"/>
<p:ajax update="mainForm:table1:#{rowIndex}:receiptCode, mainForm:table1:#{rowIndex}:referenceType" actionListener="#{ReceiptDetailsBean.obtainReceiptDatabasedOnBussCode}" event="change"/>
</h:selectOneMenu>
</p:column>
<p:column id="receiptCodeCol">
<f:facet name="header">
<h:outputText value="Receipt Code" />
</f:facet>
<h:inputText value="#{ReceiptDetailsBean.receiptCode}" id="receiptCode" style="font-family: verdana;font-size: 10px;width:80px;height:15px" />
</p:column>
<p:column id="receiptTypeCol">
<f:facet name="header">
<h:outputText value="Ref Type" />
</f:facet>
<h:inputText value="#{ReceiptDetailsBean.receiptType}" id="referenceType" style="font-family: verdana;font-size: 10px;width:80px;height:15px"/>
</p:column>
</p:dataTable>
</div>
</p:tab>
<p:tab title="Print">
</p:tab>
</p:tabView>
</h:form>
The id from the DOM view source was table1:0:receiptCodeHotKey:receiptCode
What would be the problem for the data to not get populated in the field.
I think the source of the problem is your usage of h:form. You don't need to put it around each single input element. Put one h:form around the datatable and then check again the generated ids.
Then it should be something like (example for first row with rowindex 0):
formId:table1:0:receiptCode

Ajax call is made but the related fields are updated only after page refresh

I have tried making an ajax call for a selectOneMenu using JSF 2 and primefaces 2.2. The actionListener method is being called. But the columns I specified in the update attribute are not getting updated. When I refersh the page, I could find the updated values. Please help me out in this.
The code I used was
<h:form id="mainForm" prependId="false">
<p>
<p:tabView>
<p:tab title="Receipt">
<p:dataTable id="table1" var="recepit" rowIndexVar="rowIndex" value="#{ReceiptDetailsBean.iterativeList}" scrollable="true" height="120px" styleClass="leftTable">
<p:column style="background-color: #EFF2F9">
<f:facet name="header">
<h:outputText value="SL NO" />
</f:facet>
<h:outputText value="#{rowIndex+1}" />
</p:column>
<p:column >
<f:facet name="header">
<h:outputText value="Buss." />
</f:facet>
<h:selectOneMenu id="selectOneCb4" value="#{ReceiptDetailsBean.bussCode}" >
<f:selectItem itemLabel="V_BUSS_CODE" itemValue=""/>
<f:selectItems value="#{ReceiptDetailsBean.rdetails}" var="model" itemLabel="#{model.buss}" itemValue="#{model.buss}"/>
<p:ajax update="table1:#{rowIndex}:receiptCode, table1:#{rowIndex}:referenceType" actionListener="#{ReceiptDetailsBean.obtainReceiptDatabasedOnBussCode}" event="change"/>
</h:selectOneMenu>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Receipt Code" />
</f:facet>
<h:inputText value="#{ReceiptDetailsBean.receiptCode}" id="receiptCode" style="font-family: verdana;font-size: 10px;width:80px;height:15px" onkeypress="return showForhotKey(event,'#{rowIndex}');"/>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Ref Type" />
</f:facet>
<h:inputText value="#{ReceiptDetailsBean.receiptType}" id="referenceType" style="font-family: verdana;font-size: 10px;width:80px;height:15px" onkeypress="return showForhotKey(event,'#{rowIndex}');"/>
</p:column>
</p:dataTable>
</p:tab>
<p:tab title="Print">
</p:tab>
Try f:ajax instead of p:ajax and re-render the whole form to get closer to the problem source :
<h:selectOneMenu id="selectOneCb4" value="#{ReceiptDetailsBean.bussCode}" >
<f:selectItem itemLabel="V_BUSS_CODE" itemValue=""/>
<f:selectItems value="#{ReceiptDetailsBean.rdetails}" var="model"
itemLabel="#{model.buss}" itemValue="#{model.buss}"/>
<f:ajax render="#form"
listener="#{ReceiptDetailsBean.obtainReceiptDatabasedOnBussCode}"/>
</h:selectOneMenu>
This should work as stated in my answer to your previous question.
Partial updates of dataTables and ajax updates of dataTables triggered from a component within the dataTable are not working in the 2.2 version of Primefaces. This is a known bug that may have been resolved in version 3.
One suggestion you can try is to use a single form for each dataTable and only update elements from within that one form.

Resources