<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<!------ Include the above in your HEAD tag ---------->
<div class="container">
<div class="row">
<input type="text" id="taginput" value="bootstrap, 3" class="form-control">
</div>
</div>
/*
Copywrite Square Bracket LLC - Sean Clark 2012-3012
http://square-bracket.com
http://connect.ai
http://youtube.com/optikalefxx
*/
.tags-wrapper {
display: block;
width: 100%;
height: 43px;padding: 6px 12px;
font-size: 14px;
line-height: 1.428571429;
color: #555;
vertical-align: middle;
background-color: #fff;
border: 1px solid #ccc;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);
box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);
-webkit-transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
}
.tags-wrapper ul {
margin:0px;
padding:0px;
}
.tags-wrapper li {
float:left;
list-style:none;
}
.tags-wrapper li.tag {
display: inline-block;
min-width: 10px;
padding: 3px 7px;
font-size: 12px;
font-weight: bold;
line-height: 1;
color: #fff;
text-align: center;
white-space: nowrap;
vertical-align: baseline;
background-color: #999;
border-radius: 10px;
}
.tags-wrapper li a {
text-decoration:none;
color:white;
padding:2px;
display:inline-block;
margin-left:6px;
color: rgb(51, 51, 51);
}
.tags-wrapper li a:hover {
color:#222;
}
.tags-wrapper input {
display:none;
}
.tags-wrapper li.tags-input {
white-space: nowrap;
margin: 0;
padding: 0;
outline:none;
}
.tags-wrapper li input {
display:block;
outline:none;
border:none;
margin: 0 0 8px;
width: 100%;
padding: 6px 12px;
font-size: 10px;
line-height: 1.428571429;
}
.tags-wrapper .autofill-bg {
position:relative;
top:4px;
}
/*
Copywrite Square Bracket LLC - Sean Clark 2012-3012
http://square-bracket.com
http://connect.ai
http://youtube.com/optikalefxx
*/
(function($) {
$.fn.tags = function(opts) {
var selector = this.selector;
//console.log("selector",selector);
// updates the original input
function update($original) {
var all = [];
var list = $original.closest(".tags-wrapper").find("li.tag span").each(function() {
all.push($(this).text());
});
all = all.join(",");
$original.val(all);
}
return this.each(function() {
var self = this,
$self = $(this),
$wrapper = $("<div class='tags-wrapper'><ul></ul></div");
tags = $self.val(),
tagsArray = tags.split(","),
$ul = $wrapper.find("ul");
// make sure have opts
if(!opts) opts = {};
opts.maxSize = 50;
// add tags to start
tagsArray.forEach(function(tag) {
if(tag) {
$ul.append("<li class='tag'><span>"+tag+"</span><a href='#' class='glyphicon glyphicon-remove'></a></li>");
}
});
// get classes on this element
if(opts.classList) $wrapper.addClass(opts.classList);
// add input
$ul.append("<li class='tags-input'><input type='text' class='tags-secret'/></li>");
// set to dom
$self.after($wrapper);
// add the old element
$wrapper.append($self);
// size the text
var $input = $ul.find("input"),
size = parseInt($input.css("font-size"))-4;
// delete a tag
$wrapper.on("click","li.tag a",function(e) {
e.preventDefault();
$(this).closest("li").remove();
$self.trigger("tagRemove",$(this).closest("li").find("span").text());
update($self);
});
// backspace needs to check before keyup
$wrapper.on("keydown","li input",function(e) {
// backspace
if(e.keyCode == 8 && !$input.val()) {
var $li = $ul.find("li.tag:last").remove();
update($self);
$self.trigger("tagRemove",$li.find("span").text());
}
// prevent for tab
if(e.keyCode == 9) {
e.preventDefault();
}
});
// as we type
$wrapper.on("keyup","li input",function(e) {
e.preventDefault();
$ul = $wrapper.find("ul");
var $next = $input.next(),
usingAutoFill = $next.hasClass("autofill-bg"),
$inputLi = $ul.find("li.tags-input");
// regular size adjust
$input.width($input.val().length * (size) );
// if combined with autofill, check the bg for size
if(usingAutoFill) {
$next.width($next.val().length * (size) );
$input.width($next.val().length * (size) );
// make sure autofill doesn't get too big
if($next.width() < opts.maxSize) $next.width(opts.maxSize);
var list = $next.data().data;
}
// make sure we don't get too high
if($input.width() < opts.maxSize) $input.width(opts.maxSize);
// tab, comma, enter
if(!!~[9,188,13].indexOf(e.keyCode)) {
var val = $input.val().replace(",","");
var otherCheck = true;
// requring a tag to be in autofill
if(opts.requireData && usingAutoFill) {
if(!~list.indexOf(val)) {
otherCheck = false;
$input.val("");
}
}
// unique
if(opts.unique) {
// found a match already there
if(!!~$self.val().split(",").indexOf(val)) {
otherCheck = false;
$input.val("");
$next.val("");
}
}
// max tags
if(opts.maxTags) {
if($self.val().split(",").length == opts.maxTags) {
otherCheck = false;
$input.val("");
$next.val("");
}
}
// if we have a value, and other checks pass, add the tag
if(val && otherCheck) {
// place the new tag
$inputLi.before("<li class='tag'><span>"+val+"</span><a href='#' class='glyphicon glyphicon-remove'></a></li>");
// clear the values
$input.val("");
if(usingAutoFill) $next.val("");
update($self);
$self.trigger("tagAdd",val);
}
}
});
});
}
})(jQuery);
$(function() {
$("#taginput").tags({
unique: true,
maxTags: 5
});
});