今天想弄个tag的自动完成功能,网上搜了下,发现这个插件bootstrap-tagsinput可以使用,
不过都是基于bootstrap4的,现在已经升级到bootstrap5.1了,但是代码还是兼容的,简单测试了下,可以正常使用的,
要使用自动完成,需要整合typeahead.js,下面具体说说怎么实现Tag输入的自动完成。
说之前先列举下官方网站:
大致效果如下:
一般情况下有两种方式,
第1种是tag的数据不大,比如几十上百个,这样的话可以加载到前端,当自动完成时不会发起Ajax操作。
第2种方式是数据量很大,当你打字时,会实时发起Ajax操作,从后台获取数据,并返回到前端展现出来。
先说第1种,直接上代码吧,新建一个页面,把css加载进去
<link href="https://cdn.staticfile.org/twitter-bootstrap/5.1.3/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.staticfile.org/bootstrap-tagsinput/0.8.0/bootstrap-tagsinput.css" rel="stylesheet">
<style>
/* Twitter Typeahead */
.twitter-typeahead {
}
.typeahead,
.tt-query,
.tt-hint {
outline: 0;
}
.tt-hint {
color: #999;
}
.tt-menu {
width: 100%;
margin-top: 1px;
min-width: 180px;
padding: 8px 0;
background-color: #fff;
border: 1px solid transparent;
border-radius: 3px;
max-height: 300px;
overflow-y: auto;
-webkit-box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);
}
.typeahead-scrollable .tt-menu {
max-height: 250px;
}
.typeahead-rtl .tt-menu {
text-align: right;
}
.tt-suggestion {
padding: 8px 15px;
cursor: pointer;
}
.tt-suggestion:hover,
.tt-suggestion:focus,
.tt-suggestion.tt-cursor {
background-color: #f5f5f5;
}
.tt-dataset-group .tt-suggestion {
padding-left: 32px;
padding-right: 32px;
}
.tt-heading {
font-size: 11px;
line-height: 1.82;
padding: 8px 15px;
text-transform: uppercase;
display: block;
font-weight: 700;
margin-top: 2px;
margin-bottom: 2px;
}
.typeahead-template .empty-message {
padding: 8px 15px;
text-align: center;
}
.bootstrap-tagsinput {
width: 100%;
}
</style>
然后再把js也加载进去
<script src="https://cdn.staticfile.org/twitter-bootstrap/5.1.3/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.staticfile.org/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/typeahead.js/0.11.1/typeahead.bundle.min.js"></script>
<script src="https://cdn.staticfile.org/bootstrap-tagsinput/0.8.0/bootstrap-tagsinput.min.js"></script>
然后在页面中加入一行:
<div style="margin: 10% 30%;"><input id="tags" type="text" class="form-control" name="tags" value="" ></div>
最后加入js的代码,把fruits里面的变量换成自己的内容就可以了
<script>
var fruits = ['Apples', 'Avocado', 'Bananas', 'Blackberries', 'Blueberries',
'Cherries', 'Cranberries', 'Durian', 'Grapefruit', 'Grapes',
'Guava', 'Lemons', 'Mango', 'Olives', 'Oranges', 'Papaya',
'Pineapple', 'Pomegranate', 'Strawberries', 'Watermelon'];
$('#tags').tagsinput({
tagClass: 'badge rounded-pill bg-info',
typeaheadjs:({
hint: true,
highlight: true,
minLength: 1
}, {
source: function(strs) {
return function findMatches(q, cb) {
var matches;
matches = [];
substrRegex = new RegExp(q, 'i');
$.each(strs, function(i, str) {
if (substrRegex.test(str)) {
matches.push(str);
}
});
cb(matches);
};
}(fruits)
})
});
</script>
还有一种方法是从后台加载数据的,get里面的url换成自己后端的URL,代码如下:
<script>
$('#tags').tagsinput({
trimValue: true,
tagClass: 'badge rounded-pill bg-info',
maxTags: 20,
typeaheadjs: {
limit: 99, //下拉框返回数量source: function(query, syncResults, asyncResults) {
//change url to your url
$.get('/get-tag?key=' + query, function(data) {
asyncResults(data);
});
}
}
});
</script>
后端返回数据如下,tag名的Json格式数组,laravel用 Response::json($data); 就可以了
['Apples', 'Avocado', 'Bananas', 'Blackberries',]