Specialized components MapDropDownChoice, for use when the values of a drop 
down choice is backed by a java.util.Map or a Collection<?>
---------------------------------------------------------------------------------------------------------------------------------------

                 Key: WICKET-2443
                 URL: https://issues.apache.org/jira/browse/WICKET-2443
             Project: Wicket
          Issue Type: New Feature
    Affects Versions: 1.4.1
            Reporter: Eirik Lygre


In working with out first wicket applications, there were two very related 
things that turned out to be a lot harder than expected: 

1) We had a business object with a String property, where we needed to create a 
drop-down list selecting from a Map<String, String>.
2) We had a business object with a String property, with a similar drop down 
backed by a Bean with "String getKey()" and "String getValue()"

After much googling and many trials, we ended up writing the following utility 
classes which I think would be a very useful new feature.

I'm guessing it belongs in either "org.apache.wicket.markup.html.form" or 
"org.apache.wicket.extensions.markup.html.form", but will leave that up to the 
existing maintainers.


Code for the MapDropDownChoice:

import java.util.ArrayList;
import java.util.Map;

import org.apache.wicket.markup.html.form.ChoiceRenderer;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.model.IModel;


/**
 * A specialized DropDownChoice that uses a java.util.Map as the source 
 * of choices (both id and display value).
 * 
 * The type of the model should match the type of the key in the map,
 * such that an Integer model would use a Map<Integer,?>.
 * 
 * <p>
 * Java:
 * 
 * <pre>
 * Map<String,String> countries = new HashMap<String,String>();
 * countries.put ("US", "United States");
 * countries.put ("KG", "Kyrgyzstan");
 * countries.put ("NO", "Norway");
 * countries.put ("VU", "Vanuatu");
 * 
 * // Expect a form model property of name "country" and type String
 * form.add(new MapDropDownChoice<String>("country", countries));
 * </p>
 * 
 * @param <T> Type of model object to bind to.
 */
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();
        }
    }

}


Code for the BeanDropDownChoice:

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.apache.wicket.markup.html.form.IChoiceRenderer;
import org.apache.wicket.model.IModel;


/**
 * A specialized DropDownChoice that uses a collection of Beans
 * as the source of choices (both id and display value).
 *
 * <p>
 * Java:
 *
 * <pre>
 * interface Country {
 *    String getId();
 *    String getName();
 * }
 * Collection<Country> countries;
 *
 * IChoiceRenderer renderer = new ChoiceRenderer<Country>("id", "name");
 *
 * // Expect a form model property of name "country" and type String
 * form.add(new BeanDropDownChoice<String>("country", countries, renderer));
 * </p>
 *
 * @param <T> Type of model object to bind to.
 */
public class BeanDropDownChoice<T> extends MapDropDownChoice<T> {

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

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

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


-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to