【问题标题】:Dynamic <optgroup> support in wicketwicket 中的动态 <optgroup> 支持
【发布时间】:2011-12-15 14:04:02
【问题描述】:

我希望使用检票口在我的页面中呈现&lt;select&gt; 标记,但将选项与&lt;optgroup&gt; 分组,这已在Separator in a Wicket DropDownChoice 上讨论过,但在解决方案中&lt;optgroup&gt; 假设@ 987654325@ 标签是静态的,我想从数据库中提取选项和组。

【问题讨论】:

    标签: java forms wicket optgroup


    【解决方案1】:

    使用两个嵌套的中继器来迭代您的组和选项:

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

    【讨论】:

    • 但是在提交表单时表单组件(wicket:id="select")是否仍会填充所选选项?
    【解决方案2】:

    我遇到了基本相同的问题。在寻找一个简短的解决方案几天后,我相信最有效的方法是使用 repeaters、containers 和 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; “repeatingView”是一个重复视图。嵌套在 RepeatingView 中有一个由 .newChildId() 命名的 WebMarkupContainer。嵌套在里面的是另一个代表“optGroup”的 WebMarkupContainer。在第二个 WMC 内部是一个 AttributeModifier,它向 optgroup 添加动态标签,以及一个处理“selectOptions”和“option”的 SelectOptions。比如:

    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 类型的 bean,列在变量 listOfBeanOptionsForThisGroup 中)

    我想将这个解决方案重构为使用更少嵌套的东西应该不难,如果有人有建议,我会将它们编辑成答案并归功于他们。使用 ListView 而不是 RepeatingView 也应该减少代码大小。

    【讨论】:

    • “repeatingView”WebMarkupContainer 可以去掉,改用“optGroup”作为重复视图,更简单
    【解决方案3】:

    好的,所以目前我的解决方案是这样的:

       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 已经根据类别排序。

    【讨论】:

    • 当 Wicket 专门为 optgroup 等情况提供 Select、SelectOption 和 SelectOptions 类(如 userBigNum 的答案使用)时,这似乎有点 hacky。但是当我使用这些类实现一个解决方案时,我发现你失去了一些融入 DropDownChoice 的细节——更具体地说,它不会为你呈现“选择一个”选项,它需要一个 IOptionRenderer 而不是一个选择渲染器。您提出的方法很可能是两者中更好的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-17
    • 1970-01-01
    • 1970-01-01
    • 2012-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多