Why does a subTable break a4j:commandLink's reRender? - jsf

Here is a minimal rich:dataTable example with an a4j:commandLink inside. When clicked, it sends an AJAX request to my bean and reRenders the dataTable.
<rich:dataTable id="dataTable" value="#{carManager.all}" var="item">
<rich:column>
<f:facet name="header">name</f:facet>
<h:outputText value="#{item.name}" />
</rich:column>
<rich:column>
<f:facet name="header">action</f:facet>
<a4j:commandLink reRender="dataTable" value="Delete" action="#{carForm.delete}">
<f:setPropertyActionListener value="#{item.id}" target="#{carForm.id}" />
<f:param name="from" value="list" />
</a4j:commandLink>
</rich:column>
</rich:dataTable>
The exmaple obove works fine so far. But when I add a rich:subTable (grouping the cars by garage for example) to the table, reRendering fails...
<rich:dataTable id="dataTable" value="#{garageManager.all}" var="garage">
<f:facet name="header">
<rich:columnGroup>
<rich:column>name</rich:column>
<rich:column>action</rich:column>
</rich:columnGroup>
</f:facet>
<rich:column colspan="2">
<h:outputText value="#{garage.name}" />
</rich:column>
<rich:subTable value="#{garage.cars}" var="car">
<rich:column><h:ouputText value="#{car.name}" /></rich:column>
<rich:column>
<a4j:commandLink reRender="dataTable" value="Delete" action="#{carForm.delete}">
<f:setPropertyActionListener value="#{item.id}" target="#{carForm.id}" />
<f:param name="from" value="list" />
</a4j:commandLink>
</rich:column>
</rich:column>
</rich:dataTable>
Now the rich:dataTable is not rerendered but the item gets deleted since the item does not show up after a manual page refresh.
Why does subTable break support for reRender-ing here?
Tanks Tom

It turned out that Hibernate did not update the list of the related models.
After removing the Car using AppFuse's carManager, the deleted car still showed in the getCars()-list of the associated Garage [when receiving the Garages using garageManager.getAll()].
So the problem was not related to richfaces itself!
Currently I'm using a workaround (deleting the items manually when receiving the data from the related model oO) but maybe I'll open a new question to solve this problem.

Related

Primefaces DataTable cellEdit required inputText not evaluated

can someone explain why following minimal example won't evaluate the required element? Or is it the "wrong" way and there is a better one I don't know.
I'm aware that my question is similiar to this question: Primefaces cellEditor required inputText. For me it seems that the solution is more of a workaround than a valid way to cope with this problem. So yeah any ideas how to deal with this?
Code:
<p:dataTable id="ruleTableID" var="rule" value="#{rC.rules}" widgetVar="rowsTable"
rows="20" editable="#{rC.editable}"
editMode="cell" paginator="true"
paginatorPosition="bottom" paginatorTemplate="{Save}"
emptyMessage="#{t['rule.empty']}">
<p:ajax event="cellEdit" update=":newRules:messages, :newRules:" />
<p:column headerText="#{t['policy.registerNumber']}">
<p:cellEditor>
<f:facet name="input">
<p:inputText styleClass="ruleInputText" value="#{rule.registerNr}" required="true" maxlength="4">
<f:validateLength minimum="4" />
<f:validateRegex pattern="([A-Z\d]{4})" />
<p:clientValidator/>
</p:inputText>
</f:facet>
<f:facet name="output">
<h:outputText value="#{rule.registerNr}" />
</f:facet>
</p:cellEditor>
</p:column>
<f:facet name="{Save}">
<p:commandButton id="saveButton" value="#{t['button.save']}" action="#{rC.saveRules}" update=":newRules" rendered="#{rC.isAllValueSet}" />
</f:facet>
</p:dataTable>
If you are using client side validation you have to add the attributes ajax="false" and validateClient="true" to your commandButton
You can see a example here:
http://www.primefaces.org/showcase/ui/csv/event.xhtml

Datatable not displaying any data but its fine using a pannel grid

