bootstrap-select

这里要实现的是带有搜索功能的select框

bootstrap 官网没有可以直接拿来用的。如下是官网给出的解释,带搜索功能的select需要自定义。

在网上找到了有自己用javascript+html+css生写的,代码量比较大,有两百多行,我拷贝了,试运行过,是没有问题,可以直接用的。

如下是我找的别人的原创博客地址。

https://blog.csdn.net/L333333333/article/details/102556003

我自己另外找了一个可以引用的组件,在特定的位置加上属性,即可实现bootstrap渲染的带搜索框的select标签,下面是我找的另一人的原创博客地址,

博客中的demo,直接copy可以运行,达到预期的效果,亲测有效。

https://blog.csdn.net/xb12369/article/details/50999265

 我自己在实际生产中,发现不能直接拿着人家的组件直接用,会有其他问题引出来,我已经解决了,所以写博客加以补充。

先介绍一下缘由,上面的两个例子里面,都能实现select框带模糊查询功能,因为是给出的demo示例,所以,option标签都是预先在页面上写死的,

但是,我们的实际生产中,select里面的option标签值,有的时候,是需要从后端接口拿到数据,然后才能进行渲染的,这个时候,就会牵扯到浏览器异步的问题。

我自己的这个项目里面,select里面是人员名单,而人员名单是需要从后端接口拿到数据,然后再用js进行渲染,这个时候,就会出现,Ajax调用后端接口,

还没有等Ajax拿到返回值结果,bootstrap-select组件就已经预加载了,而这个时候,option标签里面是没有数据信息的,所以,按照上面的用法,

bootstrap-select组件渲染的结果里面是没有数据的。

解决办法就是让他们变成同步的。

我自己的项目里面,window.onload里面是一个Ajax函数,这个Ajax函数是调用后端接口拿到返回值信息,然后在Ajax的回调函数里面用js去创建option标签,渲染页面。

我的解决办法就是,把触发bootstrap-select的jquery代码,放到我的Ajax回调函数里面,这样,在Ajax内部就完成了同步。

<link rel="stylesheet"
          href="{% static bootstrap %}bootstrap-3.3.7-dist/css/bootstrap.css"> <!-- 这里是我自己项目内部配置的本地的bootstrap的css引用库 -->

    <title>Title</title>
<!-- 这里是引用的cdn的jquery,jQuery的引用一定要放在最顶上,因为下面boostrap-select.js以及boostrap.js都需要建立在jQuery基础上 -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> 
   <!-- 这里是bootstrap-select css&js cdn引用 --> <script type="text/javascript" src="http://cdn.bootcss.com/bootstrap-select/2.0.0-beta1/js/bootstrap-select.js"></script> <link rel="stylesheet" type="text/css" href="http://cdn.bootcss.com/bootstrap-select/2.0.0-beta1/css/bootstrap-select.css"> <!-- 这里是我项目本地配置的bootstrap js引用库3.0 --> <script src="{% static bootstrap %}bootstrap-3.3.7-dist/js/bootstrap.js"></script>

<script>

//Ajax的前半截就不复制了,直接上Ajax回调函数部分,
xmlHttp.onreadystatechange = function (data) {
if (xmlHttp.readyState === 4 &&
(
(xmlHttp.status >= 200 && xmlHttp.status < 300)
|| xmlHttp.status === 304)
) {
    //拿到Ajax的回调函数,解析出来
    let response_data = data.srcElement.response;
    //get object type of data which backend transfer
    let parsed_data = JSON.parse(response_data).data;
    //拿到返回值之后,用js渲染标签
    show_option_data(parsed_data);
    //渲染完成之后,再触发bootstrap-select的组件
    $('.test-select').selectpicker();

  }
}

</script>

<!-- 如下是标签的属性绑定,这是单选的用法,如果需要多选,只需要在此基础上加上 multipule 即可-->
<select data-live-search="true" class="test-select"></select>

我自己把上面两个人的博客里面的代码,在自己博客里面备份一下,以防别人博客删除,没有线索了。

