5

Is there some obvious way to add a separator to the list of options in a Wicket DropDownChoice? In my case I'm populating the selection with two types of domain objects from my datasource. I guess I could go and manually add some kind of dummy domain object to the choice list but it feels pretty ugly.

Example:

+---------+-+
| Apple   |▼|
| Orange  +-+
| ------- |
| Carrot  |
| Cucumber|
+---------+

Current code (without any separator) looks something like:

EntityModel model = getModel();
List<? extends Produce> foods = foodService.getAllProduce(); 
// getAllProduce() returns first all fruits, then all vegetables
add(new DropDownChoice<Produce>(
    "produceSelect", new PropertyModel<Produce>(model, "favProduce"), foods)
);
Jonik
  • 80,077
  • 70
  • 264
  • 372
Janne
  • 3,647
  • 7
  • 28
  • 34

3 Answers3

7

I ended up solving this using the Select and SelectOptions components from wicket-extensions as mentioned by martin-g.

SelectOptions<Produce> fruitOptions = new SelectOptions<Produce>(
                                      "fruits",
                                      fruitCollection, 
                                      new FruitRenderer());

SelectOptions<Produce> vegetableOptions = new SelectOptions<Produce>(
                                          "vegetables",
                                          vegetableCollection, 
                                          new VegetableRenderer());

Select select = new Select("produceSelect", 
                           new PropertyModel<Produce>(model, "favProduce"));
select.add(fruitOptions);
select.add(vegetableOptions);

The corresponding HTML looks something like this:

<select wicket:id="produceSelect" id="produceSelect">
    <optgroup label="Fruits">
        <wicket:container wicket:id="fruits">
            <option wicket:id="option">Apple</option>
        </wicket:container>
    </optgroup>
    <optgroup label="Vegetables">
        <wicket:container wicket:id="vegetables">
            <option wicket:id="option">Carrot</option>
        </wicket:container>
    </optgroup>
</select>

This produces a bit different but better end result as the optgroup labels are bolded and cannot be selected:

+----------------+-+
| **Fruits**     |▼|
| Apple          +-+  
| Orange         | 
| **Vegetables** |  
| Carrot         |
| Cucumber       |
+----------------+
Janne
  • 3,647
  • 7
  • 28
  • 34
  • 2
    This solution assumes that you know that the groups will be 'fruits' and 'Vegetables' . What if you dont know the expected groups? – joshua Jan 22 '12 at 08:45
  • In that case, you will not be able to use a SelectOption in this way since under the hood it is just a repeatingListView that needs to have an ID. You might want to create a repeating listviewe directly under the select that in turn contains a SelectOption with a fixed ID? – Willem Mulder May 30 '12 at 13:51
5
    add(new DropDownChoice<String>("choice", Arrays.asList("Apple","Orange","Carrot","Cucumber")) {
        @Override
        protected void appendOptionHtml(AppendingStringBuffer buffer, String choice, int index, String selected) {
            super.appendOptionHtml(buffer, choice, index, selected);
            if ("Orange".equals(choice)) {
                buffer.append("<optgroup label='----------'></optgroup>");
            }
        }
    });
tetsuo
  • 10,726
  • 3
  • 32
  • 35
  • Thing is, PropertyModel is used for a good reason (UI changes propagate nice & automatically down to persistence layer). This approach (giving DropDownChoice simply a list of choices) would complicate how domain objects (& database) get updated. – Jonik Jul 06 '11 at 11:33
  • Er, what? The example is about how to add the separator (overriding `appendOptionHtml()` and appending ``). Passing a list directly was just the simplest thing I could do to make the example to compile and run. Of course you could use the `PropertyModel` and custom classes... – tetsuo Jul 06 '11 at 17:59
  • Ah, sorry, I somehow missed your point (overriding appendOptionHtml()). This would indeed work with PropertyModel just as well. You'd just have to figure out which is the *last* domain object of the *first* type (or first of the second type, which I guess would be easier). So, +1 as this is a viable solution that's at least quicker than switching to Select & SelectOptions from wicket-extensions. – Jonik Jul 06 '11 at 22:01
  • Doesn't this have the problem it will not enclose the ``? The ``. – Matthew Buckett Dec 15 '11 at 14:02
  • Well, the more 'semantically correct' way to do this is using the Select/SelectOption components, as pointed by @martin-g. The `appendOptionHtml()` is a simple hack that may come handy in some situations. By 'hack' I don't mean it'll generate invalid HTML (by itself) or cause any trouble to Wicket, but is not a pure and, again, 'semantically correct' HTML (since the option elements are not grouped by their semantics). But may take fewer lines :) – tetsuo Dec 15 '11 at 19:41
2

See http://www.wicket-library.com/wicket-examples-6.0.x/compref/wicket/bookmarkable/org.apache.wicket.examples.compref.SelectPage There is "Source code" link.

martin-g
  • 17,243
  • 2
  • 23
  • 35