How to prevent duplicate with Bootstrap Tokenfield When using Jquery Ui Autocomplete

前端 未结 4 2033
抹茶落季
抹茶落季 2021-02-06 05:06

I am trying to implement Bootstrap Tokenfield with Jquery Ui autocomplete and so far i was able to do that except the fact that i am not able to prevent duplicates in the input

相关标签:
4条回答
  • 2021-02-06 05:28

    This prevents listing items that have already been added as tokens:

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

    This function is called after token is created or deleted to update the list. It uses JSON.stringify() to compare objects, and does the comparison for string objects and for {value: "foo", label: "bar"} source objects.

    0 讨论(0)
  • 2021-02-06 05:32
    $('.tokenfield').on('tokenfield:createtoken', function (event) {
        var existingTokens = $(this).tokenfield('getTokens');
        $.each(existingTokens, function(index, token) {
            if (token.value === event.attrs.value)
                event.preventDefault();
        });
    });
    
    0 讨论(0)
  • 2021-02-06 05:51

    @Javier Your solution work good but sometimes it gets buggy and add twice the token! Have you got idea for this behaviour?

    PS After seen the documentation i found the solution. Both event handling are needed. Because events are fired before and after creation/edit/remove of tokens.

    So you need this to prevent the add (before create event)

    $('#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;
            }
        });
    });
    

    And this other too, as you suggested, for the source-list (after create event)

    $('#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("");
    });
    

    NOTE: I changed the "check loop", (double for was overkilling), and added a check to avoid "capitalized" matching, just in case you need it.

    function capitalizeFirstLetter(string) {
        return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
    }
    
    0 讨论(0)
  • 2021-02-06 05:52

    I think you've done it all, all you are left to do is to replace the class

    So after the first code, instead of the second code write

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

    The difference here is your class that has to be applied and it works both for Twitter Typeahead and Jquery Ui

    0 讨论(0)
提交回复
热议问题