使用Jquery Ui自动完成时如何使用Bootstrap Tokenfield防止重复

时间:2015-02-24 06:05:33

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

我正在努力实施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();
    });
});

4 个答案:

答案 0 :(得分:18)

我认为你已经完成了所有工作,你要做的就是更换课程

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

$('.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

答案 1 :(得分:1)

这可以防止列出已添加为令牌的项目:

    $('.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”}源对象进行比较。

答案 2 :(得分:1)

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

注意:我改变了“检查循环”,(双重因为过度杀戮),并添加了一个检查以避免“大写”匹配,以防万一你需要它。

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

答案 3 :(得分:0)

RewriteRule ^cs/(.*)$ cs/compare.php?slug=$1 [L,QSA]