Bootstrap-select,行为类似于 SO 标签字段

Bootstrap-select, behavior like SO tags field

我有一个 bootstrap-select 多模式和实时搜索。我需要添加一个行为,例如 Stack Overflow Tags select: 意思是如果您输入列表中不存在的关键字,则应在您按下逗号后立即添加它。有什么简单的方法可以做到这一点吗?

<select id="@Html.IdForModel()" name="@Html.NameForModel()"
 class="selectpicker form-control" data-live-search="true" multiple></select>

只是为了完整起见:我还在其上使用 https://github.com/truckingsim/Ajax-Bootstrap-Select,但我怀疑这是否重要。

好的,这似乎是一个非常复杂的问题。部分原因是我使用了 Ajax-Bootstrap-Select(认为这微不足道,但事实并非如此)。这段代码有一些问题,比如垃圾邮件 setTimeout - 我对大多数人不在乎,但这段代码应该给任何正在为我遇到的同样问题而苦苦挣扎的人提供一个想法。

var keywordsSelectItemTemplate = $('#@Html.IdForModel()selectItemTemplate').html();
var keywordsSelectBox = $('#@Html.IdForModel()');
var keywordsSelectedElements = [];
// list of words that were persisted
var keywordsAddedElementsStable = [];
// Remembered list of words that are currently in the input box (currently entered)
var keywordsAddedElements = [];

// The search box input
var keywordsSearchBox = keywordsSelectBox.parent().find("div.bs-searchbox").find("input");
// Subscribe to all kind of keypress events to track changes
keywordsSearchBox.bind("propertychange change click keyup input paste",
       function(event) {
                            var value = keywordsSearchBox.val();

                            // Parse words by splitting input box value with ,
                            var keywords = value.split(",").map(function (str) {
                                return str.trim();
                            }).filter(function(str) {
                                return str != undefined && str.length > 0;
                            });

                            // Removing last word, because this is the word that is currently being typed
                            if (keywordsAddedElements.slice(-1).length > 0) {
                                keywordsAddedElements.splice(-1, 1);
                            }

                            // Remembering all words so Bootstrap-Select-Ajax could process them.
                            keywords.forEach(function(keyword) {
                                if ($.inArray(keyword, keywordsAddedElements) === -1) {
                                    keywordsAddedElements.push(keyword);
                                }
                            });

                            // Adding entered words as selected and refresh the selectbox. The timeout should be biger than the timeout defined
                            // in Bootstrap-Select-Ajax, so this refresh will happen after Bootstrap-Select-Ajax process the selected list
                            setTimeout(function() {
                                keywordsSelectBox.val(keywordsSelectBox.val().concat(keywords));
                                keywords.forEach(function(keyword) {
                                    keywordsSelectBox.find("[value=" + keyword + "]").attr('selected', '1');
                                });

                                keywordsSelectBox.selectpicker('refresh');
                                keywordsSelectBox.selectpicker('render');
                            }, 500);
                        });

                    // If we leave search box input - remember the entered items as persisted. 
                    // The user is no longer able to change them, unless by clicking in Bootstrap-Select (as any other items)
                    keywordsSearchBox.focusout(function() {
                        // Refreshing selected items of Bootstrap-Select-Ajax, ensuring that it thinks 
                        // these items were processed as any other.
                        var selectedItems = keywordsSelectBox.ajaxSelectPicker()
                            .data()
                            .AjaxBootstrapSelect.list.selected;
                        keywordsAddedElements.forEach(function(el) {
                            if (!selectedItems.some(function(element) { return element.value === el;})) {
                                selectedItems.push({
                                    "class": "",
                                    data: {
                                        content: el
                                    },
                                    preserved: true,
                                    selected: true,
                                    text: el,
                                    value: el
                                });
                            }
                        });

                        // Remember items as "persisted"
                        keywordsAddedElementsStable = keywordsAddedElementsStable.concat(keywordsAddedElements);
                        keywordsAddedElements = [];

然后在 ajaxSelectPickerpreprocessData:

  // Adding both "persisted" and "temporary" items to the Bootstrap-Select-Ajax list.
   keywordsAddedElementsStable.concat(keywordsAddedElements).forEach(function(el) {
        result.push({
            value: el,
            text: el,
            data: {
                content: el
            }
        });

不使用Ajax-Bootstrap-Select,问题很简单:查找搜索框:

var keywordsSearchBox = keywordsSelectBox.parent().find("div.bs-searchbox").find("input")

订阅更改:

keywordsSearchBox.bind("propertychange change click keyup input paste",
       function(event) { ...

并通过selectBox.selectpicker('val', searchBox.val().split(","));

添加元素