You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@wicket.apache.org by Eirik Lygre <ei...@gmail.com> on 2009/08/20 00:17:09 UTC

DropDown where (type of model property) != (type of choices)

I'm looking for the best way to implement a drop-down, where the type of the
model property is not the type of the lists:

For example, with the model below, I want to implement a drop-down to select
languages for a user.

    class User {
        String languageId;
    }

    class Language {
        String languageId;
        String languageName;
    }

    // From MyForm extends Form<User>
    // here, this.getModelObject returns a User
    // Somewhere in the constructor...
    ...
    List<Language> languages = getLanguagesFromDatabase();
    form.add (new DropDownChoice("languageDropDown", ...eh...?
    ...

My workaround involves creating a separate model for the language, and copy
from the language model to the user model whenever I use the user model. But
it's cumbersome...

1) Is there a better way?
2) Is there an established "best practice" for this (probaly common)
scenario?


Eirik

Re: DropDown where (type of model property) != (type of choices)

Posted by elygre <ei...@gmail.com>.

MattyDE wrote:
> 
> Great! Thanks a lot for this BeanDropDownChoice-Component ... iam a little
> bit dissapointed that something similiar is not include inside the
> standard-wicket framework....
> 

Thanks -- I'm glad to hear you enjoyed it :-)

If you want this to be part of Wicket itself, you may want to vote for
https://issues.apache.org/jira/browse/WICKET-2443.
-- 
View this message in context: http://old.nabble.com/DropDown-where-%28type-of-model-property%29-%21%3D-%28type-of-choices%29-tp25052893p27715910.html
Sent from the Wicket - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: DropDown where (type of model property) != (type of choices)

Posted by MattyDE <uf...@gmail.com>.
Great! Thanks a lot for this BeanDropDownChoice-Component ... iam a little
bit dissapointed that something similiar is not include inside the
standard-wicket framework....

One again: Great! :o)




elygre wrote:
> 
> 
> elygre wrote:
>> 
>> It seems to me that it is a fairly hard requirement that the model and
>> the choice list have identical types. I'll investigate a bit further, to
>> see if I can build a generic mechanism for both a Map and a "bean"-style
>> object.
>> 
> 
> After looking deeper into this, I created two different specialized
> DropDownChoices, with different properties. The class signatures
> (interfaces) are as follows with complete code further below
> 
> Now, of all the things I did in Wicket, this is the one thing that turned
> out to be furthest from expectations. It wasn't the hardest, but it was
> the easiest thing that turned out to be hard :-). If there is interest (or
> at least no objections...), I'll create a jira issue and submit this code
> for inclusion into 1.5.
> 
> Class signatures:
> 
> public class MapDropDownChoice<T> extends DropDownChoice<T> {
>     public MapDropDownChoice(String id, Map<T, ?> choices);
>     public MapDropDownChoice(String id, IModel<T> model, Map<T, ?>
> choices);
> }
> 
> public class BeanDropDownChoice<T> extends MapDropDownChoice<T> {
>     public BeanDropDownChoice(String id, List choices, IChoiceRenderer
> renderer);
>     public BeanDropDownChoice(String id, IModel<T> model, List choices,
> IChoiceRenderer renderer);
> }
> 
> 
> Full code:
> public class MapDropDownChoice<T> extends DropDownChoice<T> {
> 
>     public MapDropDownChoice(String id, Map<T, ?> choices) {
>         super(id, new ArrayList<T>(choices.keySet()), new
> MapChoiceRenderer(choices));
>     }
> 
>     public MapDropDownChoice(String id, IModel<T> model, Map<T, ?>
> choices) {
>         super(id, model, new ArrayList<T>(choices.keySet()), new
> MapChoiceRenderer(choices));
>     }
> 
>     private static class MapChoiceRenderer extends ChoiceRenderer {
> 
>         private final Map map;
> 
>         public MapChoiceRenderer(Map map) {
>             super("value", "key");
>             this.map = map;
>         }
> 
>         public Object getDisplayValue(Object object) {
>             Object value = map.get(object);
>             return value == null ? "" : value.toString();
>         }
> 
>         public String getIdValue(Object object, int index) {
>             return object == null ? "" : object.toString();
>         }
>     }
> 
> }
> 
> public class BeanDropDownChoice<T> extends MapDropDownChoice<T> {
> 
>     public BeanDropDownChoice(String id, List choices, IChoiceRenderer
> renderer) {
>         super(id, createMap(choices, renderer));
>     }
> 
>     public BeanDropDownChoice(String id, IModel<T> model, List choices,
> IChoiceRenderer renderer) {
>         super(id, model, createMap(choices, renderer));
>     }
> 
>     static Map createMap(Collection choices, IChoiceRenderer renderer) {
>         Map map = new HashMap();
>         for (Object choice : choices) {
>             map.put(renderer.getIdValue(choice, -1),
> renderer.getDisplayValue(choice));
>         }
>         return map;
>     }
> }
> 
> 
> 

