jquerytwitter-bootstrapbootstrap-tags-input

Bootstrap tags input allow duplicates


I want to allow duplicates in bootstrap tags input.

<input type="text" id="y_data" name="y_data" data-provide="tag" placeholder="Add tags" />

I'm trying to add the same tag when it is exist, but it is not working.

$(function () {
    $('#y_data').tagsinput({
        onTagExists: function(item, $tag) {
            $('#y_data').tagsinput('add', item);
        }
    });
});

Is it correct way or any other solution to achieve my problem.


Solution

  • You need to remove the below code from bootstrap-tagsinput plugin,

      // Ignore items allready added
          var existing = $.grep(self.itemsArray, function(item) { return self.options.itemValue(item) === itemValue; } )[0];
          if (existing) {
            // Invoke onTagExists
            if (self.options.onTagExists) {
              var $existingTag = $(".tag", self.$container).filter(function() { return $(this).data("item") === existing; });
              self.options.onTagExists(item, $existingTag);
            }
            return;
          }
    

    Here is line https://github.com/TimSchlechter/bootstrap-tagsinput/blob/master/src/bootstrap-tagsinput.js#L91

    But this is not good Idea, So I provided monkey patching for this,

    /**
       * HtmlEncodes the given value
       */
    
    var htmlEncodeContainer = $('<div />');
      function htmlEncode(value) {
        if (value) {
          return htmlEncodeContainer.text(value).html();
        } else {
          return '';
        }
      }
       $.fn.tagsinput.Constructor.prototype.add = function (item, dontPushVal) {
          var self = this;
    
          if (self.options.maxTags && self.itemsArray.length >= self.options.maxTags)
            return;
    
          // Ignore falsey values, except false
          if (item !== false && !item)
            return;
    
          // Throw an error when trying to add an object while the itemValue option was not set
          if (typeof item === "object" && !self.objectItems)
            throw("Can't add objects when itemValue option is not set");
    
          // Ignore strings only containg whitespace
          if (item.toString().match(/^\s*$/))
            return;
    
          // If SELECT but not multiple, remove current tag
          if (self.isSelect && !self.multiple && self.itemsArray.length > 0)
            self.remove(self.itemsArray[0]);
    
          if (typeof item === "string" && this.$element[0].tagName === 'INPUT') {
            var items = item.split(',');
            if (items.length > 1) {
              for (var i = 0; i < items.length; i++) {
                this.add(items[i], true);
              }
    
              if (!dontPushVal)
                self.pushVal();
              return;
            }
          }
    
          var itemValue = self.options.itemValue(item),
              itemText = self.options.itemText(item),
              tagClass = self.options.tagClass(item);
    
          // Ignore items allready added
          var existing = $.grep(self.itemsArray, function(item) { return self.options.itemValue(item) === itemValue; } )[0];
          if (existing) {
            // Invoke onTagExists
            if (self.options.onTagExists) {
              var $existingTag = $(".tag", self.$container).filter(function() { return $(this).data("item") === existing; });
              self.options.onTagExists(item, $existingTag);
            }
    
          }
    
          // register item in internal array and map
          self.itemsArray.push(item);
    
          // add a tag element
          var $tag = $('<span class="tag ' + htmlEncode(tagClass) + '">' + htmlEncode(itemText) + '<span data-role="remove"></span></span>');
          $tag.data('item', item);
          self.findInputWrapper().before($tag);
          $tag.after(' ');
    
          // add <option /> if item represents a value not present in one of the <select />'s options
          if (self.isSelect && !$('option[value="' + escape(itemValue) + '"]',self.$element)[0]) {
            var $option = $('<option selected>' + htmlEncode(itemText) + '</option>');
            $option.data('item', item);
            $option.attr('value', itemValue);
            self.$element.append($option);
          }
    
          if (!dontPushVal)
            self.pushVal();
    
          // Add class when reached maxTags
          if (self.options.maxTags === self.itemsArray.length)
            self.$container.addClass('bootstrap-tagsinput-max');
    
          self.$element.trigger($.Event('itemAdded', { item: item }));
        }
    

    Here is JsFiddle Demo