h:commandLink with Java bean - jsf

I have a datalist"gouvernorats" extracted from a data table and each item of the list is a command link that outcome an other page which contains a list "villes" referenced to the item. My code doesn't work.I ask someone to help me running it.
gouvernorat.xhtml
<c:forEach varStatus="#{stat}" items="gouvernoratbean.gouvernorats" var="gouv"><c:set var="villes" scope="request" value="${gouv.getvilles}"/>
<h:commandLink action="ville" actionListener="#{gouvernoratbean.showville}" value="#{gouv.nomGouv}"><f:setPropertyActionListener target="#{requestscope.gouv}" value="#{gouv}"></f:setPropertyActionListener>
</h:commandLink></c:forEach>
ville.xhtml
<p:dataList value="#{requestScope.gouvernoratbean.showville}" var="ville" >
<h:outputText><h2>#{ville.nomVille}</h2> </h:outputText> </p:dataList>
gouvernoratbean.java
public void showville(ActionEvent event){Villes=gouv.getVilles();}

No idea what your actual question is..
But it may not working as you have not referenced your bean properly in this part of the xhtml:
items="gouvernoratbean.gouvernorats"
Should be:
items="#{gouvernoratbean.gouvernorats}".

Related

p:dataTable how prevent f:viewParam being invoked on 1st rowEdit then “tick save” using JSF at XHTML level (not in Java in backing bean)

