2011-12-15 3 views
4

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

ответ

2

Итак, в данный момент мое решение, чтобы иметь что-то вроде этого:

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 уже отсортированы на основе категории.

+0

Это почти кажется немного взломанным, когда Wicket предоставляет классы Select, SelectOption и SelectOptions (например, использование ответа пользователя UserBigNum) специально для таких случаев, как optgroup. Но когда я реализовал решение с использованием этих классов, я обнаружил, что вы потеряли некоторые из тонкостей, которые выпекались в DropDownChoice - точнее, он не отображает вариант «Выбрать один» для вас, и вместо него требуется IOptionRenderer вместо ChoiceRenderer. Подход, который вы придумали, вполне может быть лучшим из двух. – spaaarky21

4

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

<select wicket:id="select"> 
    <optgroup wicket:id="group"> 
     <option wicket:id="option"></option> 
    </optgroup> 
</select> 
+1

Но будет ли компонент формы (калитка: id = "select") по-прежнему заполняться выбранным вариантом при отправке формы? –

+0

Yup, он работает, протестировал его. – userBigNum

3

У меня были в основном те же проблемы. Через несколько дней, глядя на короткое решение, я считаю, что лучше всего работает для достижения максимальной гибкости в использовании ретрансляторов, контейнеров и 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 ; «repeatingView» - это 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 также должно уменьшить размер кода.

+0

«Повторяющийся» WebMarkupContainer можно удалить и использовать «optGroup» как повторяющееся представление вместо этого, упрощая его – spuas

Смежные вопросы