i am currently using a pannel grid to display some data retrived from a database, this is working fine, the layout is not perfect but it displays all of the correct data, however i am wanting to use a datatable for looks more than anything, i have tried to use the outputText from the pannel grid but when i run the page it just says no data found, but on the same page the same code displays the data in the pannel grid
what am i doing wrong ?
this is the code for the working pannel grid
<!-- heading -->
<f:facet name="header">
User Details
</f:facet>
<h:outputText value="#{bundle.ViewUserdetailsLabel_id}"/>
<!-- adding in a small effect here that will fade a message when a user hovers over the id number or username -->
<h:outputLink id="id1" value="#">
<h:outputText id="id" value="#{userdetailsController.selected.id}" title="#{bundle.ViewUserdetailsTitle_id}"/>
</h:outputLink>
<p:tooltip for="id" value="This is your I.D. Number" showEffect="fade" hideEffect="fade" />
<h:outputText value="#{bundle.ViewUserdetailsLabel_username}"/>
<h:outputLink id="username1" value="#">
<h:outputText id="username" value="#{userdetailsController.selected.username}" title="#{bundle.ViewUserdetailsTitle_username}"/>
</h:outputLink>
<p:tooltip for="username" value="Your registered username, this can be changed" showEffect="fade" hideEffect="fade" />
</p:panelGrid>
and here is the not working datatable
<p:dataTable>
<p:column >
<f:facet name="header">
<h:outputText value="{bundle.ViewUserdetailsLabel_id}"/>
</f:facet>
<h:outputText value="{userdetailsController.selected.id}" />
</p:column>
<p:column headerText="username" >
<f:facet name="header">
<h:outputText value="{bundle.ListUserdetailsTitle_username}"/>
</f:facet>
<h:outputText value="{userdetailsController.selected.username}" />
</p:column>
</p:dataTable>
as you can see the outputText values are the same so it should work right ?
thanks
If you happen to have only few hardcoded values to display in a form of a table, then you are better off using <h:panelGrid>. If you however have a list of objects that you want to iterate over and display them quickly then use <p:dataTable>.
Let's say we have a List of employees
<p:dataTable var="employee" value="#{tableBean.employees}">
<p:column headerText="Name">
<h:outputText value="#{employee.name}" />
</p:column>
<p:column headerText="Age">
<h:outputText value="#{employee.age}" />
</p:column>
<p:column headerText="Sex">
<h:outputText value="#{employee.sex}" />
</p:column>
</p:dataTable>
then your table would look like this. var in this case is completely arbitrary, you could for instance call it 'fluffy' if you wanted. There are a lot of settings you can use with dataTable like pagination, export, sorting etc. But I suggest you familiarize yourself with Primefaces showcase

outputText and inputText in f:facet of rich:column doesn't work - JSF

I'm trying to achieve external filtering using rich:dataTable which has sorting ability.
Here's what I have tried:
<rich:column sortBy="#{data.name}" id="name" filterMethod="#myBean.filter}">
<f:facet name="header">
<h:outputText value="Name" />
<h:inputText value="#{myBean.currentName}"
id="nameFilterInput" onclick="Event.stop(event)" onkeypress="searchNameOnEnter(event, this);">
<a4j:support event="onkeyup" reRender="dataTable , ds"
ignoreDupResponses="true" requestDelay="700" />
</h:inputText>
</f:facet>
<h:outputText value="#{data.name}" />
</rich:column>
Problem: The input text field is overwriting the output text (the header name)
I've tried using h:panelGroup inside the f:facet, but the problem is the sort icon is rendered in the third row seperately.
What am I missing here?
Any help would be great.
Updated: #Christophe Roussy, here's the screenshot
As seen the inputText is overwriting the outputText.
Update 2: I saw a post here: https://community.jboss.org/thread/13046 which explains to use <f:facet name="filter"> for inputText, but that seems to work only for rich:extendedDataTable.
Any way to make it work with rich:dataTable?
The <f:facet> can have only one child. Wrap them in a <h:panelGroup>.
<f:facet name="header">
<h:panelGroup>
<h:outputText ... />
<h:inputText ... />
</h:panelGroup>
</f:facet>

Richfaces: component rich:dataScroller doesn't work

