PickList getTarget returning itemValue instead of var

UI Components for JSF
Post Reply
yapfa
Posts: 22
Joined: 18 Oct 2011, 11:49

29 Nov 2011, 12:49

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=)?

yapfa
Posts: 22
Joined: 18 Oct 2011, 11:49

30 Nov 2011, 10:36

Since this is a serious bug or misconception, I'll show a simple example.

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>
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).

cagatay.civici
Prime
Posts: 18616
Joined: 05 Jan 2009, 00:21
Location: Cybertron
Contact:

30 Nov 2011, 11:34

You must use converter if you are working with a type any other than string.

yapfa
Posts: 22
Joined: 18 Oct 2011, 11:49

30 Nov 2011, 12:04

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.

matrix
Posts: 7
Joined: 11 Aug 2016, 08:45

04 Nov 2016, 17:21

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

dahoc
Posts: 1
Joined: 01 Feb 2017, 10:37

01 Feb 2017, 10:41

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

Post Reply

Return to “PrimeFaces”

  • Information
  • Who is online

    Users browsing this forum: Baidu [Spider] and 39 guests