Bootstrap Multiselect - 动态期权人口

时间:2017-05-02 15:25:25

标签: jquery twitter-bootstrap wicket bootstrap-multiselect

我正在使用Bootstrap Multiselect来满足我的应用程序要求。我的应用程序也使用wicket框架。我正面临一个问题,刷新我的应用程序中的一个bootstrap multiselect。请参考下面的图片

enter image description here

根据从报告区域选择框中选择的值,可用多选项应使用适当的选项进行刷新。虽然使用不同的值修改了底层的常规多选,但位于其上的boostrap multiselect无法刷新。

报告区域选择框正在使用wicketajax,我尝试使用以下代码刷新可用 bootstrap multiselect

<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>

1 个答案:

答案 0 :(得分:1)

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

当您通过availbleId.multiselect();调用创建多选时,引导程序multiselect将一些数据附加到原始选择的dom元素(无法完全回忆起数据的确切含义)。从我对类似问题的调查来看,这些数据对于纠正Bootstrap Multiselect的功能至关重要。

但是,Wicket的Ajax有其他计划。当您通过wicket的ajax重新渲染组件时,wicket所做的是重新呈现组件的HTML(以及可能相关的任何脚本)并将新的html发送到客户端。在浏览器方面,wicket 使用包含新生成的HTML的新DOM元素完全替换旧DOM元素。

你现在可以猜到问题是什么。当wicket替换原始选择的HTML时,Bootstrap Multiselect附加到DOM元素的任何数据都将消失。这会导致多重选择停止工作。

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

@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);
}