Home > wicket > Super-Easy DropDownChoice Renderer for String values

Super-Easy DropDownChoice Renderer for String values

Too often you may find yourself writing a simple selection list in Wicket.
Whether you know your list values in advance or not, you’ll soon fight with some rendering issue involved with your select component.
Wicket puts at your service the good old DropDownChoice component; good enough to do the job, but it usually force you to use a compound object as its model; If you want to use a simple list of Strings you’ll have to figure out for yourself how to handle “id” and “value” visualization; If not instructed other-way, Wicket will use the “toString” for your object as the display value and its index in the list as its option value.
//DataObject is come kind of value object having the String property "value"...
List<String> values = Arrays.asList( "value_1", "value_2" );
add( new DropDownChoice<String>("my_wicket_id",
                 new PropertyModel<String>(myDataObject, "value"), values ) );
In the preceding code bit, you’ll get a selection list having options with id=1,2,3.. and displayed values of “value_1″, “value_2″..
If you are happy in using the option index as the actual key and/or you don’t have any localization requirement you can be satisfied with it; Otherwise, here’s a very simple yet effective solution to manage the localization thing and keeping the power to choose what information to use as the option key:
public class StringBasedChoiceRenderer implements IChoiceRenderer<String>{
    private static final long serialVersionUID = 1L;
    String context;

    /**
     *
     * @param context can be your wicketId or any other string you desire.
     * this value is used as a prefix in order to get the localized option value.
     */
    public StringBasedChoiceRenderer( String context )
    {
        this.context = context;
    }
    /**
     * To obtain the display value we localize the string obtained concatenating
     * the constructor context value and the actual value of the option.
     */
    public Object getDisplayValue(String object)
    {
        return new ResourceModel( context + "." + object, object ).getObject();
    }

    /**
     * This basic implementation use the entire string value as the option key
     */
    public String getIdValue(String object, int index)
    {
        return object;
    }
}

Using this class is super easy:

List<String> values = Arrays.asList( "value_1", "value_2" );

add( new DropDownChoice<String>("my_wicket_id",
                 new PropertyModel<String>(myDataObject, "value"), values,
                 new StringBasedChoiceRenderer( "options.value" ) ) );

You’ll have, obviously, to add localization strings to your Application property file. NOTE: you have to put localized strings in your Application-wide property files because the renderes uses ResourceModel and it’s not bound to any component:

options.value.value_1=First Value
options.value.value_2=Second Value
Advertisement
Categories: wicket
  1. May 23, 2010 at 12:46 | #1

    Just want to say what a great blog you got here!
    I’ve been around for quite a lot of time, but finally decided to show my appreciation of your work!

    Thumbs up, and keep it going!

    Cheers
    Christian, iwspo.net

    • May 25, 2010 at 00:01 | #2

      Thanx a lot Christian :D
      I’m really happy to see that this blog is appreciated! thanks again for your support :)

  2. gary ogden
    November 4, 2010 at 02:53 | #3

    So how does one associate the picked item from the drop down to a backing bean? So for example you have a bean with a string member. And you want the chosen value (value_1) assigned to the member variable of the pojo bean. Here’s a shortened example:
    ————————————————————
    MyBean myBean = new MyBean();
    ….
    List gendersList = …. from properties file….
    DropDownChoice gendersDDC = new DropDownChoice(“gender”, new Model(),
    gendersList, new ChoiceRenderer(“value”, “name”));
    add(gendersDDC);
    ————————————————————-
    NameValue class is just a pojo with 2 member variables of type String. And myBean has the gender member variable. I assume somehow you assign the model of the bean to the model of the ddc?

    • November 4, 2010 at 19:21 | #4

      In your example, you use an empty Model; in this way there’s no way to connect the DDC with a backing bean.

      The point is that you have to make YOUR Pojo the model of the DDC :)

      The Wicket PropertyModel class is there just for this reason; it acts as a proxy/bridge between your model and the DDC, passing back and forth values between the two.

      In your code, just substitute the call to “Model()” to :

      DropDownChoice gendersDDC =
         new DropDownChoice(“gender”,
             new PropertyModel( yourBean, nameOfYourStringProperty ),
             gendersList, new ChoiceRenderer(“value”, “name”));
      

      At this point, the string property of your bean will be used as a source for the selected option in the list (if not null) and the target when the user select an option.

      I’m going by memory but It should be right. ;)
      Let me know.

  3. gary ogden
    November 4, 2010 at 19:27 | #5

    You’re correct. I did this last night and it worked:
    ——————————————————————————
    List genders = getStringsList(FormsUtil.get(this, “genders”));
    DropDownChoice gendersDDC = new DropDownChoice(“gender”,
    new PropertyModel(myBean, “gender”), genders,
    new StringBasedChoiceRenderer( “gender” )){
    @Override
    public boolean isRequired() {
    return setRequiredFields;
    }
    };
    gendersDDC.setOutputMarkupId(true);
    add(gendersDDC);
    ——————————————————————————
    And in my properties file I have:
    gender.M=Male
    gender.F=Female
    genders=M;F

    The trouble I had was what you mentioned but I overlooked. The fact that they need to be in the application properties file. There can’t be enough emphasis on that one!!

    Great work and thanks for the help.

  4. gary ogden
    November 4, 2010 at 19:31 | #6

    I should add that the line: getStringsList(FormsUtil.get(this, “genders”)) should be explained. I don’t want to put the ids of the drop down in the code, so I added them to the props file as : genders=M;F. One method gets them from the props file, and the other splits them into a list to pass to the dropDownChoice.

    FormsUtil.get() :
    public static String get(Component inst, String key) {
    StringResourceModel srm = new StringResourceModel(key, inst, null);
    String returnString = srm.getString();
    return returnString;
    }

    and get stringsList:
    private List getStringsList(String stringToSplit) {
    List strings = new ArrayList();
    String[] nameValuesSplit = stringToSplit.split(“;”);
    for (int j = 0; j < nameValuesSplit.length; j++) {
    strings.add(nameValuesSplit[j]);
    }
    return strings;
    }

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.