【问题标题】:How to prevent duplicate with Bootstrap Tokenfield When using Jquery Ui Autocomplete使用Jquery Ui自动完成时如何防止与Bootstrap Tokenfield重复
【发布时间】:2017-02-27 09:17:15
【问题描述】:

我正在尝试实现Bootstrap Tokenfield with Jquery Ui autocomplete 到目前为止,我能够做到这一点,除了我无法防止输入字段中的重复,因此,不幸的是,我的用户可以选择两次相同的值。

在我的搜索中,我发现 Bootstrap Tokenfield 有一个preventing duplicate 的方式。但是我不知道如何应用到我的代码,因为在我看来它与 Twitter typeahead 而不是 Jquery Ui 一起使用。

如何使用 Jquery Ui 自动完成功能防止 Bootstrap TokenField 重复?

这是我基于 jquery ui 自动完成的 Bootstrap TokenField 代码

$('.tokenfield').tokenfield({
  autocomplete: {
    source: [
    {
        "id": "1",
        "value": "Ferdine Faithfull" 
    },
    {
        "id": "2",
        "value": "John Carta" 
    },
    {
        "id": "3",
        "value": "Mezane Smith" 
    }
    ],

    delay: 100
  },
  showAutocompleteOnFocus: true
});

以下是我在 Github 上发现的防止重复的内容,尽管我认为它适用于 Typeahead

$('#my-tokenfield').on('tokenfield:createtoken', function (event) {
    var existingTokens = $(this).tokenfield('getTokens');
    $.each(existingTokens, function(index, token) {
        if (token.value === event.attrs.value)
            event.preventDefault();
    });
});

【问题讨论】:

    标签: twitter-bootstrap jquery-ui-autocomplete bootstrap-tokenfield


    【解决方案1】:

    我想你已经全部完成了,剩下要做的就是替换类

    所以在第一个代码之后,而不是第二个代码编写

    $('.tokenfield').on('tokenfield:createtoken', function (event) {
        var existingTokens = $(this).tokenfield('getTokens');
        $.each(existingTokens, function(index, token) {
            if (token.value === event.attrs.value)
                event.preventDefault();
        });
    });
    

    这里的区别是你的类必须被应用,它适用于 Twitter Typeahead 和 Jquery Ui

    【讨论】:

      【解决方案2】:

      这可以防止列出已添加为标记的项目:

          $('.tokenfield').on('tokenfield:createdtoken tokenfield:removedtoken', function (event) {
          var field = $(this);
          var currentTokens = field.tokenfield('getTokens');
          var originalSource = field.data('bs.tokenfield').options.autocomplete.source;
          var newSource = originalSource.slice(); //clone original autocomplete source
          for (var i = newSource.length - 1; i >= 0; i--) {
            for (var j = currentTokens.length - 1; j >= 0; j--) {
              if (JSON.stringify(currentTokens[j].label) == JSON.stringify(newSource[i]) 
                || JSON.stringify(currentTokens[j]) == JSON.stringify(newSource[i]) ) {
                //remove the token from the newSource
                var index = newSource.indexOf(newSource[i]);
                if (index > -1) 
                  newSource.splice(index, 1);
              };
            };
          };
          //update source
          field.data('bs.tokenfield').$input.autocomplete({source: newSource})
      })
      

      该函数在创建或删除令牌后调用以更新列表。它使用 JSON.stringify() 来比较对象,并对字符串对象和 {value: "foo", label: "bar"} 源对象进行比较。

      【讨论】:

        【解决方案3】:

        @Javier 您的解决方案运行良好,但有时它会出现错误并添加两倍的令牌!您对这种行为有什么想法吗?

        PS 在查看文档后,我找到了解决方案。两个事件处理都是需要的。因为在创建/编辑/删除令牌之前和之后都会触发事件。

        所以你需要这个来防止添加(在创建事件之前)

        $('#tokenfield').on('tokenfield:createtoken', function (event) {
            var existingTokens = $(this).tokenfield('getTokens');
            //check the capitalized version
            event.attrs.value =  capitalizeFirstLetter(event.attrs.value);
            $.each(existingTokens, function(index, token) {
                if (token.value === event.attrs.value) {
                    event.preventDefault();
                    return false;
                }
            });
        });
        

        正如你所建议的,另一个也是源列表(在创建事件之后)

        $('#tokenfield').on('tokenfield:createdtoken tokenfield:removedtoken', function (event) {
            var field = $(this);
            var currentTokens = field.tokenfield('getTokens').map(function(i){return i.value});
            var originalSource = field.data('bs.tokenfield').options.autocomplete.source;
            var newSource = [];
            for (var i = 0; i<originalSource.length; i++) {
              if(currentTokens.indexOf(originalSource[i])==-1){
                newSource.push(originalSource[i]);
              }
            };
            //update source
            field.data('bs.tokenfield').$input.autocomplete({source: newSource});
            //empty the input field
            $(".tokenfield.form-control").find("input.token-input").val("");
        });
        

        注意:我更改了“检查循环”,(double for 太过分了),并添加了一个检查以避免“大写”匹配,以防万一。

        function capitalizeFirstLetter(string) {
            return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-09-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-05-31
          • 2017-07-24
          相关资源
          最近更新 更多