This has already been reported as "BUG in Picklist".
I'm using 3.0.RC1-SNAPSHOT 28-Nov-2011 22:23.
Just like the original post says, PickList getSource()/getTarget() returns itemValues instead of vars once it has been updated by a JSF setter call.
That is, I start with a PickList for class Foo (e.g. LinkedList<Foo>), do some clicks in the webapp, then PickList setter is called with ArrayList<String> for source and target.
Is this intended? I'd expect the source and target Lists of PickList to remain for the same type and holding the same objects that I passed onto PickList at creation time.
Are we supposed to use some sort of id for itemValue and then gather the original objects we supplied as source/target our self (using converter=)?
PickList getTarget returning itemValue instead of var
Since this is a serious bug or misconception, I'll show a simple example.
Place a breakpoint on the last line in PickListBean constructor to see how DualListModel is populated (LinkedList<Cat>). Also place a breakpoint on PickListBean.setCats() to see how DualListModel gets updated with ArrayList<String>itemValue (which is Cat.toString() here).
Then click on the command button to hit the second breakpoint.
I'll ask again; Are we really supposed to use an converter and e.g. Cat.id as itemValue, then re-read those Cats from DB using their id?
I see no other way to obtain the original Cat objects after the command button has been clicked (there are only ArrayLists of Strings as source and target, no Cats).
Code: Select all
public class Cat {
private String name;
// getter, setter
}
Code: Select all
public class PickListBean {
private DualListModel<Cat> cats;
// getter, setter
public PickListBean() {
List<Cat> source = new LinkedList<Cat>();
for (Long i = 0L; i < 16L; i++) {
Cat c = new Cat("cat " + i.toString());
source.add(c);
}
List<Cat> target = new LinkedList<Cat>();
for (Long i = 0L; i < 4; i++) {
Cat k = new Cat("kitten " + i.toString());
target.add(k);
}
cats = new DualListModel<Cat>(source, target);
}
Code: Select all
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>Cat PickList</title>
</h:head>
<h:body>
<h:form>
<p:pickList value="#{pickListBean.cats}" var="cat" itemValue="#{cat}">
<p:column>#{cat.name}</p:column>
</p:pickList>
<p:commandButton value="Show" update="displayCats" oncomplete="catsDlg.show()"/>
<p:dialog widgetVar="catsDlg">
<h:panelGrid id="displayCats" columns="2">
<h:outputText value="Source: "/>
<ui:repeat value="#{pickListBean.cats.source}" var="cat">
<h:outputText value="#{cat.name}"/>
</ui:repeat>
<h:outputText value="Target: "/>
<ui:repeat value="#{pickListBean.cats.target}" var="cat">
<h:outputText value="#{cat.name}"/>
</ui:repeat>
</h:panelGrid>
</p:dialog>
</h:form>
</h:body>
</html>
Then click on the command button to hit the second breakpoint.
I'll ask again; Are we really supposed to use an converter and e.g. Cat.id as itemValue, then re-read those Cats from DB using their id?
I see no other way to obtain the original Cat objects after the command button has been clicked (there are only ArrayLists of Strings as source and target, no Cats).
-
- Prime
- Posts: 18616
- Joined: 05 Jan 2009, 00:21
- Location: Cybertron
- Contact:
You must use converter if you are working with a type any other than string.
What's the reason for this? Other "containers" like dataTable work fine without a converter, using either rowKey or SelectableDataModel. I don't see why the same approach could not be used here.
Is there another way than using Foo.id in the converter and doing unneccessary database hits (or excessive caching) to reconstruct the objects in getAsObject()?
I've found this, but have not tested it. But frankly speaking it looks like a hack.
Is there another way than using Foo.id in the converter and doing unneccessary database hits (or excessive caching) to reconstruct the objects in getAsObject()?
I've found this, but have not tested it. But frankly speaking it looks like a hack.
I also stumbled over this issue, and I too cannot see any reason why contrary to other components the value passed to the setter is being converted (DualListModel with source and target members converted to List of Strings), and therefore is also inconsistent with the getter (which then has a different type as the setter, if to be overly correct).
Can't this be changed per default, without custom converter - as that would the most intuitive and therefore (probably by most users) expected behaviour?
Best regards
Can't this be changed per default, without custom converter - as that would the most intuitive and therefore (probably by most users) expected behaviour?
Best regards
Hi,
for other people out there running into the same problem, following is a pretty generic converter for Primefaces Picklist (and OrderList) that solved it for us (without a single static growing hashMap as seen elsewhere, but relying on object hashCode() - mind the implications of a hash collision, you can override the object's hashCode() to account for that).
https://gist.github.com/DaHoC/f6aff7b76 ... de81504f22
And a similar converter for Primefaces OrderList:
https://gist.github.com/DaHoC/e046b9947 ... d0d65a5406
Best regards
for other people out there running into the same problem, following is a pretty generic converter for Primefaces Picklist (and OrderList) that solved it for us (without a single static growing hashMap as seen elsewhere, but relying on object hashCode() - mind the implications of a hash collision, you can override the object's hashCode() to account for that).
https://gist.github.com/DaHoC/f6aff7b76 ... de81504f22
And a similar converter for Primefaces OrderList:
https://gist.github.com/DaHoC/e046b9947 ... d0d65a5406
Best regards
-
- Information
-
Who is online
Users browsing this forum: Baidu [Spider] and 39 guests