Thank you Volker. I now have something that works!! Here's what I did:
I made a generic converter that is backed up by a "storage bean" wired in from Spring under session scope. The storage bean is no more than a HashMap that has the String as key and the Object as value. I can now put the object in storage in the asString method and fetch it in asObject. The only concern is the growing storage bean. For my application I think this is a minor issue. A small price to pay for getting "real" data binding! Thanks again Jarle -----Opprinnelig melding----- Fra: weber.vol...@googlemail.com [mailto:weber.vol...@googlemail.com] På vegne av Volker Weber Sendt: 9. juni 2009 09:24 Til: MyFaces Discussion Emne: Re: [Tobago] Binding selected item from <tx:selectOneChoice> Hi Jarle, 2009/6/8 Jarle Halvorsen <j...@multiplus.as>: > Thank you for the replies folks. > > I'm not that experienced with neither JSF nor Tobago, but I find it a bit > strange that I have to tie in a converter in this case. Its plain jsf issue all value types except String need a Converter. Some converters are bundled with jsf-api. > Could you explain why I need one? The selectOneChoice is able to initially > set the correct selected object based on getSelectedServiceReportType(), if I > modify my test code to set the private selectedServiceReportType, without a > converter. Let me explain how it works: At render time while rendering the html option tags the current selectItems value are compared with the selectOnes value to decide setting the option selected. The value of the html option is generated by invoke asString on the converter, or if no converter just by toString() on the select items value. This is why the initially rendering works correct. At submit time the submitted value is the same String which was rendered as the option tags value attribute. If there is no converter jsf can't convert this to a Object. But ony if the result of converting is in the list of select Items the selection is valid, otherwise you get the validation error. > > The converter interface defines methods for converting from String to Object > and from Object to String. In my case ServiceReportType is a complex type and > a conversion to it from a String would not be possible. In theory all my > ServiceReportTypes could have the same description/label. I'm confused as you > might have noticed.. :) If it is not possible to vconvert from String, what it is in html, to the object back, than it is not possible to use it as the items value. One possiblity is to implement a converter which has internaly a List of the items and make a conversion from list index as String and from String to index to return the correct value. Regards, Volker > > My focus has been on the SelectItem class. As far as I can see these objects > should be enough. Shouldn't the framework be able to forward the value of the > SelectItem(Object) to my bound controller property when selected, via a set > method?? At least this is the behaviour I'm used to other frameworks. > > Thanks again > > Jarle Halvorsen > > -----Opprinnelig melding----- > Fra: weber.vol...@googlemail.com på vegne av Volker Weber > Sendt: ma 08.06.2009 19:47 > Til: MyFaces Discussion > Emne: Re: [Tobago] Binding selected item from <tx:selectOneChoice> > > Hi Jarle, > > you need a converter for ServiceReportType. > > > Regards, > Volker > > 2009/6/8 Jarle Halvorsen <j...@multiplus.as>: >> Hi. >> >> >> >> Im on tobago 1.0.20 >> >> >> >> I'm think I've missed something here. I just can't find out what is wrong >> with my code. I'm trying to bind the selected item of a selectOneChoice to a >> property on a controller. >> >> The selectOneChoice is initially rendered correctly with data from my >> database. But when I try to select from the list, I get a validation error, >> and the setSelectedServiceReportType to set the value back to the controller >> is never called. If I set the test up with an int og even a Long as values >> for the selectItems it all works fine.. >> >> >> >> What am I doing wrong?? >> >> >> >> I have this test code: >> >> >> >> jsp: >> >> <tc:box label="Register New Report"> >> >> <tc:panel> >> >> <f:facet name="layout"> >> >> <tc:gridLayout columns="*;*;" rows="fixed;" >> border="0" /> >> >> </f:facet> >> >> <tx:selectOneChoice label="Select One" >> value="#{testController.selectedServiceReportType}"> >> >> <f:selectItems >> value="#{testController.serviceReportTypes}"/> >> >> <f:facet name="change"> >> >> <tc:command >> action="#{testController.selectedServiceReportTypeAction}"/> >> >> </f:facet> >> >> </tx:selectOneChoice> >> >> >> >> <tx:label value="TEsting"/> >> >> </tc:panel> >> >> </tc:box> >> >> >> >> >> >> controller: >> >> >> >> public class TestController { >> >> >> >> private ArrayList<ServiceReportType> serviceReportTypes; >> >> private ServiceReportType selectedServiceReportType; >> >> >> >> public void setSelectedServiceReportType(ServiceReportType >> selectedServiceReportType) { >> >> this.selectedServiceReportType = selectedServiceReportType; >> >> } >> >> >> >> public ServiceReportType getSelectedServiceReportType() { >> >> return selectedServiceReportType; >> >> } >> >> >> >> public ArrayList<SelectItem> getServiceReportTypes() { >> >> if (serviceReportTypes == null) { >> >> serviceReportTypes = new ArrayList<ServiceReportType>(); >> >> for (int i = 0; i < 3; i++) { >> >> ServiceReportType serviceReportType = new ServiceReportType(); >> >> serviceReportType.setDescription("Decription " + i); >> >> serviceReportTypes.add(serviceReportType); >> >> } >> >> } >> >> >> >> ArrayList<SelectItem> selectItems = new ArrayList<SelectItem>(); >> >> for (ServiceReportType serviceReportType : serviceReportTypes) { >> >> selectItems.add(new SelectItem(serviceReportType, >> serviceReportType.getDescription())); >> >> } >> >> return selectItems; >> >> } >> >> >> >> public String selectedServiceReportTypeAction() { >> >> return "OK"; >> >> } >> >> >> >> } >> >> >> >> ServiceReportType entity (which is Hibernate mapped): >> >> >> >> public class ServiceReportType implements Serializable { >> >> >> >> private static final long serialVersionUID = 2869236275653791385L; >> >> >> >> private Long id; >> >> private String typeCode; >> >> private String description; >> >> >> >> public Long getId() { >> >> return id; >> >> } >> >> >> >> public void setId(Long id) { >> >> this.id = id; >> >> } >> >> >> >> public String getTypeCode() { >> >> return typeCode; >> >> } >> >> >> >> public void setTypeCode(String typeCode) { >> >> this.typeCode = typeCode; >> >> } >> >> >> >> public String getDescription() { >> >> return description; >> >> } >> >> >> >> public void setDescription(String description) { >> >> this.description = description; >> >> } >> >> >> >> } >> >> > > > > -- > inexso - information exchange solutions GmbH > Bismarckstraße 13 | 26122 Oldenburg > Tel.: +49 441 4082 356 | > FAX: +49 441 4082 355 | www.inexso.de > > -- inexso - information exchange solutions GmbH Bismarckstraße 13 | 26122 Oldenburg Tel.: +49 441 4082 356 | FAX: +49 441 4082 355 | www.inexso.de