JavaScript+html+css

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 <head>
  4     <meta charset="UTF-8">
  5     <title>javascript+html+css--select-search</title>
  6     <style type="text/css">
  7 
  8         *{
  9             padding: 0;
 10             margin: 0;
 11         }
 12 
 13         body{
 14             width: 100vw;
 15             height: calc(100vh - 20px);
 16         }
 17 
 18         div.select select{
 19             display: none;
 20         }
 21 
 22         div.select-box{
 23             width: 200px;
 24             margin: 20px 20px;
 25         }
 26 
 27         div.select-head{
 28             position: relative;
 29             height: 30px;
 30             width: 100%;
 31             display: flex;
 32             border: solid 1px #000;
 33             align-items: center;
 34             cursor: pointer;
 35         }
 36 
 37         div.select-head span{
 38             font-size: 16px;
 39             margin-left: 5px;
 40             color: #AAA;
 41         }
 42 
 43         div.select-head span.fill{
 44             color: #000;
 45         }
 46 
 47         div.select-head i{
 48             position: absolute;
 49             height: 16px;
 50             width: 16px;
 51             right: 5px;
 52             background-image: url(./arrow.png);
 53             background-size: 16px auto;
 54         }
 55 
 56         div.select-body{
 57             display: none;
 58             width: 100%;
 59             border: solid 1px #000;
 60             border-top: none;
 61         }
 62 
 63         div.search-input{
 64             position: relative;
 65             height: 40px;
 66         }
 67 
 68         div.search-input input{
 69             height: 30px;
 70             width: 150px;
 71             margin: 5px 8px;
 72             text-indent: 10px;
 73             padding-right: 30px;
 74         }
 75 
 76         div.search-input i{
 77             position: absolute;
 78             display: block;
 79             height: 20px;
 80             width: 20px;
 81             top: 12px;
 82             right: 15px;
 83             background-image: url(./search-normal.png);
 84             background-size: 20px 20px;
 85             cursor: pointer;
 86         }
 87 
 88         div.search-input i:hover{
 89             background-image: url(./search-active.png);
 90         }
 91 
 92         div.value-body{
 93             max-height: 150px;
 94             overflow: auto;
 95         }
 96 
 97         div.value-body li{
 98             display: flex;
 99             height: 24px;
100             padding: 5px 5px;
101             font-size: 14px;
102             align-items: center;
103             cursor: pointer;
104         }
105 
106         div.value-body li:hover,li.active{
107             background-color: #F5F6FA;
108         }
109 
110         div.value-body li.none,div.none{
111             display: none;
112         }
113 
114         div.value-body div{
115             text-align: center;
116             height: 30px;
117             line-height: 30px;
118             color: #AAA;
119         }
120     </style>
121     <script type="text/javascript">
122         window.onload = function () {
123             //清空select的value
124             document.querySelector('div.select>select').value = ''
125 
126             /**
127              * 点击自定义的select框开启或收回选择框
128              */
129             document.querySelector('div.select-head').onclick = function () {
130                 //清空输入框内容
131                 document.querySelector('div.search-input>input').value = ''
132 
133                 document.querySelectorAll('div.value-body>li').forEach( function(element, index) {
134                     if (element.classList.contains('active')) {
135                         element.classList = 'active'
136                     }else {
137                         element.classList = ''
138                     }
139                 });
140 
141                 document.querySelector('div.value-body>div').classList = 'none'
142 
143                 var select_body = document.querySelector('div.select-body')
144                 if (select_body.style.display == 'block')
145                     select_body.style.display = 'none'
146                 else
147                     select_body.style.display = 'block'
148             };
149 
150             /**
151              * 点击空白处关闭select框
152              */
153             document.onclick = function (argument) {
154                 if(!argument.target.classList.contains('s')){
155                     var select_body = document.querySelector('div.select-body')
156                     if (select_body.style.display == 'block')
157                         select_body.style.display = 'none'
158                 }
159             }
160 
161             /**
162              * 自定义的select的选值功能
163              */
164             document.querySelectorAll('div.value-body>li').forEach( function(element, index) {
165                 element.onclick = function () {
166                     //初始化下样式
167                     document.querySelectorAll('div.value-body>li').forEach( function(element, index) {
168                         element.classList = ''
169                     });
170                     element.classList = 'active'
171                     //更新select框的value和自定义的select框的value
172                     var data_value = element.getAttribute('data-value')
173                     var select_head_span = document.querySelector('div.select-head>span')
174                     document.querySelector('div.select>select').value = data_value
175                     select_head_span.innerHTML = data_value
176                     if(!select_head_span.classList.contains('fill'))
177                         select_head_span.classList = 'fill'
178 
179                     //关闭select-body
180                     document.querySelector('div.select-body').style.display = 'none'
181                 }
182             });
183 
184             /**
185              * 搜素功能实现
186              */
187             document.querySelector('div.search-input>input').oninput = function () {
188                 var input_value = document.querySelector('div.search-input>input').value
189                 if(input_value == '') {
190                     document.querySelectorAll('div.value-body>li').forEach( function(element, index) {
191                         if (element.classList.contains('active')) {
192                             element.classList = 'active'
193                         }else {
194                             element.classList = ''
195                         }
196                     });
197                 }else{
198                     document.querySelectorAll('div.value-body>li').forEach( function(element, index) {
199                         if(element.getAttribute('data-value').indexOf(input_value) == -1){
200                                 if (element.classList.contains('active')) {
201                                     element.classList += ' none'
202                                 }else {
203                                     element.classList = 'none'
204                                 }
205                         }else {
206                             if(element.classList.contains('none')) {
207                                 document.querySelectorAll('div.value-body>li').forEach( function(element, index) {
208                                     if (element.classList.contains('active')) {
209                                         element.classList = 'active'
210                                     }else {
211                                         element.classList = ''
212                                     }
213                                 });
214                             }
215                         }
216                     });
217                 }
218                 //记一下结果数量
219                 var length = 0
220                 document.querySelectorAll('div.value-body>li').forEach( function(element, index) {
221                     if (!element.classList.contains('none')) length++
222                 });
223 
224                 if (length == 0) {
225                     document.querySelector('div.value-body>div').classList = ''
226                 }else{
227                     document.querySelector('div.value-body>div').classList = 'none'
228                 }
229             }
230         };
231     </script>
232 </head>
233 <body>
234     <div class="select">
235         <select name="select-name">
236             <option value="" disabled="true">请选择</option>
237             <option value="选择1">选择1</option>
238             <option value="选择2">选择2</option>
239             <option value="选择3">选择3</option>
240             <option value="选择4">选择4</option>
241             <option value="选择5">选择5</option>
242             <option value="选择6">选择6</option>
243             <option value="选择7">选择7</option>
244             <option value="选择8">选择8</option>
245             <option value="选择9">选择9</option>
246             <option value="选择10">选择10</option>
247         </select>
248         <div class="s select-box">
249             <div class="s select-head">
250                 <span class="s">请选择</span>
251                 <i class="s"></i>
252             </div>
253             <div class="s select-body">
254                 <div class="s search-input">
255                     <input class="s" type="text" placeholder="搜索">
256                     <i class="s"></i>
257                 </div>
258                 <div class="s value-body">
259                     <li data-value="选择1">选择1</li>
260                     <li data-value="选择2">选择2</li>
261                     <li data-value="选择3">选择3</li>
262                     <li data-value="选择4">选择4</li>
263                     <li data-value="选择5">选择5</li>
264                     <li data-value="选择6">选择6</li>
265                     <li data-value="选择7">选择7</li>
266                     <li data-value="选择8">选择8</li>
267                     <li data-value="选择9">选择9</li>
268                     <li data-value="选择10">选择10</li>
269                     <div class="none">暂无匹配选项</div>
270                 </div>
271             </div>
272         </div>
273     </div>
274 </body>
275 </html>
View Code