-- 
View this message in context: http://old.nabble.com/DropDown-where-%28type-of-model-property%29-%21%3D-%28type-of-choices%29-tp25052893p27714412.html
Sent from the Wicket - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: DropDown where (type of model property) != (type of choices)

Posted by elygre <ei...@gmail.com>.

elygre wrote:
> 
> It seems to me that it is a fairly hard requirement that the model and the
> choice list have identical types. I'll investigate a bit further, to see
> if I can build a generic mechanism for both a Map and a "bean"-style
> object.
> 

After looking deeper into this, I created two different specialized
DropDownChoices, with different properties. The class signatures
(interfaces) are as follows with complete code further below

Now, of all the things I did in Wicket, this is the one thing that turned
out to be furthest from expectations. It wasn't the hardest, but it was the
easiest thing that turned out to be hard :-). If there is interest (or at
least no objections...), I'll create a jira issue and submit this code for
inclusion into 1.5.

Class signatures:

public class MapDropDownChoice<T> extends DropDownChoice<T> {
    public MapDropDownChoice(String id, Map<T, ?> choices);
    public MapDropDownChoice(String id, IModel<T> model, Map<T, ?> choices);
}

public class BeanDropDownChoice<T> extends MapDropDownChoice<T> {
    public BeanDropDownChoice(String id, List choices, IChoiceRenderer
renderer);
    public BeanDropDownChoice(String id, IModel<T> model, List choices,
IChoiceRenderer renderer);
}


Full code:
public class MapDropDownChoice<T> extends DropDownChoice<T> {

    public MapDropDownChoice(String id, Map<T, ?> choices) {
        super(id, new ArrayList<T>(choices.keySet()), new
MapChoiceRenderer(choices));
    }

    public MapDropDownChoice(String id, IModel<T> model, Map<T, ?> choices)
{
        super(id, model, new ArrayList<T>(choices.keySet()), new
MapChoiceRenderer(choices));
    }

    private static class MapChoiceRenderer extends ChoiceRenderer {

        private final Map map;

        public MapChoiceRenderer(Map map) {
            super("value", "key");
            this.map = map;
        }

        public Object getDisplayValue(Object object) {
            Object value = map.get(object);
            return value == null ? "" : value.toString();
        }

        public String getIdValue(Object object, int index) {
            return object == null ? "" : object.toString();
        }
    }

}

public class BeanDropDownChoice<T> extends MapDropDownChoice<T> {

    public BeanDropDownChoice(String id, List choices, IChoiceRenderer
renderer) {
        super(id, createMap(choices, renderer));
    }

    public BeanDropDownChoice(String id, IModel<T> model, List choices,
IChoiceRenderer renderer) {
        super(id, model, createMap(choices, renderer));
    }

    static Map createMap(Collection choices, IChoiceRenderer renderer) {
        Map map = new HashMap();
        for (Object choice : choices) {
            map.put(renderer.getIdValue(choice, -1),
renderer.getDisplayValue(choice));
        }
        return map;
    }
}


-- 
View this message in context: http://www.nabble.com/DropDown-where-%28type-of-model-property%29-%21%3D-%28type-of-choices%29-tp25052893p25076154.html
Sent from the Wicket - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: DropDown where (type of model property) != (type of choices)

