欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-04-10 13:44:21
在网上找的,效果如下 html代码 flat-ui标签

在网上找的,效果如下

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

 

 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);