boostrap-select

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <title>jQuery bootstrap-select</title>
 5     <!-- set jquery cdn -->
 6     <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
 7 
 8     <!-- set bootstrap-select js and css -->
 9     <script type="text/javascript" src="http://cdn.bootcss.com/bootstrap-select/2.0.0-beta1/js/bootstrap-select.js"></script>
10     <link rel="stylesheet" type="text/css" href="http://cdn.bootcss.com/bootstrap-select/2.0.0-beta1/css/bootstrap-select.css">
11 
12     <!-- 3.0 cnd bootstrap css and js -->
13     <link href="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet">
14     <script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
15     <script type="text/javascript">
16         $(window).on('load', function () {
17 
18             $('.selectpicker').selectpicker();//one way set no params
19             //$('.selectpicker').selectpicker( //another way set params
20             // { 'selectedText': 'cat' }
21             // )
22 
23             // $('.selectpicker').selectpicker('hide');
24         });
25     </script>
26 </head>
27 <body>
28 <div>
29 
30     <label for="id_select">Test label YEag</label>
31     <select id="id_select" class="selectpicker bla bla bli"
32             multiple data-live-search="true">
33         <option>cow</option>
34         <option>bull</option>
35         <option class="get-class" disabled>ox</option>
36         <optgroup label="test" data-subtext="another test" data-icon="icon-ok">
37             <option>ASD</option>
38             <option selected>Bla</option>
39             <option>Ble</option>
40         </optgroup>
41     </select>
42 
43     <div class="container">
44         <form class="form-horizontal" role="form">
45             <div class="form-group">
46                 <label for="bs3Select" class="col-lg-2 control-label">Test bootstrap 3 form</label>
47                 <div class="col-lg-10">
48                     <select id="bs3Select" class="selectpicker show-tick form-control" multiple data-live-search="true">
49                         <option>cow</option>
50                         <option>bull</option>
51                         <option class="get-class" disabled>ox</option>
52                         <optgroup label="test" data-subtext="another test" data-icon="icon-ok">
53                             <option>ASD</option>
54                             <option selected>Bla</option>
55                             <option>Ble</option>
56                         </optgroup>
57                     </select>
58                 </div>
59               </div>
60         </form>
61     </div>
62     </div>
63 
64 </body>
65 </html>
View Code
原文地址:https://www.cnblogs.com/2012-dream/p/14793873.html