EDIT: 2017-04-28 The exact same problem (different circumstances/application) is described here: Process f:viewParam only on page load
Primefaces 6.1.RC2
JSF Mojarra 2.3.0
I already have a Java backing-bean based workaround (explained below) for the problem the following behaviour of p:dataTable causes, but I am not very happy with that workaround, and I would like to understand the behavior of p:dataTable row editing better and if possible I would like to find a purely XHTML-level solution to my problem. (BTW I am otherwise very experienced with p:dataTable, which I have used for some very complex applications for some years.)
It is not about an error or bug in p:dataTable, but the way it behaves during row editing causes me a problem in one situation.
The following code examples are completely simplified and adapted for this forum.
I have an entity Element, which has a relationship List<Link> getLinks(), where Link is also an entity.
Element has an editor edit.xhtml.
The aim is to have an composite component links_editor.xhtml that can be embedded in the edit.xhtml.
There is a CDI-compliant #ViewScoped #Named backing bean Manager.
The edit.xhtml relies on an f:viewParam to load an Element for editing:
<f:view>
<f:metadata>
<f:viewParam name="id" value="#{manager.id}"/>
</f:metadata>
</f:view>
Where in the backing bean Manager:
public void setId(Long id) {
if (id != null) {
//load an Element from database for editing by id
And in the links_editor.xhtml:
<cc:implementation>
<div id="#{cc.clientId}">
<p:growl id="testgrowl"/>
<p:dataTable
id="links_table"
editable="true"
var="link"
value="#{cc.attrs.element.links}"
>
<p:ajax
event="rowEdit"
listener="#{cc.attrs.manager.onLinkRowEdit}"
update="#{cc.clientId}:testgrowl"
/>
<p:column headerText="Link title">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{link.name}" />
</f:facet>
<f:facet name="input">
<p:inputText id="name" value="#{link.name}"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Link URL">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{link.urlAsString}" />
</f:facet>
<f:facet name="input">
<p:inputText id="url" value="#{link.urlAsString}"/>
<p:message
for="url"
display="icon"
/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column>
<p:rowEditor />
</p:column>
</p:dataTable>
The row edit listener:
public void onLinkRowEdit(RowEditEvent event) {
Link link = (Link) event.getObject();
try {
checkLink(link); //throws if URL string malformed
JsfUtil.addInfoMessage("DEBUG: Link: "+link);
} catch (LocalUpdateException ex) {
JsfUtil.addErrorMessage(ex.getMessage());
}
}
(where JsfUtil obviously just leverages FacesContext.getCurrentInstance().addMessage(...))
The issue/concern:
If I edit a Link row in the p:dataTable a first time and then use the "tick save" the onLinkRowEdit listener is invoked, but the diagnostics show that the value appear not to have changed. The reason is that this f:viewParam is invoked:
<f:viewParam name="id" value="#{manager.id}"/>
This (via routes not shown in detail) loads the Element entity again from database via setId(Long id), so that in the composite component edit_links.xthml this essentially resets #{cc.attrs.element.links}, so any changes are discarded.
The interesting thing is that if (without reloading the entire #ViewScoped page) one edits the same p:dataTable row a second time that f:viewParam is NOT invoked, and thereafter it works as desired.
A workaround (rather hacky) is to "block" any attempt to reload the Element by id within the view scope backing bean Manager:
public void setId(Long id) {
//HACK/WORKAROUND: prevent reload of Element by id
if (Objects.equals(id, this.id)) {
return;
}
if (id != null) {
//load an Element from database for editing by id
To be clear, I am aware of the usual strategies for using #PostConstruct and/or lazy database fetching in getters of frequently accessed info under JSF in backing beans. And I don't want to abandon here the f:viewParam approach entirely (and it works well for other situations the same Manager bean is also used for).
My interest is specifically about Primefaces p:dataTable:
Q1: Why does p:dataTable need to call the f:viewParam during the 1st row edit then "tick save", when the row information (in this cases element.links) is clearly already available ?
Q2: Why does p:dataTable NOT need to call the f:viewParam during the 2nd row edit then "tick save" ?
Q3: Is there a JSF XHTML-based way of preventing p:dataTable from calling the f:viewParam at all during a rowEdit then "tick save" (including the 1st go) ?
UPDATE: 2017-04-21: There is now a mini test web app for NetBeans 8.2 demonstrating the problem at:
https://github.com/webelcomau/Webel_PrimeFaces_test_p50445_dataTable_fviewParam
Please just download the master ZIP-archive, unzip it, and open it in NetBeans IDE 8.2. You don't need to Git-clone the project. Make sure you have Glassfish-4.1.1 set as the server for the project.
Both the README there and the web app test page itself give precise steps for reproducing the problem (or the behavior that concerns me).
I have invested some effort in analysing this because I use p:dataTable "embedded" in edit forms together with f:viewParam a lot, and I want to understand this matter better, even if it is not an actual problem with p:dataTable.

JSF 2: duplicate IDs inside p:dataList

i have a list of billable services per client and i'm trying to build a table where the user can select which ones shall actually be billed:
<p:dataList value="#{billController.billings}" var="billings">
<p:dataTable value='#{billings.billablesDataModel}' var='item' selection="#{billings.toBill}">
<f:facet name="header">
<h:outputText value="#{billings.client.id}" />
</f:facet>
[...]
</p:dataTable>
</p:dataList>
the problem is, that all the dataTables are rendered with the same ID attribute (j_idt9:j_idt13:0:j_idt14) which is automatically assigned by JSF. i'm suspecting this is causing that the selection doesn't work. (the backing bean billings.toBill is not updated/stays empty.)
i was trying to set the ID attribute of the dataTable manually like this:
<p:dataTable id="#{billings.client.id}" ...>
however, i get the following error:
java.lang.IllegalArgumentException: Empty id attribute is not allowed
(#{billings.client.id} is definitely set to the unique client's ID as i get the right output from an h:outputText for debug purposes.)
can you help me fixing this?
i'm using JSF Mojarra 2.1.1 and PrimeFaces 3.2 on a Tomcat 6.
You need to use p:column for content of datalist as documented in user's guide.
What if you loop over billController.billings via ui:repeat and not via p:dataList:
<ui:repeat var="billings" value="#{billController.billings}">
<p:dataTable value="#{billings.billablesDataModel}" var="item" selection="#{billings.toBill}">
[...]
</p:dataTable>
</ui:repeat>

JSF Primefaces TabView problems

I asked this in the PF Forum but no one seems to want to answer so I though I'd try my luck here.
I have a ui:repeat that is not being updated correctly after an Ajax call when it is within a TabView.
Simple scenario is I have a ui:repeat pointing at an ArrayList (ArrayList contains simple pojos with a String). Within this I have an h:inputText whose value is the pojo's String getter/setter. The ui:repeat is contained within a h:panelGroup. I use a p:commandButton to run an action to update the ArrayList (just add a couple of objects to it a Math.random value for the String) and then update the h:panelGroup. The updated values in the ArrayList are not reflecting in the ui:repeat input fields. This only appears to be affecting input fields as outputText fields do update correctly. Also if I do the same for a p:dataTable the input field are updated correctly. If I remove the Tabview and Tab tags it works fine.
As it works when removing the Tabs I can only assume this is a bug and not designed to work like this. If someone could please confirm if this is so or if there is a viable work around. I need to use a ui:repeat as my fields are not in a tabular format. This has only occurred since migrating from PF 2.2. I'm currently on PF 3.1, Weblogic 10.3.4 and Mojarra 2.0.4
<p:tabView>
<p:tab title="Test">
<h:form prependId="false">
<p:commandButton id="testStringCheck"
value="Test String Check"
process="#form"
update="testPanel"
action="#{testBean.generateVOwithRandomStrings}">
</p:commandButton>
<h:panelGroup id="testPanel" layout="block">
<ui:repeat value="#{testBean.voList}" var="entry">
<h:outputText value="#{entry.randomString}"/>
<p:inputText style="display:block;"
value="#{entry.randomString}"
size="15">
</p:inputText>
</ui:repeat>
</h:panelGroup>
</h:form>
</p:tab>
</p:tabView>
As a workaround I've used a p:datagrid instead of a ui:repeat. This achieves the look I had in the the ui:repeat so I'm happy. Hopefully this bug will be fixed on future releases.
This is something of a bug in Primefaces commandButton. See the following thread:
http://forum.primefaces.org/viewtopic.php?f=3&t=17454
You can try replacing
<p:commandLink id="testStringCheck" ... update="#form" />
With an <h:commandLink>
<h:commandLink id="testStringCheck" render="#form"/>
Also from the above link here is an interesting method that somebody posted that enables you to correctly find the correct clientId to update.
http://paste.kde.org/177698/
temp solution: insert outside h:panelGroup:
<p:outputPanel defered="true" delay="1" ..>
and update outputPanel instead of panelGroup
Or use a datalist component instead of ui:repeat.
One more, i'm not sure but you can try, so update class instead id:
<h:panelGroup id="testPanel" layout="block" styleClass="testPanelCl" ../>
and update : #(.testPanelCl), don't forget id of panelGroup, without id JSF can not update by class

input binding in ui:repeat in jsf

i am using facelets jsf 2.0 with primefaces 3.0.M2 component library.
i am trying to achieve dynamic numbers of rows including iput fields that are filled when a datatable selection occurs.
whenever a selection is made the dynamic rows generated correctly with input fields but after the first selection for following selections dynamic row count changes correctly but the input fields does not update and keeps showing inputs from the first selection.
here is how i iterate list in facelet;
<ui:repeat value="#{goalEntranceBean.selectedCard.parameterList}" var="prmBean" >
<li><h:outputText value="#{prmBean.lookUp.value}"/></li>
<li>
<h:outputText value="Weight:"/>
<p:inputText id="wx" required="true" value="#{prmBean.weight}">
</p:inputText>
<h:outputText value="Percent:"/>
<p:inputText required="true" value="#{prmBean.percent}">
</p:inputText>
</li>
</ui:repeat>
my bean where i get the list of cards and set the selectedCard with rowSelect event in datatable.
#ManagedBean(name = "goalEntranceBean")
#ViewScoped
public class GoalEntranceAction implements Serializable {
private List<ScoreCard> personalCards = new ArrayList<ScoreCard>();
private ScoreCard selectedCard = new ScoreCard();
......
}
when i checked in debug mode i can see the true list but in screen the elements does not change.
This is a common problem (gets asked every couple of days). To make long story short, inputs inside ui:repeat do not work, period.
It is a problem with JSF, a long standing, famous one. Maybe it will be fixed. Maybe not, it seems that no one really cares (I mean - an input? in a... ui:repeat? such crazy scenario!).
A quick-fix is to use a h:dataTable, possibly ungodly abused with css to make it look like a list. A long-fix is to use some iterator from a different library. Primefaces has an element that should work that renders an unordered list.
thanks for your replies. Sorry for forget sharing the solution.
As i mentioned above i have primefaces datatable.
On row selection event i render datatable and want to update the cells of that datatable.
USING p:inputtext easily solved my problem. Now i can change the data on screen and i can see the values after update operation on screen. I don't understand the reason but it works.
<p:dataTable var="orgPrmBean"
value="#{scoreCardOperationsBean.selectedCard.orgParameterList}"
emptyMessage="#{labels.norecord}"
rowKey="#{orgPrmBean.id}"
>
<p:columnGroup type="header">
<p:row>
<p:column headerText="Parameters" colspan="3" style="text-align:left;width:480;"/>
</p:row>
</p:columnGroup>
<p:column style="text-align:left;width:200px;">
<h:outputText value="#{orgPrmBean.info}"/>
</p:column>
<p:column style="text-align:left;width:180px;">
<p:inputText value="#{orgPrmBean.weight}"
rendered="#{scoreCardOperationsBean.selectedCard.goalEdit}">
<f:convertNumber maxFractionDigits="0"/>
</p:inputText>
</p:column>
</p:dataTable>
It IS possible to make it work, but the solution is to bind the inputs to a backing bean, and update the values of the controls in the backing bean via listeners (using the new value received in the argument). Obviously this isn't a good solution if you have a complex form, as you need to add a listener/control in the backing bean for each control in the page, but it's practical if you just have one or two inputs.

JSF, datatable in datatable

Could someone please tell me, how should be the backing bean of a page that shows datatable in datatable. For example:
If I want to show the users in the cities, the below code would be the design part of the page, but what about the bean?
<h:form><rich:dataList var="city" value="#{myBean.allCity}">
<h:outputText value="#{city.name}" ></h:outputText>
<rich:dataList var="user" value="#{city.users}">
<h:outputText value="#{user.name}" ></h:outputText>
</rich:dataList></rich:dataList></h:form>
Thanks.
in your City class you should have a method
"public List<User> getUsers()"
where it should return the appropriate list of users you want to list.
It should return User list.

Resources