Динамическая поддержка <optgroup>в калитке - PullRequest
5 голосов
/ 15 декабря 2011

Я хочу отобразить тег <select> на своей странице, используя wicket, но сгруппируйте параметры с <optgroup>, это обсуждалось на Разделитель в Wicket DropDownChoice , но в решениях <optgroup> предполагают, что теги <optgroup> являются статическими, я хочу получить опции и группы из базы данных.

Ответы [ 3 ]

4 голосов
/ 15 декабря 2011

Используйте два вложенных повторителя для перебора ваших групп и опций:

<select wicket:id="select">
    <optgroup wicket:id="group">
        <option wicket:id="option"></option>
    </optgroup>
</select>
3 голосов
/ 03 мая 2012

У меня была в основном та же проблема. После нескольких дней поиска короткого решения, я считаю, что для максимальной гибкости лучше всего использовать повторители, контейнеры и AttributeModifier , что-то вроде:

<select wicket:id="select">
    <wicket:container wicket:id="repeatingView">
        <optgroup wicket:id="optGroup">
          <wicket:container wicket:id="selectOptions">
            <option wicket:id="option"></option>
          </wicket:container>
        </optgroup>
    </wicket:container>
</select>

В Java-коде «select» - это Select; «repeatatingView» является RepeatingView. Внутри RepeatingView есть вложенный WebMarkupContainer с именем .newChildId (). Внутри находится еще один WebMarkupContainer, который представляет «optGroup». Внутри этого второго WMC находятся AttributeModifier, который добавляет динамическую метку в optgroup, и SelectOptions, который обрабатывает «selectOptions» и «option». Что-то вроде:

Select select = new Select("select");
add(select);

RepeatingView rv = new RepeatingView("repeatingView");
select.add(rv);

for(String groupName : groupNames){

    WebMarkupContainer overOptGroup = new WebMarkupContainer(rv.newChildId());
    rv.add(overGroup);

    WebMarkupContainer optGroup = new WebMarkupContainer("optGroup");
    overOptGroup.add(optGroup);
    optGroup.add(
        new AttributeModifier("label",true,new Model<String>(groupName))
    );
    optGroup.add(
        new SelectOptions<MyBean>(
            "selectOptions",listOfBeanOptionsForThisGroup,new MyBeanRenderer()
        )
    );
}

(предполагается, что строки передаются напрямую как имена групп и что параметры относятся к компонентам типа MyBean, перечисленным в переменной listOfBeanOptionsForThisGroup)

Я полагаю, что не должно быть сложным преобразовать это решение во что-то, что использует гораздо меньше вложений, если у кого-то есть предложения, я отредактирую их в ответе и внесу в кредит. Использование ListView вместо RepeatingView также должно уменьшить размер кода.

2 голосов
/ 15 декабря 2011

Хорошо, поэтому на данный момент мое решение должно иметь что-то вроде этого:

   interface Thing {
       String getCategory();
   }

, а затем:

            List<Thing> thingList = service.getThings();
    DropDownChoice<Thing> dropDownChoice = new DropDownChoice<Thing>("select",
            thingList) {
        private static final long serialVersionUID = 1L;
        private Thing last;

        private boolean isLast(int index) {
            return index - 1 == getChoices().size();
        }

        private boolean isFirst(int index) {
            return index == 0;
        }

        private boolean isNewGroup(Thing current) {
            return last == null
                    || !current.getCategory().equals(last.getCategory());
        }

        private String getGroupLabel(Thing current) {
            return current.getCategory();
        }

        @Override
        protected void appendOptionHtml(AppendingStringBuffer buffer,
                Thing choice, int index, String selected) {
            if (isNewGroup(choice)) {
                if (!isFirst(index)) {
                    buffer.append("</optgroup>");
                }
                buffer.append("<optgroup label='");
                buffer.append(Strings.escapeMarkup(getGroupLabel(choice)));
                buffer.append("'>");
            }
            super.appendOptionHtml(buffer, choice, index, selected);
            if (isLast(index)) {
                buffer.append("</optgroup>");
            }
            last = choice;

        }
    };

Это требует, чтобы thingList уже было отсортировано накатегория.

...