Posted by "eirik.lygre@gmail.com" <ei...@gmail.com>.
I tried the code from that blog entry, but I don't think it will work. Or
maybe I'm wrong, but...

First, my understanding is that the code has two different types in the
model object and the choices object. In my case, the model object is a
string; and in any case the choices object will be an ArrayList<Map.Entry>.

Because of this, during render the ChoiceRenderer is called with different
types:

a) First, it is called with my model object (a string), from
AbstractSingleSelectChoice.getModelValue() 

	int index = getChoices().indexOf(object);
	return getChoiceRenderer().getIdValue(object, index);
	// calls getIdValue(String,int);

b) Later, it is called many times with the Map.Entry-object from
AbstractChoice.appendOptionHtml():

	T objectValue = (T)renderer.getDisplayValue(choice);
	// calls getDisplayValue(Map.Entry)

It seems to me that it is a fairly hard requirement that the model and the
choice list have identical types. I'll investigate a bit further, to see if
I can build a generic mechanism for both a Map and a "bean"-style object.



igor.vaynberg wrote:
> 
> http://steve-on-sakai.blogspot.com/2008/12/using-hashmap-with-dropdownchoice.html
> 
> -igor
> 
> On Wed, Aug 19, 2009 at 3:17 PM, Eirik Lygre<ei...@gmail.com> wrote:
>> I'm looking for the best way to implement a drop-down, where the type of
>> the
>> model property is not the type of the lists:
>>
> 
> 

-- 
View this message in context: http://www.nabble.com/DropDown-where-%28type-of-model-property%29-%21%3D-%28type-of-choices%29-tp25052893p25058595.html
Sent from the Wicket - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: DropDown where (type of model property) != (type of choices)

Posted by Igor Vaynberg <ig...@gmail.com>.
http://steve-on-sakai.blogspot.com/2008/12/using-hashmap-with-dropdownchoice.html

-igor

On Wed, Aug 19, 2009 at 3:17 PM, Eirik Lygre<ei...@gmail.com> wrote:
> I'm looking for the best way to implement a drop-down, where the type of the
> model property is not the type of the lists:
>
> For example, with the model below, I want to implement a drop-down to select
> languages for a user.
>
>    class User {
>        String languageId;
>    }
>
>    class Language {
>        String languageId;
>        String languageName;
>    }
>
>    // From MyForm extends Form<User>
>    // here, this.getModelObject returns a User
>    // Somewhere in the constructor...
>    ...
>    List<Language> languages = getLanguagesFromDatabase();
>    form.add (new DropDownChoice("languageDropDown", ...eh...?
>    ...
>
> My workaround involves creating a separate model for the language, and copy
> from the language model to the user model whenever I use the user model. But
> it's cumbersome...
>
> 1) Is there a better way?
> 2) Is there an established "best practice" for this (probaly common)
> scenario?
>
>
> Eirik
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: DropDown where (type of model property) != (type of choices)

Posted by Eyal Golan <eg...@gmail.com>.
using ChoiceRenderer?

Eyal Golan
egolan74@gmail.com

Visit: http://jvdrums.sourceforge.net/
LinkedIn: http://www.linkedin.com/in/egolan74

P  Save a tree. Please don't print this e-mail unless it's really necessary


On Thu, Aug 20, 2009 at 1:17 AM, Eirik Lygre <ei...@gmail.com> wrote:

> I'm looking for the best way to implement a drop-down, where the type of
> the
> model property is not the type of the lists:
>
> For example, with the model below, I want to implement a drop-down to
> select
> languages for a user.
>
>    class User {
>        String languageId;
>    }
>
>    class Language {
>        String languageId;
>        String languageName;
>    }
>
>    // From MyForm extends Form<User>
>    // here, this.getModelObject returns a User
>    // Somewhere in the constructor...
>    ...
>    List<Language> languages = getLanguagesFromDatabase();
>    form.add (new DropDownChoice("languageDropDown", ...eh...?
>    ...
>
> My workaround involves creating a separate model for the language, and copy
> from the language model to the user model whenever I use the user model.
> But
> it's cumbersome...
>
> 1) Is there a better way?
> 2) Is there an established "best practice" for this (probaly common)
> scenario?
>
>
> Eirik
>