bootstrap-tagsinput与typeahead的实现自动完成的使用心得

Bootstrap
483
1
1
2022-06-05

今天想弄个tag的自动完成功能,网上搜了下,发现这个插件bootstrap-tagsinput可以使用,

不过都是基于bootstrap4的,现在已经升级到bootstrap5.1了,但是代码还是兼容的,简单测试了下,可以正常使用的,

要使用自动完成,需要整合typeahead.js,下面具体说说怎么实现Tag输入的自动完成。

说之前先列举下官方网站:

bootstrap-tagsinput演示地址

typeahead演示地址

大致效果如下:

Bootstrap 5 Tags Input Examples

一般情况下有两种方式,

第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',]