Primefaces update table from another form - jsf

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.

Related

how to make columns of primefaces datatable clickable

I'm using a primefaces datatable and trying to make it clickable without using a javascript. Can anyone help me?
Here is my code. By clicking rows, I want to invoke a method.
<p:dataTable id="examplej" class="table couple-table" rowKey="#{info.id}" selectionMode="single" selection="#{bb.detail(info)}" rowIndexVar="rowIndex"
var="info" value="#{bb.coupleList}" rows="10" paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
rowsPerPageTemplate="5,10,15" paginator="true" emptyMessage="お探しの地域では見つかりませんでした">
<p:column class="column-couple">
<h:outputText value="#{info.addressOne}" />
</p:column>
This is a method which i want to invoke by clicking rows.
<p:commandLink action="#{bb.detail(info)}"/>
when i run my webapp, i get this error now.
javax.el.PropertyNotFoundException: The class 'java.lang.String' does not have the property 'id'.
Thank you in advance.
It can be done via selection and selectionMode attributes in <p:datatable> component. In selection you can specify action in backing bean what would you like to do with selected object. It is clearly documented and presented on primefaces showcase site

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>

p:rowExpansion gets rendered even though it's not toggled

I have a problem with data in a <p:rowExpansion> being loaded before the row is expanded (which leads to loads of web service requests).
I am using PrimeFaces 5.2. I have a dataTable with lazy loading and pagination. Inside of the table, I have <p:rowToggler> with a <p:rowExpansion>:
<p:dataTable var="order"
widgetVar="orderTable"
lazy="true"
value="#{ordersBean.orders}"
paginator="true"
rows="20"
rowsPerPageTemplate="20,50,100"
filterDelay="300"
styleClass="filtered">
<p:column width="4%">
<p:rowToggler />
</p:column>
<p:column headerText="Order number" width="96%">
<h:outputText value="#{order.number}" />
</p:column>
<p:rowExpansion>
<h:panelGrid columns="1">
<h:outputText value="#{order.number}" />
<h:outputText value="#{order.info}" />
<h:dataTable var="item" value="#{ordersBean.getItemsInOrder(order.number)}">
<h:column>
<h:outputText value=" #{item.title}" />
</h:column>
</h:dataTable>
</h:panelGrid>
</p:rowExpansion>
</p:dataTable>
When I first load the page, the getItemsInOrder() method is not called, except for when I expand a row. But if I navigate to page 2 (or if I navigate back to page 1 later) using the paginator, then getItemsInOrder() is called for every row in the outer table. Since I have 20 rows showing, navigating between the pages leads to 20 web service requests (in getItemsInOrder()).
How do I prevent it from calling the getItemsInOrder() method until the row is expanded?
I have the same problem. Until I find a better solution, this is the workaround I am using:
register a (DataTable event-) listener on event rowToggle.
In the listener, store an identifier of the toggled row. Hint: you can get the row object with event.getData()
Instead of directly accessing the data requesting component, write a proxy method in front of it which checks if the requested object belongs to the identifier stored in the listener.

JSF redirect to another page and open dialog

I'm struggling now with redirecting. I want to redirect from one page to another with usage of h:commandButton / p:commandButton. And that works, but i need to pass an argument/ parameter with that request. And then use that parameter instantly after the new page reloads.
First page:
<p:dataTable id="list" var="oneRow"
value="#{test.get_list()}" rowKey="#{oneRow.id}"
rows="15" paginator="true" paginatorAlwaysVisible="false"
paginatorPosition="bottom"
selection="#{test.oneRowObject}"
paginatorTemplate="{PreviousPageLink} {PageLinks} {NextPageLink}"
emptyMessage="----------" >
<p:column selectionMode="single"/>
<p:column headerText="ID" >
#{oneRow.getID()}
</p:column>
</p:dataTable>
And there is a commandButton which should redirect from page1 to page2, and in that page it should open dialogbox.
How can I do that? Do you have any suggestions or examples?
p - primefaces
I think you should use <f:param/>
<h:commandButton value="Send" action="#{bean.method}">
<f:param name="paramName" value="someValue" />
</h:commandButton>

Wrong values in <p:rowExpansion> and empty values in <p:cellEditor> on scrolled page when using <p:dataTable lazy="true" liveScroll="true">

I am using JSF 2.2 with PrimeFaces 4.0. I have a <p:dataTable> with live scrolling, lazy loading, row-expansion and cell-editing, etc.
<p:dataTable
id="dtaTable"
selection="#{cont.selectedArray}"
resizableColumns="true"
draggableColumns="true"
var="dataModel"
value="#{cont.yieldBondsModel}"
editable="true"
editMode="cell"
selectionMode="multiple"
rowSelectMode="add"
scrollable="true"
scrollHeight="650"
rowKey="#{modeld.id}+#{model.name}"
rowIndexVar="rowIndex"
filterEvent="enter"
styleClass="screenScrollStyle"
scrollRows="25"
liveScroll="true"
lazy="true"
rows="50"
filteredValue="#{cont.filteredModel}"
widgetVar="dt4"
>
<p:rowExpansion>
<h:panelGrid id="display" columns="2" cellpadding="4" style="width:300px;" styleClass="ui-widget-content grid">
<f:facet name="header" styleClass="dataTableHeader">Other Data</f:facet>
<h:outputText value="id " />
<h:outputText value="#{dataModel.id}"/>
<h:outputText value="Name" />
<h:outputText value="#{dataModel.name}" />
</h:panelGrid>
</p:rowExpansion>
<p:column width="15">
<p:rowToggler />
</p:column>
...
</p:dataTable>
On the first page everything works like a charm. Once I scroll it down, data is getting lazy-loaded perfectly fine, but it has some problems during row-expansion and cell-editing:
In row-expansion, I am getting wrong values. Maybe overlapped values from other row.
Cell-editing is also not working. Once I edit any cell, values are not getting displayed in cell-editor. I have checked in Firebug, there is no value in <h:outputText> as confirmed by the generated HTML <div class="ui-cell-editor-output" style="display: none;"></div>. As you can see, there is no value inside the div.
The backing bean is #SessionScoped.
How is this caused and how can I solve it?
This is a known issue on PrimeFaces, and already reported and fixed in Elite version (4.0.7 if I remember well). However community release does not contain this fix yet. There is an RC for PrimeFaces 5.0 which contains this fix. You can download it and test if it's suits for you needs, but be aware that this is only a release candidate, not a final release. AFAIK the ETA for the 5.0 final is the first half of May.

Resources