i'm using richfaces 3.3.3 I've a rich:dataTable inside another rich:dataTable and both have a rich:dataScroller but the inner doesn't work:
<rich:dataTable id="dataTableVisibility" value="#{jsfGridUtenti.itemKeys}"
var="roleName" cellspacing="1"
cellpadding="1" border="1"
styleClass="tab" style="width:60%"
rowClasses="rdispari,rpari"
headerClass="headTab" rows="3"
rendered="#{jsfGridUtenti.renderPanelReportVisibility}">
<f:facet name="footer">
<rich:datascroller for="dataTableVisibility"
fastStep="10" pagesVar="pageCountCl"
pageIndexVar="pageIndexCl"
maxPages="9" renderIfSinglePage="false"
selectedStyle="font-weight:bold;">
</rich:datascroller>
</f:facet>
<h:column>
<f:facet name="header">
#{applicationMessages.ruolo}
</f:facet>
<a4j:commandLink reRender="reportUserVisibilityCompanyRoleClass" action="#{jsfGridUtenti.deleteAssociationRole(roleName)}">
<h:graphicImage styleClass="toolbarLabel" url="../resources/img/cancella.png" />
</a4j:commandLink>
<rich:spacer height="1" width="8" />
<h:outputText style="font-size:11px" value="#{roleName}"/>
</h:column>
<h:column>
<f:facet name="header">
#{applicationMessages.companyAssociate}
</f:facet>
<h:column>
<rich:dataTable id="dataTableCompany"
var="company" value="#{jsfGridUtenti.findCompanyInHashMap(roleName)}"
style="width:100%" rows="5"
rowClasses="rdispari,rpari"
columnsWidth="10%,10%,80%"
headerClass="headTab">
<f:facet name="footer">
<rich:datascroller for="dataTableCompany"
fastStep="10" pagesVar="pageCountCls"
pageIndexVar="pageIndexCls"
maxPages="9" ajaxSingle="true"
selectedStyle="font-weight:bold;"
renderIfSinglePage="false">
</rich:datascroller>
</f:facet>
<h:column>
<a4j:commandLink reRender="reportUserVisibilityCompanyRoleClass" action="#{jsfGridUtenti.deleteAssociationCompany(roleName,company)}">
<h:graphicImage styleClass="toolbarLabel" url="../resources/img/cancella.png" />
</a4j:commandLink>
</h:column>
<h:column>
<a4j:commandLink immediate="true" action="#{jsfGridUtenti.setCompanyToShow(roleName,company)}"
reRender="showClassi,panelGridReport">
<h:graphicImage styleClass="toolbarLabel" url="../resources/img/lente.png" />
</a4j:commandLink>
</h:column>
<h:column>
<h:outputText style="font-size:11px" value="#{company.label}"/>
</h:column>
</rich:dataTable>
</h:column>
</h:column>
</rich:dataTable>
Now when I click on the outer rich:dataScroller it works well, instead when I click on the inner nothing happens. How can I fix?
This is a known issue. rich:datascroller doesn't support nested iteration components such as dataTable, repeat etc.
There is a JIRA issue for this.
Did you say 'nothing happens'? Did you look at your console? Doesn't it display a warning like this?
The requested page #2 isn't found in the model containing 1 pages. Paging is reset to page #1
I got the same warning message and solved it by adding a session variable like:
<rich:dataScroller for="table" page="#{sessionBean.page}" />
In my case the bean wasn't accessible (due to scope) before I changed the code. I was on the wrong track because I would have expected a warning/error pointing out that the problem is related to the expression language.

Sortable columns in embedded rich:dataTable

I have a jsp page containing a rich:dataTable with some data regarding my clients.
In each row I have another rich:dataTable containing some commission rates for the current customer.
The code is something like this:
<rich:dataTable id="clientList" value="#{clientsBean.model}" var="client" rows="15">
<rich:column id="nameColumn">
<f:facet name="header">
<h:outputText value="#{msg.manageclients_client_name}" />
</f:facet>
<h:outputText id="name" value="#{client.name}" />
</rich:column>
<rich:column id="clientRatesColumn">
<f:facet name="header">
<h:outputText value="#{msg.manageclients_client_rates}" />
</f:facet>
<rich:dataTable id="clientRates" value="#{client.clientRates}" var="clientRate">
<rich:column id="clientRateProduct" sortable="true" sortBy="#{clientRate.product.qualifiedName}">
<f:facet name="header">
<h:outputText value="#{msg.manageclients_rate_product}" />
</f:facet>
<h:outputText value="#{clientRate.product.qualifiedName}" />
</rich:column>
...
</rich:dataTable>
</rich:column>
...
</rich:dataTable>
As you can see the embedded rich:dataTable (id=clientRates) contains a sortable column (id=clientRateProduct).
My problem is that if I click on the sort icon in the clientRateProduct column for the current client all clientRates dataTables will be sorted (not just the one for the current client).
I want the sort action to be performed just on the current clientRates dataTable. Can anybody please suggest a solution ?
I use RichFaces 3.2.2.SR1. & Tomcat 6.0.29
you should encapsulate the inner data table with
<a4j:region renderRegionOnly="true" >
so only it will be updated from the ajax request

Resources