当前位置: 移动技术网 > IT编程>开发语言>JavaScript > JQ input输入框回车生成标签,可删除,并获取标签的值

JQ input输入框回车生成标签,可删除,并获取标签的值

2020年01月16日  | 移动技术网IT编程  | 我要评论

在网上找的,效果如下

 

 html代码

<!doctype html>
<html lang="zh-cn">
<head>
<title>flat-ui标签</title>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width" />
<script src="js/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="css/css.css"/>
<script src="js/tagsinput.js" type="text/javascript" charset="utf-8"></script>

</head>
<body>

<div class="box">
    <h1 style="text-align: center;margin: 20px 0;margin-top: 200px;">提取input中的标签</h1>
    <div class="tagsinput-primary form-group">
        <input name="tagsinput" id="tagsinputval" class="tagsinput" data-role="tagsinput" value="faltui,这是一个标签" placeholder="输入后回车"/>
        <button class="btn" onclick="getinput()">获取输入的值</button>
    </div>
</div>

<script type="text/javascript">
function getinput(){
    alert($('#tagsinputval').val());
}
</script>

</body>
</html>

css代码:

*{margin: 0;padding: 0;list-style-type: none;text-decoration: none;}
.box{width: 500px;margin: auto;}
.bootstrap-tagsinput {
  background-color: white;
  border: 2px solid #ebedef;
  border-radius: 6px;
  margin-bottom: 18px;
  padding: 6px 1px 1px 6px;
  text-align: left;
  font-size: 0;
}

.bootstrap-tagsinput .badge {
  border-radius: 4px;
  background-color: #ebedef;
  color: #7b8996;
  font-size: 13px;
  cursor: pointer;
  display: inline-block;
  position: relative;
  vertical-align: middle;
  overflow: hidden;
  margin: 0 5px 5px 0;


  padding: 6px 28px 6px 14px;
  transition: .25s linear;
}

.bootstrap-tagsinput .badge > span {
  color: white;
  padding: 0 10px 0 0;
  cursor: pointer;
  font-size: 12px;
  position: absolute;
  right: 0;
  text-align: right;
  text-decoration: none;
  top: 0;
  width: 100%;
  bottom: 0;
  z-index: 2;
}

.bootstrap-tagsinput .badge > span:after {
  content: "x";
  font-family: "flat-ui-pro-icons";
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  line-height: 27px;
}

@media (hover: hover) {
  .bootstrap-tagsinput .badge {
    padding: 6px 21px;
  }
  .bootstrap-tagsinput .badge > span {
    opacity: 0;
    filter: "alpha(opacity=0)";
    transition: opacity .25s linear;
  }
  .bootstrap-tagsinput .badge:hover {
    background-color: #16a085;
    color: white;
    padding-right: 28px;
    padding-left: 14px;
  }
  .bootstrap-tagsinput .badge:hover > span {
    padding: 0 10px 0 0;
    opacity: 1;
    -webkit-filter: none;
            filter: none;
  }
}


.bootstrap-tagsinput input[type="text"] {
  font-size: 14px;
  border: none;
  box-shadow: none;
  outline: none;
  background-color: transparent;
  padding: 0;
  margin: 0;
  width: auto !important;
  max-width: inherit;
  min-width: 80px;
  vertical-align: top;
  height: 29px;
  color: #34495e;
}

    .tagsinput-primary {
  margin-bottom: 18px;
}

.tagsinput-primary .bootstrap-tagsinput {
  border-color: #1abc9c;
  margin-bottom: 0;
}

