Bootstrap 多选 - 动态选项填充

Bootstrap Multiselect - Dynamic option population

我正在使用 Bootstrap Multiselect 来满足我的申请要求。我的应用程序也使用 wicket 框架。我在刷新我的应用程序中的 bootstrap multiselect 之一时遇到问题。请参考下图

根据从 Report Area select 框中选择的值,Available multiselect 应该刷新为适当的选项。虽然底层的常规 multiselect 被修改为不同的值,但位于它之上的 boostrap multiselect 无法刷新。

报告区 select 框正在使用 wicketajax,我已尝试使用以下代码刷新 可用 bootstrap多select

<div>Report Area:</div>
<div>
    <select wicket:id="reportArea">
        <option value="TaskCardAssignment">TaskCardAssignment</option>                                                           
    </select>
</div>
<div class="labelbg">Available:</div>
<div class="select">
    <select wicket:id="available" multiple="true" size="15">
       <option value="Workgroup">Workgroup</option>                                                      
    </select>
</div>
<script type="text/javascript">
    var idAvailable = jQuery('[name="attributes:available"]').attr('id');
    var availbleId = jQuery('#'+idAvailable);
    availbleId.multiselect(); //Creates multiselect 

    jQuery('[name="attributes:reportArea"]').change(function(e) {
      setTimeout(function() {
            availbleId.multiselect('rebuild');
            availbleId.multiselect('refresh');
        },0);
    });
</script>

Wicket 的 Ajax 和 Bootstrap Multiselect 不能很好地协同工作。

当您通过 availbleId.multiselect(); 调用创建 multiselect 时,bootstrap multiselect 将一些数据附加到原始元素的 dom 元素select(不太记得数据是什么)。从我对类似问题的调查来看,这些数据似乎对 Bootstrap Multiselect.

的正确功能至关重要

Wicket 的 Ajax 但是,还有其他计划。当您通过 wicket 的 ajax 重新呈现组件时,wicket 所做的是重新呈现组件的 HTML(以及任何可能相关的脚本)并发送新的 html给客户。在浏览器端,wicket 用包含新生成的 HTML.

的新元素完全替换了 旧的 DOM 元素

你现在大概能猜到是什么问题了。当 wicket 将 HTML 替换为原始 select 时,Bootstrap Multiselect 附加到 DOM 元素的任何数据都将消失。这会导致 multiselect 停止工作。

不幸的是,这个问题没有简单的解决方案。与 ListView 之类的东西不同,其中的各个选项也是 wicket 组件,扩展 AbstractChoice 的任何组件中的选项都不是,因此不能单独重新呈现。但是,您可以使用一种解决方案,而不是重新呈现 AbstractChoice,您可以为选项生成 HTML 并编写一些 javascript 来仅替换选项而不是 select 本身。这可以通过做与 wicket 在 AbstractChoice#onComponentTagBody() 中所做的基本相同的事情来完成。也就是说,而不是做

@Override 
protected void onUpdate(final AjaxRequestTarget target) { 
    target.add(availableFields);
}

你可以做类似

@Override 
protected void onUpdate(final AjaxRequestTarget target) { 

    // Generate HTML for the select's options - this is literally the code from AbstractChoice#onComponentTagBody()

    List<? extends T> choices = getChoices();
    final AppendingStringBuffer buffer = new AppendingStringBuffer((choices.size() * 50) + 16);
    final String selectedValue = getValue();

    buffer.append(getDefaultChoice(selectedValue));

    for (int index = 0; index < choices.size(); index++)
    {
        final T choice = choices.get(index);
        appendOptionHtml(buffer, choice, index, selectedValue);
    }

    // Create javascript which will replace the body of the select with the new options
    String replacementJavaScript =
            "$('#" + this.getMarkupId() + "')" +
                    ".replaceWith('" + buffer.toString().replace("'", "\"") + "');";

    String multiselectRefresh = "$(yourMultiselectSelector).multiselect('refresh');"

    target.appendJavaScript(replacementJavaScript + multiselectRefresh);
}