All Metawidget does in response to a @UiFacesLookup is to programmatically hook up a 'f:selectItems value="#{myBean.allMyObjectsAvailable}". So the first step in resolving your problem would be to manually assemble the JSF widgets and see if they work:
I tried to do what you suggested me, but I am not able to make it work on my jspx.
But I don't think the problem is with the managed bean. I'll try to explain why.
I have Correo instances who have a many to many relation with Sistema instances.
Correo has an accessor like this:
@UiFacesLookup(value = "#{correoEditorManager.sistemasAvailable}")
public List<Sistema> getSistemas()
CorreoEditorManager has something like this:
public List getSistemasAvailable() {
List items = new Vector();
for ( Sistema sistema: Sistema.getAll() ) {
items.add( new SelectItem( sistema, sistema.getDescripcion() ) );
}
return items;
}
When editing a Correo instance, its many fields are displayed including an HtmlSelectManyCheckbox whose checkboxs are apropiately turned on/off according to the sistemas included in the correo.getSistemas() collection.
If that selection is changed, the resulting correo.getSistemas() collection is replaced with a toString() collection of each of the sistemas selected.
I played a bit with sistema.toString() and the SelectItem values to confirm that this is the sustained behaviour.
I am afraid that faces serialises the objects I put into a selectItem and uses that to fill the collection to return.
Does metawidget keep the original collection? in order to return the original objects and not the serialized result.
Best,
Emilio
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I cannot know for sure without seeing your code, but it sounds like the problem IS with your managed bean. A strong indicator of this is that your JSPX isn't working either.
I'm guessing (because you haven't mentioned it) that you're forgetting to register a Converter. In JSF, you cannot just put non-primitives (ie. non-String, non-Integer) into a SELECT box and expect it to return correctly. JSF will always serialize your Object into a String (because HTML is just Strings), and you need to write something to turn it back from a String into an Object.
You need to write, and register in faces-config.xml, a JSF Converter for your type. Typically you also need to specify this converter on your <h:selectOne>, although if you're using Metawidget it will do that bit for you.
Hope that helps.
Regards,
Richard.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
-
2010-05-07
Richard
Thanks for all your patience,
In fact I was suspecting about the need of something like a converter. Your suggestion put me on the road and did the trick.
The collection proyected on @UiFacesLookup(value = "#{correoEditorManager.sistemasAvailable}") is rather large.
I wrote a class like IceFacesWidgetBuilder (yeah, I cut&paste it) using HtmlSelectManyListbox instead of HtmlSelectManyCheckbox.
Its working now. But I really'd like another way. Is it configurable?
Can metawidget be extended in order to let me choose or configure what component to use?
Can I help to do this? (that should require your guidance, sorry :)
Best
Emilio
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Yes, Metawidget can be extended in order to 'choose' or 'configure' what component to use. To 'choose' you write a WidgetBuilder. To 'configure' you write a WidgetProcessor.
At a pinch you can use the existing HtmlWidgetBuilder and the @UiFacesComponent annotation, but that approach is pretty limited. You are better off writing your own WidgetBuilder, as it sounds like you are doing.
Can you please provide details:
1. What your WidgetBuilder looks like?
2. Why HtmlSelectManyListbox is better than HtmlSelectManyCheckbox for 'rather large' collections?
3. Why this approach is not to your liking and why you'd like another way?
Regards,
Richard.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
-
2010-05-10
Richard,
Yes I know, I always can write my own builder or processor. That's my usual way out .
> At a pinch you can use the existing HtmlWidgetBuilder and the @UiFacesComponent annotation…
I think I missed that, I'll try it.
> 1. What your WidgetBuilder looks like?
Exactly like IceFacesWidgetBuilder but using HtmlSelectManyListbox instead of HtmlSelectManyCheckbox, pluss a setSize( 10 ) to the component.
> 2. Why HtmlSelectManyListbox is better than HtmlSelectManyCheckbox for 'rather large' collections?
Because the list of check boxes does not fit in my screen. A listbox of size 10 appeals me more
> 3. Why this approach is not to your liking and why you'd like another way?
Because I'd like to be able to note:
@UiFacesComponent( value= HtmlSelectManyCheckbox )
@UIParamOrSomething( key=size, value=10)
Besides I am not comfortable writing a hole new builder just to swap list for a checkbox.
Ignorance on the framework drives me to duplicate code, I can not yet understand the semantic and relevance of the code I am copying. So I just copy something that works and change what I need.
So, even if I were able to trim down my builder just to the necessary code to define and use HtmlSelectManyCheckbox component, It seems so much. I think I should be able to do it just with notations.
Please take into account that I am pretty ignorant on ice and html components, I mainly do look for documentation a examples on the web.
Best,
Emilio
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi,
I am anotating a List<MyObect> kind accessor with
@UiFacesLookup(value = "#{myBean.allMyObjectsAvailable}")
allMyObjectsAvailable() returns a list of selectItems of the kind: new SelectItem( myObject, myObject.getDescription() )
But the collecction I get back is a collections of Strings, not a collection of myObjects
I am using icefaces.
What I am missing?
Thanks
Emilio
Emilio,
Thank you for your interest in Metawidget.
All Metawidget does in response to a @UiFacesLookup is to programmatically hook up a 'f:selectItems value="#{myBean.allMyObjectsAvailable}". So the first step in resolving your problem would be to manually assemble the JSF widgets and see if they work:
This will rule out an issue with the managed beans. Failing that, can you give more detail of your problem?
Regards,
Richard.
Richard,
Thanks!
Metawidget is a nice framework (have you met Magritte? http://www.lukas-renggli.ch/smalltalk/magritte)
I tried to do what you suggested me, but I am not able to make it work on my jspx.
But I don't think the problem is with the managed bean. I'll try to explain why.
I have Correo instances who have a many to many relation with Sistema instances.
Correo has an accessor like this:
@UiFacesLookup(value = "#{correoEditorManager.sistemasAvailable}")
public List<Sistema> getSistemas()
CorreoEditorManager has something like this:
public List getSistemasAvailable() {
List items = new Vector();
for ( Sistema sistema: Sistema.getAll() ) {
items.add( new SelectItem( sistema, sistema.getDescripcion() ) );
}
return items;
}
When editing a Correo instance, its many fields are displayed including an HtmlSelectManyCheckbox whose checkboxs are apropiately turned on/off according to the sistemas included in the correo.getSistemas() collection.
If that selection is changed, the resulting correo.getSistemas() collection is replaced with a toString() collection of each of the sistemas selected.
I played a bit with sistema.toString() and the SelectItem values to confirm that this is the sustained behaviour.
I am afraid that faces serialises the objects I put into a selectItem and uses that to fill the collection to return.
Does metawidget keep the original collection? in order to return the original objects and not the serialized result.
Best,
Emilio
Emilio,
I cannot know for sure without seeing your code, but it sounds like the problem IS with your managed bean. A strong indicator of this is that your JSPX isn't working either.
I'm guessing (because you haven't mentioned it) that you're forgetting to register a Converter. In JSF, you cannot just put non-primitives (ie. non-String, non-Integer) into a SELECT box and expect it to return correctly. JSF will always serialize your Object into a String (because HTML is just Strings), and you need to write something to turn it back from a String into an Object.
You need to write, and register in faces-config.xml, a JSF Converter for your type. Typically you also need to specify this converter on your <h:selectOne>, although if you're using Metawidget it will do that bit for you.
Hope that helps.
Regards,
Richard.
Richard
Thanks for all your patience,
In fact I was suspecting about the need of something like a converter. Your suggestion put me on the road and did the trick.
The collection proyected on @UiFacesLookup(value = "#{correoEditorManager.sistemasAvailable}") is rather large.
I wrote a class like IceFacesWidgetBuilder (yeah, I cut&paste it) using HtmlSelectManyListbox instead of HtmlSelectManyCheckbox.
Its working now. But I really'd like another way. Is it configurable?
Can metawidget be extended in order to let me choose or configure what component to use?
Can I help to do this? (that should require your guidance, sorry :)
Best
Emilio
Emilio,
Yes, Metawidget can be extended in order to 'choose' or 'configure' what component to use. To 'choose' you write a WidgetBuilder. To 'configure' you write a WidgetProcessor.
At a pinch you can use the existing HtmlWidgetBuilder and the @UiFacesComponent annotation, but that approach is pretty limited. You are better off writing your own WidgetBuilder, as it sounds like you are doing.
Can you please provide details:
1. What your WidgetBuilder looks like?
2. Why HtmlSelectManyListbox is better than HtmlSelectManyCheckbox for 'rather large' collections?
3. Why this approach is not to your liking and why you'd like another way?
Regards,
Richard.
Richard,
Yes I know, I always can write my own builder or processor. That's my usual way out .
> At a pinch you can use the existing HtmlWidgetBuilder and the @UiFacesComponent annotation…
I think I missed that, I'll try it.
> 1. What your WidgetBuilder looks like?
Exactly like IceFacesWidgetBuilder but using HtmlSelectManyListbox instead of HtmlSelectManyCheckbox, pluss a setSize( 10 ) to the component.
> 2. Why HtmlSelectManyListbox is better than HtmlSelectManyCheckbox for 'rather large' collections?
Because the list of check boxes does not fit in my screen. A listbox of size 10 appeals me more
> 3. Why this approach is not to your liking and why you'd like another way?
Because I'd like to be able to note:
@UiFacesComponent( value= HtmlSelectManyCheckbox )
@UIParamOrSomething( key=size, value=10)
Besides I am not comfortable writing a hole new builder just to swap list for a checkbox.
Ignorance on the framework drives me to duplicate code, I can not yet understand the semantic and relevance of the code I am copying. So I just copy something that works and change what I need.
So, even if I were able to trim down my builder just to the necessary code to define and use HtmlSelectManyCheckbox component, It seems so much. I think I should be able to do it just with notations.
Please take into account that I am pretty ignorant on ice and html components, I mainly do look for documentation a examples on the web.
Best,
Emilio
Emilio,
Some points in reply:
1. Your phrase 'writing a whole new builder' is misleading. You only have to write a tiny little builder, for the one thing you want (ie. your HtmlSelectManyCheckbox), then chain it together with the existing builders using CompositeWidgetBuilder. For an example: http://metawidget.sourceforge.net/doc/reference/en/html/ch02s04.html#section-architecture-widgetbuilders-implementing-your-own
2. I don't supply a @UiParamOrSomething by default because I think it goes 'too far' in how much UI stuff to put in the business object. However, I've blogged how you can add your own: http://kennardconsulting.blogspot.com/2010/05/custom-annotations-uifacescomponentprop.html
Hope that helps,
Richard.
Thanks Richard
I'll look into those links.
Emilio