.tagsinput-primary .badge {
  background-color: #1abc9c;
  color: white;
}
.btn{background: #1abc9c;border: none;color: #fff;padding: 10px;border-radius: 5px;margin-top: 10px;}

jq代码:

 /* bootstrap-tagsinput v0.8.0
 */

(function ($) {
  "use strict";

  var defaultoptions = {
    tagclass: function(item) {
      return 'badge badge-info';
    },
    focusclass: 'focus',
    itemvalue: function(item) {
      return item ? item.tostring() : item;
    },
    itemtext: function(item) {
      return this.itemvalue(item);
    },
    itemtitle: function(item) {
      return null;
    },
    freeinput: true,
    addonblur: true,
    maxtags: undefined,
    maxchars: undefined,
    confirmkeys: [13, 44],
    delimiter: ',',
    delimiterregex: null,
    cancelconfirmkeysonempty: false,
    ontagexists: function(item, $tag) {
      $tag.hide().fadein();
    },
    trimvalue: false,
    allowduplicates: false,
    triggerchange: true
  };

  /**
   * constructor function
   */
  function tagsinput(element, options) {
    this.isinit = true;
    this.itemsarray = [];

    this.$element = $(element);
    this.$element.hide();

    this.isselect = (element.tagname === 'select');
    this.multiple = (this.isselect && element.hasattribute('multiple'));
    this.objectitems = options && options.itemvalue;
    this.placeholdertext = element.hasattribute('placeholder') ? this.$element.attr('placeholder') : '';
    this.inputsize = math.max(1, this.placeholdertext.length);

    this.$container = $('<div class="bootstrap-tagsinput"></div>');
    this.$input = $('<input type="text" placeholder="' + this.placeholdertext + '"/>').appendto(this.$container);

    this.$element.before(this.$container);

    this.build(options);
    this.isinit = false;
  }

  tagsinput.prototype = {
    constructor: tagsinput,

    /**
     * adds the given item as a new tag. pass true to dontpushval to prevent
     * updating the elements val()
     */
    add: function(item, dontpushval, options) {
      var self = this;

      if (self.options.maxtags && self.itemsarray.length >= self.options.maxtags)
        return;

      // ignore falsey values, except false
      if (item !== false && !item)
        return;

      // trim value
      if (typeof item === "string" && self.options.trimvalue) {
        item = $.trim(item);
      }

      // 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 delimiter = (self.options.delimiterregex) ? self.options.delimiterregex : self.options.delimiter;
        var items = item.split(delimiter);
        if (items.length > 1) {
          for (var i = 0; i < items.length; i++) {
            this.add(items[i], true);
          }

          if (!dontpushval)
            self.pushval(self.options.triggerchange);
          return;
        }
      }

      var itemvalue = self.options.itemvalue(item),
          itemtext = self.options.itemtext(item),
          tagclass = self.options.tagclass(item),
          itemtitle = self.options.itemtitle(item);

      // ignore items allready added
      var existing = $.grep(self.itemsarray, function(item) { return self.options.itemvalue(item) === itemvalue; } )[0];
      if (existing && !self.options.allowduplicates) {
        // invoke ontagexists
        if (self.options.ontagexists) {
          var $existingtag = $(".badge", self.$container).filter(function() { return $(this).data("item") === existing; });
          self.options.ontagexists(item, $existingtag);
        }
        return;
      }

      // if length greater than limit
      if (self.items().tostring().length + item.length + 1 > self.options.maxinputlength)
        return;

      // raise beforeitemadd arg
      var beforeitemaddevent = $.event('beforeitemadd', { item: item, cancel: false, options: options});
      self.$element.trigger(beforeitemaddevent);
      if (beforeitemaddevent.cancel)
        return;

      // register item in internal array and map
      self.itemsarray.push(item);

      // add a tag element

      var $tag = $('<span class="badge ' + htmlencode(tagclass) + (itemtitle !== null ? ('" title="' + itemtitle) : '') + '">' + htmlencode(itemtext) + '<span data-role="remove"></span></span>');
      $tag.data('item', item);
      self.findinputwrapper().before($tag);
      $tag.after(' ');

      // check to see if the tag exists in its raw or uri-encoded form
      var optionexists = (
        $('option[value="' + encodeuricomponent(itemvalue) + '"]', self.$element).length ||
        $('option[value="' + htmlencode(itemvalue) + '"]', self.$element).length
      );

      // add <option /> if item represents a value not present in one of the <select />'s options
      if (self.isselect && !optionexists) {
        var $option = $('<option selected>' + htmlencode(itemtext) + '</option>');
        $option.data('item', item);
        $option.attr('value', itemvalue);
        self.$element.append($option);
      }

      if (!dontpushval)
        self.pushval(self.options.triggerchange);

      // add class when reached maxtags
      if (self.options.maxtags === self.itemsarray.length || self.items().tostring().length === self.options.maxinputlength)
        self.$container.addclass('bootstrap-tagsinput-max');

      // if using typeahead, once the tag has been added, clear the typeahead value so it does not stick around in the input.
      if ($('.typeahead, .twitter-typeahead', self.$container).length) {
        self.$input.typeahead('val', '');
      }

      if (this.isinit) {
        self.$element.trigger($.event('itemaddedoninit', { item: item, options: options }));
      } else {
        self.$element.trigger($.event('itemadded', { item: item, options: options }));
      }
    },

    /**
     * removes the given item. pass true to dontpushval to prevent updating the
     * elements val()
     */
    remove: function(item, dontpushval, options) {
      var self = this;

      if (self.objectitems) {
        if (typeof item === "object")
          item = $.grep(self.itemsarray, function(other) { return self.options.itemvalue(other) ==  self.options.itemvalue(item); } );
        else
          item = $.grep(self.itemsarray, function(other) { return self.options.itemvalue(other) ==  item; } );

        item = item[item.length-1];
      }

      if (item) {
        var beforeitemremoveevent = $.event('beforeitemremove', { item: item, cancel: false, options: options });
        self.$element.trigger(beforeitemremoveevent);
        if (beforeitemremoveevent.cancel)
          return;

        $('.badge', self.$container).filter(function() { return $(this).data('item') === item; }).remove();
        $('option', self.$element).filter(function() { return $(this).data('item') === item; }).remove();
        if($.inarray(item, self.itemsarray) !== -1)
          self.itemsarray.splice($.inarray(item, self.itemsarray), 1);
      }

      if (!dontpushval)
        self.pushval(self.options.triggerchange);

      // remove class when reached maxtags
      if (self.options.maxtags > self.itemsarray.length)
        self.$container.removeclass('bootstrap-tagsinput-max');

      self.$element.trigger($.event('itemremoved',  { item: item, options: options }));
    },

    /**
     * removes all items
     */
    removeall: function() {
      var self = this;

      $('.badge', self.$container).remove();
      $('option', self.$element).remove();

      while(self.itemsarray.length > 0)
        self.itemsarray.pop();

      self.pushval(self.options.triggerchange);
    },

    /**
     * refreshes the tags so they match the text/value of their corresponding
     * item.
     */
    refresh: function() {
      var self = this;
      $('.badge', self.$container).each(function() {
        var $tag = $(this),
            item = $tag.data('item'),
            itemvalue = self.options.itemvalue(item),
            itemtext = self.options.itemtext(item),
            tagclass = self.options.tagclass(item);

          // update tag's class and inner text
          $tag.attr('class', null);
          $tag.addclass('badge ' + htmlencode(tagclass));
          $tag.contents().filter(function() {
            return this.nodetype == 3;
          })[0].nodevalue = htmlencode(itemtext);

          if (self.isselect) {
            var option = $('option', self.$element).filter(function() { return $(this).data('item') === item; });
            option.attr('value', itemvalue);
          }
      });
    },

    /**
     * returns the items added as tags
     */
    items: function() {
      return this.itemsarray;
    },

    /**
     * assembly value by retrieving the value of each item, and set it on the
     * element.
     */
    pushval: function() {
      var self = this,
          val = $.map(self.items(), function(item) {
            return self.options.itemvalue(item).tostring();
          });

      self.$element.val(val, true);

      if (self.options.triggerchange)
        self.$element.trigger('change');
    },

    /**
     * initializes the tags input behaviour on the element
     */
    build: function(options) {
      var self = this;

      self.options = $.extend({}, defaultoptions, options);
      // when itemvalue is set, freeinput should always be false
      if (self.objectitems)
        self.options.freeinput = false;

      makeoptionitemfunction(self.options, 'itemvalue');
      makeoptionitemfunction(self.options, 'itemtext');
      makeoptionfunction(self.options, 'tagclass');

      // typeahead bootstrap version 2.3.2
      if (self.options.typeahead) {
        var typeahead = self.options.typeahead || {};

        makeoptionfunction(typeahead, 'source');

        self.$input.typeahead($.extend({}, typeahead, {
          source: function (query, process) {
            function processitems(items) {
              var texts = [];

              for (var i = 0; i < items.length; i++) {
                var text = self.options.itemtext(items[i]);
                map[text] = items[i];
                texts.push(text);
              }
              process(texts);
            }

            this.map = {};
            var map = this.map,
                data = typeahead.source(query);

            if ($.isfunction(data.success)) {
              // support for angular callbacks
              data.success(processitems);
            } else if ($.isfunction(data.then)) {
              // support for angular promises
              data.then(processitems);
            } else {
              // support for functions and jquery promises
              $.when(data)
               .then(processitems);
            }
          },
          updater: function (text) {
            self.add(this.map[text]);
            return this.map[text];
          },
          matcher: function (text) {
            return (text.tolowercase().indexof(this.query.trim().tolowercase()) !== -1);
          },
          sorter: function (texts) {
            return texts.sort();
          },
          highlighter: function (text) {
            var regex = new regexp( '(' + this.query + ')', 'gi' );
            return text.replace( regex, "<strong>$1</strong>" );
          }
        }));
      }

      // typeahead.js
      if (self.options.typeaheadjs) {
        // determine if main configurations were passed or simply a dataset
        var typeaheadjs = self.options.typeaheadjs;
        if (!$.isarray(typeaheadjs)) {
            typeaheadjs = [null, typeaheadjs];
        }

        $.fn.typeahead.apply(self.$input, typeaheadjs).on('typeahead:selected', $.proxy(function (obj, datum, name) {
          var index = 0;
          typeaheadjs.some(function(dataset, _index) {
            if (dataset.name === name) {
              index = _index;
              return true;
            }
            return false;
          });

          // @todo dep: https://github.com/corejavascript/typeahead.js/issues/89
          if (typeaheadjs[index].valuekey) {
            self.add(datum[typeaheadjs[index].valuekey]);
          } else {
            self.add(datum);
          }

          self.$input.typeahead('val', '');
        }, self));
      }

      self.$container.on('click', $.proxy(function(event) {
        if (! self.$element.attr('disabled')) {
          self.$input.removeattr('disabled');
        }
        self.$input.focus();
      }, self));

        if (self.options.addonblur && self.options.freeinput) {
          self.$input.on('focusout', $.proxy(function(event) {
              // hack: only process on focusout when no typeahead opened, to
              //       avoid adding the typeahead text as tag
              if ($('.typeahead, .twitter-typeahead', self.$container).length === 0) {
                self.add(self.$input.val());
                self.$input.val('');
              }
          }, self));
        }

      // toggle the 'focus' css class on the container when it has focus
      self.$container.on({
        focusin: function() {
          self.$container.addclass(self.options.focusclass);
        },
        focusout: function() {
          self.$container.removeclass(self.options.focusclass);
        },
      });

      self.$container.on('keydown', 'input', $.proxy(function(event) {
        var $input = $(event.target),
            $inputwrapper = self.findinputwrapper();

        if (self.$element.attr('disabled')) {
          self.$input.attr('disabled', 'disabled');
          return;
        }

        switch (event.which) {
          // backspace
          case 8:
            if (dogetcaretposition($input[0]) === 0) {
              var prev = $inputwrapper.prev();
              if (prev.length) {
                self.remove(prev.data('item'));
              }
            }
            break;

          // delete
          case 46:
            if (dogetcaretposition($input[0]) === 0) {
              var next = $inputwrapper.next();
              if (next.length) {
                self.remove(next.data('item'));
              }
            }
            break;

          // left arrow
          case 37:
            // try to move the input before the previous tag
            var $prevtag = $inputwrapper.prev();
            if ($input.val().length === 0 && $prevtag[0]) {
              $prevtag.before($inputwrapper);
              $input.focus();
            }
            break;
          // right arrow
          case 39:
            // try to move the input after the next tag
            var $nexttag = $inputwrapper.next();
            if ($input.val().length === 0 && $nexttag[0]) {
              $nexttag.after($inputwrapper);
              $input.focus();
            }
            break;
         default:
             // ignore
         }

        // reset internal input's size
        var textlength = $input.val().length,
            wordspace = math.ceil(textlength / 5),
            size = textlength + wordspace + 1;
        $input.attr('size', math.max(this.inputsize, size));
      }, self));

      self.$container.on('keypress', 'input', $.proxy(function(event) {
         var $input = $(event.target);

         if (self.$element.attr('disabled')) {
            self.$input.attr('disabled', 'disabled');
            return;
         }

         var text = $input.val(),
         maxlengthreached = self.options.maxchars && text.length >= self.options.maxchars;
         if (self.options.freeinput && (keycombinationinlist(event, self.options.confirmkeys) || maxlengthreached)) {
            // only attempt to add a tag if there is data in the field
            if (text.length !== 0) {
               self.add(maxlengthreached ? text.substr(0, self.options.maxchars) : text);
               $input.val('');
            }

            // if the field is empty, let the event triggered fire as usual
            if (self.options.cancelconfirmkeysonempty === false) {
                event.preventdefault();
            }
         }

         // reset internal input's size
         var textlength = $input.val().length,
            wordspace = math.ceil(textlength / 5),
            size = textlength + wordspace + 1;
         $input.attr('size', math.max(this.inputsize, size));
      }, self));

      // remove icon clicked
      self.$container.on('click', '[data-role=remove]', $.proxy(function(event) {
        if (self.$element.attr('disabled')) {
          return;
        }
        self.remove($(event.target).closest('.badge').data('item'));
      }, self));

      // only add existing value as tags when using strings as tags
      if (self.options.itemvalue === defaultoptions.itemvalue) {
        if (self.$element[0].tagname === 'input') {
            self.add(self.$element.val());
        } else {
          $('option', self.$element).each(function() {
            self.add($(this).attr('value'), true);
          });
        }
      }
    },

    /**
     * removes all tagsinput behaviour and unregsiter all event handlers
     */
    destroy: function() {
      var self = this;

      // unbind events
      self.$container.off('keypress', 'input');
      self.$container.off('click', '[role=remove]');

      self.$container.remove();
      self.$element.removedata('tagsinput');
      self.$element.show();
    },

    /**
     * sets focus on the tagsinput
     */
    focus: function() {
      this.$input.focus();
    },

    /**
     * returns the internal input element
     */
    input: function() {
      return this.$input;
    },

    /**
     * returns the element which is wrapped around the internal input. this
     * is normally the $container, but typeahead.js moves the $input element.
     */
    findinputwrapper: function() {
      var elt = this.$input[0],
          container = this.$container[0];
      while(elt && elt.parentnode !== container)
        elt = elt.parentnode;

      return $(elt);
    }
  };

  /**
   * register jquery plugin
   */
  $.fn.tagsinput = function(arg1, arg2, arg3) {
    var results = [];

    this.each(function() {
      var tagsinput = $(this).data('tagsinput');
      // initialize a new tags input
      if (!tagsinput) {
          tagsinput = new tagsinput(this, arg1);
          $(this).data('tagsinput', tagsinput);
          results.push(tagsinput);

          if (this.tagname === 'select') {
              $('option', $(this)).attr('selected', 'selected');
          }

          // init tags from $(this).val()
          $(this).val($(this).val());
      } else if (!arg1 && !arg2) {
          // tagsinput already exists
          // no function, trying to init
          results.push(tagsinput);
      } else if(tagsinput[arg1] !== undefined) {
          // invoke function on existing tags input
            if(tagsinput[arg1].length === 3 && arg3 !== undefined){
               var retval = tagsinput[arg1](arg2, null, arg3);
            }else{
               var retval = tagsinput[arg1](arg2);
            }
          if (retval !== undefined)
              results.push(retval);
      }
    });

    if ( typeof arg1 == 'string') {
      // return the results from the invoked function calls
      return results.length > 1 ? results : results[0];
    } else {
      return results;
    }
  };

  $.fn.tagsinput.constructor = tagsinput;

  /**
   * most options support both a string or number as well as a function as
   * option value. this function makes sure that the option with the given
   * key in the given options is wrapped in a function
   */
  function makeoptionitemfunction(options, key) {
    if (typeof options[key] !== 'function') {
      var propertyname = options[key];
      options[key] = function(item) { return item[propertyname]; };
    }
  }
  function makeoptionfunction(options, key) {
    if (typeof options[key] !== 'function') {
      var value = options[key];
      options[key] = function() { return value; };
    }
  }
  /**
   * htmlencodes the given value
   */
  var htmlencodecontainer = $('<div />');
  function htmlencode(value) {
    if (value) {
      return htmlencodecontainer.text(value).html();
    } else {
      return '';
    }
  }

  /**
   * returns the position of the caret in the given input field
   * http://flightschool.acylt.com/devnotes/caret-position-woes/
   */
  function dogetcaretposition(ofield) {
    var icaretpos = 0;
    if (document.selection) {
      ofield.focus ();
      var osel = document.selection.createrange();
      osel.movestart ('character', -ofield.value.length);
      icaretpos = osel.text.length;
    } else if (ofield.selectionstart || ofield.selectionstart == '0') {
      icaretpos = ofield.selectionstart;
    }
    return (icaretpos);
  }

  /**
    * returns boolean indicates whether user has pressed an expected key combination.
    * @param object keypressevent: javascript event object, refer
    *     http://www.w3.org/tr/2003/wd-dom-level-3-events-20030331/ecma-script-binding.html
    * @param object lookuplist: expected key combinations, as in:
    *     [13, {which: 188, shiftkey: true}]
    */
  function keycombinationinlist(keypressevent, lookuplist) {
      var found = false;
      $.each(lookuplist, function (index, keycombination) {
          if (typeof (keycombination) === 'number' && keypressevent.which === keycombination) {
              found = true;
              return false;
          }

          if (keypressevent.which === keycombination.which) {
              var alt = !keycombination.hasownproperty('altkey') || keypressevent.altkey === keycombination.altkey,
                  shift = !keycombination.hasownproperty('shiftkey') || keypressevent.shiftkey === keycombination.shiftkey,
                  ctrl = !keycombination.hasownproperty('ctrlkey') || keypressevent.ctrlkey === keycombination.ctrlkey;
              if (alt && shift && ctrl) {
                  found = true;
                  return false;
              }
          }
      });

      return found;
  }

  /**
   * initialize tagsinput behaviour on inputs and selects which have
   * data-role=tagsinput
   * zmm2113@qq.com 2018.6.24
   */
  $(function() {
    $("input[data-role=tagsinput], select[multiple][data-role=tagsinput]").tagsinput();
  });
})(window.jquery);

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网