Tags
by baivong
HTML
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
<div class="container">
<h1 class="text-center mb-5">Demo</h1>
<div class="form-group">
<label for="categories">Categories</label>
<input type="text" class="form-control taxonomy" id="categories">
</div>
<div class="form-group">
<label for="tags">Tags</label>
<input type="text" class="form-control taxonomy" id="tags">
</div>
<div class="form-group row">
<div class="col-8">
<label for="title">Title</label>
<input type="text" class="form-control" id="title" value="Lorem ipsum dolor sit amet" readonly>
</div>
</div>
<div class="form-group">
<label for="content">Content</label>
<textarea class="form-control" id="content" rows="3" readonly>Nulla tristique et dolor et placerat. Nulla rhoncus nisi ut mi auctor, eget interdum ipsum blandit. Donec semper cursus ex et convallis. Nullam aliquet hendrerit nisl non blandit. Duis porttitor mollis libero, eu faucibus nunc finibus in.</textarea>
</div>
<hr>
<button type="button" class="btn btn-primary">Submit</button>
</div>
CSS
.tag-wrap {
display: flex;
flex-flow: row wrap;
padding: 0 .3em .3em .3em;
height: auto;
}
.tag-typing {
margin-top: .3em;
flex-grow: 1;
min-width: 5ch;
border: 0 none;
outline: 0 none;
}
.tag-item {
display: inline-block;
background: #f4f4f4;
margin-top: .3em;
margin-right: 1ch;
padding: 0 0 0 1ch;
outline: 1px solid #ddd;
border-radius: 4px;
}
.tag-item:hover .tag-close {
color: #F44336;
}
.tag-close:after {
content: "×";
display: inline-block;
padding: 0 1ch 0 .5ch;
cursor: pointer;
}
JavaScript
$.fn.tag = function() {
this.each(function() {
var $input = $(this),
$wrap = $('<div>', {
class: 'form-control tag-wrap'
}),
$typing = $('<input>', {
class: 'tag-typing',
type: 'text'
}),
emptyVal = function() {
$input.val('');
$typing.val('');
$typing.css('width', '1ch');
$wrap.find('.tag-item').remove();
};
$input.attr('type', 'hidden');
$wrap.append($typing);
$wrap.insertAfter($input);
$wrap.on('click', function() {
$typing.focus();
}).on('click', '.tag-close', function() {
var index = $(this).data('index'),
currentVal = $input.val();
currentVal = currentVal.split(',');
currentVal.splice(index, 1);
$input.val(currentVal.join(','));
$input.trigger('change');
});
$input.on('change', function() {
var currentVal = this.value.trim() + ',' + $typing.val().trim();
currentVal = currentVal.replace(/^,+|,+$/, '');
if (currentVal === '') {
emptyVal();
return;
}
currentVal = currentVal.split(',');
currentVal = currentVal.map(function(v) {
return v.trim();
});
currentVal = currentVal.filter(function(v) {
return v !== '';
});
if (!currentVal.length) {
emptyVal();
return;
}
$input.val(currentVal.join(','));
var temp = [];
currentVal.forEach(function(v, i) {
temp.push('<span data-value="' + v + '" class="tag-item">' + v + '<strong data-index="' + i + '" class="tag-close"></strong></span>');
});
temp = temp.join('');
$wrap.find('.tag-item').remove();
$wrap.prepend(temp);
$typing.val('');
$typing.css('width', '1ch');
});
$typing.on('input', function(e) {
var currentVal = this.value;
$typing.css('width', (currentVal.length + 5) + 'ch');
if (currentVal.indexOf(',') !== -1) $input.trigger('change');
...