v1.0.8
This commit is contained in:
		
							parent
							
								
									eaa25889c3
								
							
						
					
					
						commit
						9416e64e7e
					
				
							
								
								
									
										23
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								CHANGELOG.md
									
									
									
									
									
								
							| @ -1,5 +1,28 @@ | |||||||
| ## 更新日志 | ## 更新日志 | ||||||
| 
 | 
 | ||||||
|  | ### 1.0.8 | ||||||
|  | 
 | ||||||
|  | *2019-10-16* | ||||||
|  | 
 | ||||||
|  | #### 兼容提示 | ||||||
|  | 
 | ||||||
|  | - 此版本的on方法结构调整, 升级请注意 | ||||||
|  | 
 | ||||||
|  | #### 新增 | ||||||
|  | 
 | ||||||
|  | - 新增分组单击事件 click, 可选值 `SELECT`, `CLEAR`, `AUTO`, `自定义` | ||||||
|  | - 新增`append`方法追加赋值, `delete`方法删除赋值 | ||||||
|  | - 新增搜索完成回调`filterDone` | ||||||
|  | 
 | ||||||
|  | #### Bug fixes | ||||||
|  | 
 | ||||||
|  | - 修复全选和请空不走on监听的问题 | ||||||
|  | - 修复`autoRow`模式下, 无选项时的css样式错误 | ||||||
|  | - 修复`update`后, 下拉框显示状态被重置为隐藏 | ||||||
|  | - 优化`setValue`方法, 可自行判断下拉框的显示状态 | ||||||
|  | - 修复文档错误, 实例没有`render`方法 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| ### 1.0.7 | ### 1.0.7 | ||||||
| 
 | 
 | ||||||
| *2019-10-16* | *2019-10-16* | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								dist/static/2.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/static/2.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								dist/static/3.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/static/3.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										4
									
								
								dist/static/docs.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								dist/static/docs.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								dist/xm-select.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/xm-select.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -178,6 +178,9 @@ button, input, select, textarea { | |||||||
| 	display: inline-block; | 	display: inline-block; | ||||||
| 	width: 300px; | 	width: 300px; | ||||||
| } | } | ||||||
|  | .xm-select-demo-alert:extend(.xm-select-demo){ | ||||||
|  |     margin: 20px; | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| .btn{ | .btn{ | ||||||
| 	outline: 0; | 	outline: 0; | ||||||
| @ -206,10 +209,6 @@ button, input, select, textarea { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .demo-ZM03{ | .demo-ZM03{ | ||||||
|     .layui-table-cell{ |  | ||||||
|         height: auto; |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     table{ |     table{ | ||||||
|         margin-bottom: -1px !important; |         margin-bottom: -1px !important; | ||||||
|         border-collapse: unset !important; |         border-collapse: unset !important; | ||||||
|  | |||||||
| @ -140,14 +140,13 @@ var demo5 = xmSelect.render({ | |||||||
|     remoteMethod: function(val, cb, show){ |     remoteMethod: function(val, cb, show){ | ||||||
|         axios({ |         axios({ | ||||||
|             method: 'get', |             method: 'get', | ||||||
|             url: 'https://easy-mock.com/mock/5da028e2cda1720dffee5f85/xm-select/search', |             url: 'https://www.fastmock.site/mock/98228b1f16b7e5112d6c0c87921eabc1/xmSelect/search', | ||||||
|             params: { |             params: { | ||||||
|                 keyword: val, |                 keyword: val, | ||||||
|             } |             } | ||||||
|         }).then(response => { |         }).then(response => { | ||||||
|             var res = response.data; |             var res = response.data; | ||||||
|             cb(res.data) |             cb(res.data) | ||||||
|             demo1.setValue([ 1, 2, 3 ], show)  |  | ||||||
|         }).catch(err => { |         }).catch(err => { | ||||||
|             cb([]); |             cb([]); | ||||||
|         }); |         }); | ||||||
| @ -157,3 +156,28 @@ var demo5 = xmSelect.render({ | |||||||
| </script> | </script> | ||||||
| ``` | ``` | ||||||
| ::: | ::: | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ###  搜索完成回调 | ||||||
|  | 
 | ||||||
|  | :::demo  | ||||||
|  | ```html | ||||||
|  | <div id="demo6" class="xm-select-demo"></div> | ||||||
|  | 
 | ||||||
|  | <script> | ||||||
|  | var demo6 = xmSelect.render({ | ||||||
|  |     el: '#demo6',  | ||||||
|  |     filterable: true, | ||||||
|  |     filterDone: function(val){ | ||||||
|  |         alert('搜索完毕') | ||||||
|  |     }, | ||||||
|  |     data: [ | ||||||
|  |         {name: '水果', value: 1}, | ||||||
|  |         {name: '蔬菜', value: 2}, | ||||||
|  |         {name: '桌子', value: 3}, | ||||||
|  |         {name: '北京', value: 4}, | ||||||
|  |     ] | ||||||
|  | }) | ||||||
|  | </script> | ||||||
|  | ``` | ||||||
|  | ::: | ||||||
|  | |||||||
| @ -12,8 +12,8 @@ | |||||||
| <script> | <script> | ||||||
| var demo1 = xmSelect.render({ | var demo1 = xmSelect.render({ | ||||||
|     el: '#demo1',  |     el: '#demo1',  | ||||||
|     on({ arr, item, selected }){ |     on({ arr, change, isAdd }){ | ||||||
|         alert(`name: ${item.name}, 状态: ${selected}`) |         alert(`已有: ${arr.length} 变化: ${change.length}, 状态: ${isAdd}`) | ||||||
|     }, |     }, | ||||||
|     data: [ |     data: [ | ||||||
|         {name: '张三', value: 'zhangsan', selected: true}, |         {name: '张三', value: 'zhangsan', selected: true}, | ||||||
| @ -37,8 +37,16 @@ var demo1 = xmSelect.render({ | |||||||
| <script> | <script> | ||||||
| var demo2 = xmSelect.render({ | var demo2 = xmSelect.render({ | ||||||
|     el: '#demo2',  |     el: '#demo2',  | ||||||
|     on({ arr, item, selected }){ |     toolbar: { | ||||||
|         if(selected){ |         show: true | ||||||
|  |     }, | ||||||
|  |     on({ arr, change, isAdd }){ | ||||||
|  |         //arr:  当前多选已选中的数据 | ||||||
|  |         //change, 此次选择变化的数据,数组 | ||||||
|  |         //isAdd, 此次操作是新增还是删除 | ||||||
|  |         console.log(arr); | ||||||
|  |         if(isAdd){ | ||||||
|  |             var item = change[0]; | ||||||
|             var index = arr.findIndex(i => i.mutex == item.mutex && i.value != item.value); |             var index = arr.findIndex(i => i.mutex == item.mutex && i.value != item.value); | ||||||
|             if(index != -1){ |             if(index != -1){ | ||||||
|                 arr.splice(index, 1); |                 arr.splice(index, 1); | ||||||
|  | |||||||
| @ -99,3 +99,38 @@ var demo3 = xmSelect.render({ | |||||||
| </script> | </script> | ||||||
| ``` | ``` | ||||||
| ::: | ::: | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ### 分组的单击事件 | ||||||
|  | 
 | ||||||
|  | :::demo  | ||||||
|  | ```html | ||||||
|  | <div id="demo4" class="xm-select-demo"></div> | ||||||
|  | 
 | ||||||
|  | <script> | ||||||
|  | var demo4 = xmSelect.render({ | ||||||
|  |     el: '#demo4',  | ||||||
|  |     toolbar:{ | ||||||
|  |         show: true, | ||||||
|  |     }, | ||||||
|  |     height: '500px', | ||||||
|  |     data: [ | ||||||
|  |         {name: '选中', optgroup: true, click: 'SELECT'}, | ||||||
|  |         {name: '张三', value: 1}, | ||||||
|  |         {name: '李四', value: 2, disabled: true}, | ||||||
|  |         {name: '清空', optgroup: true, click: 'CLEAR'}, | ||||||
|  |         {name: '王五', value: 3, disabled: true}, | ||||||
|  |         {name: '苹果', value: 4, selected: true}, | ||||||
|  |         {name: '自动', optgroup: true, click: 'AUTO'}, | ||||||
|  |         {name: '香蕉', value: 5}, | ||||||
|  |         {name: '葡萄', value: 6}, | ||||||
|  |         {name: '自定义', optgroup: true, click: function(item){ | ||||||
|  |             alert('自定义的, 想干嘛干嘛'); | ||||||
|  |         }}, | ||||||
|  |         {name: '小米', value: 7}, | ||||||
|  |         {name: '华为', value: 8}, | ||||||
|  |     ] | ||||||
|  | }) | ||||||
|  | </script> | ||||||
|  | ``` | ||||||
|  | ::: | ||||||
|  | |||||||
| @ -8,9 +8,13 @@ | |||||||
| :::demo  | :::demo  | ||||||
| ```html | ```html | ||||||
| <div id="demo1" class="xm-select-demo"></div> | <div id="demo1" class="xm-select-demo"></div> | ||||||
|  | <br/><br/> | ||||||
| <button class="btn" id="demo1-test1">赋值张三</button> | <button class="btn" id="demo1-test1">赋值张三</button> | ||||||
| <button class="btn" id="demo1-test2">赋值张三(value方式)</button> | <button class="btn" id="demo1-test2">赋值张三(value方式)</button> | ||||||
| <button class="btn" id="demo1-test3">清空</button> | <button class="btn" id="demo1-test3">追加赋值李四</button> | ||||||
|  | <br/><br/> | ||||||
|  | <button class="btn" id="demo1-test4">清除李四</button> | ||||||
|  | <button class="btn" id="demo1-test5">清空</button> | ||||||
| <pre id="demo1-result"></pre> | <pre id="demo1-result"></pre> | ||||||
| 
 | 
 | ||||||
| <script> | <script> | ||||||
| @ -34,6 +38,14 @@ document.getElementById('demo1-test2').onclick = function(){ | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| document.getElementById('demo1-test3').onclick = function(){ | document.getElementById('demo1-test3').onclick = function(){ | ||||||
|  |     demo1.append([ 2 ]); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | document.getElementById('demo1-test4').onclick = function(){ | ||||||
|  |     demo1.delete([ 2 ]) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | document.getElementById('demo1-test5').onclick = function(){ | ||||||
|     demo1.setValue([ ]) |     demo1.setValue([ ]) | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -15,15 +15,15 @@ layui.use('table', function() { | |||||||
|     //第一个实例 |     //第一个实例 | ||||||
|     table.render({ |     table.render({ | ||||||
|         elem: '#demo', |         elem: '#demo', | ||||||
|         height: 312, |  | ||||||
|         page: true, //开启分页 |         page: true, //开启分页 | ||||||
|  |         height: 500, | ||||||
|         cols: [ |         cols: [ | ||||||
|             [ //表头 |             [ //表头 | ||||||
|                 { field: 'id', title: 'ID', width: 80, sort: true },  |                 { field: 'id', title: 'ID', width: 80, sort: true },  | ||||||
|                 { field: 'username', title: '用户名', width: 80 },  |                 { field: 'username', title: '用户名', width: 80 },  | ||||||
|                 { field: 'sex', title: '性别', width: 80, sort: true },  |                 { field: 'sex', title: '性别', width: 80, sort: true },  | ||||||
|                 { field: 'city', title: '城市', width: 80 },  |                 { field: 'city', title: '城市', width: 80 },  | ||||||
|                 { field: 'sign', title: '爱好', width: 177, templet: function(d){ |                 { field: 'sign', title: '爱好', width: 200, templet: function(d){ | ||||||
|                     return '<div id="XM-' + d.id + '" ></div>' |                     return '<div id="XM-' + d.id + '" ></div>' | ||||||
|                 } },  |                 } },  | ||||||
|                 { field: 'experience', title: '积分', width: 80, sort: true },  |                 { field: 'experience', title: '积分', width: 80, sort: true },  | ||||||
| @ -45,9 +45,17 @@ layui.use('table', function() { | |||||||
|             {"id":10009,"username":"user-9","sex":"女","city":"城市-9","sign":"签名-9","experience":484,"logins":25,"wealth":86801934,"classify":"词人","score":75} |             {"id":10009,"username":"user-9","sex":"女","city":"城市-9","sign":"签名-9","experience":484,"logins":25,"wealth":86801934,"classify":"词人","score":75} | ||||||
|         ], |         ], | ||||||
|         done: function(res){ |         done: function(res){ | ||||||
|  |             //修改一些css样式, 这里虽然能够使用, 但是还是不太友好, 努力中... | ||||||
|  |             var cells = document.querySelectorAll('div[lay-id="demo"] .layui-table-cell'); | ||||||
|  |             for(var i = 0 ; i < cells.length ; i++ ){ | ||||||
|  |                 cells[i].style.overflow = 'unset'; | ||||||
|  |                 cells[i].style.height = 'auto'; | ||||||
|  |             } | ||||||
|  |             //渲染多选 | ||||||
|             res.data.forEach(item =>  { |             res.data.forEach(item =>  { | ||||||
|                 var xm = xmSelect.render({ |                 var xm = xmSelect.render({ | ||||||
|                     el: '#XM-' + item.id,  |                     el: '#XM-' + item.id,  | ||||||
|  |                     autoRow: true, | ||||||
|                     data: [ |                     data: [ | ||||||
|                         {name: '张三', value: 1}, |                         {name: '张三', value: 1}, | ||||||
|                         {name: '李四', value: 2}, |                         {name: '李四', value: 2}, | ||||||
|  | |||||||
							
								
								
									
										35
									
								
								docs/mds/ZM04.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								docs/mds/ZM04.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | |||||||
|  | ## 远程搜索 | ||||||
|  | 
 | ||||||
|  | :::demo  | ||||||
|  | ```html | ||||||
|  | <div id="demo1"></div> | ||||||
|  | 
 | ||||||
|  | <script> | ||||||
|  | var demo1 = xmSelect.render({ | ||||||
|  |     el: '#demo1',  | ||||||
|  |     autoRow: true, | ||||||
|  |     toolbar: { show: true }, | ||||||
|  | 	filterable: true, | ||||||
|  | 	remoteSearch: true, | ||||||
|  | 	remoteMethod: function(val, cb, show){ | ||||||
|  | 		//这里如果val为空, 则不触发搜索 | ||||||
|  | 		if(!val){ | ||||||
|  | 			return cb([]); | ||||||
|  | 		} | ||||||
|  | 	    axios({ | ||||||
|  | 	        method: 'get', | ||||||
|  | 	        url: 'https://www.fastmock.site/mock/98228b1f16b7e5112d6c0c87921eabc1/xmSelect/search', | ||||||
|  | 	        params: { | ||||||
|  | 	            keyword: val, | ||||||
|  | 	        } | ||||||
|  | 	    }).then(response => { | ||||||
|  | 	        var res = response.data; | ||||||
|  | 	        cb(res.data) | ||||||
|  | 	    }).catch(err => { | ||||||
|  | 	        cb([]); | ||||||
|  | 	    }); | ||||||
|  | 	}, | ||||||
|  | }) | ||||||
|  | </script> | ||||||
|  | ``` | ||||||
|  | ::: | ||||||
							
								
								
									
										56
									
								
								docs/mds/ZM05.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								docs/mds/ZM05.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,56 @@ | |||||||
|  | ## 动态数据 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ### 本地数据动态赋值 | ||||||
|  | 
 | ||||||
|  | :::demo  | ||||||
|  | ```html | ||||||
|  | <div id="demo1" class="xm-select-demo"></div> | ||||||
|  | 
 | ||||||
|  | <script> | ||||||
|  | var demo1 = xmSelect.render({ | ||||||
|  |     el: '#demo1',  | ||||||
|  |     data: [] | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | demo1.update({ | ||||||
|  |     data: [ | ||||||
|  |         {name: '张三', value: 1, selected: true}, | ||||||
|  |         {name: '李四', value: 2, selected: true}, | ||||||
|  |         {name: '王五', value: 3, disabled: true}, | ||||||
|  |     ] | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
|  | ``` | ||||||
|  | ::: | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ### 远程数据动态赋值 | ||||||
|  | 
 | ||||||
|  | :::demo  | ||||||
|  | ```html | ||||||
|  | <div id="demo2" class="xm-select-demo"></div> | ||||||
|  | 
 | ||||||
|  | <script> | ||||||
|  | var demo2 = xmSelect.render({ | ||||||
|  |     el: '#demo2',  | ||||||
|  |     toolbar: {show: true}, | ||||||
|  |     data: [] | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | axios({ | ||||||
|  |     method: 'get', | ||||||
|  |     url: 'https://www.fastmock.site/mock/98228b1f16b7e5112d6c0c87921eabc1/xmSelect/search', | ||||||
|  | }).then(response => { | ||||||
|  |     var res = response.data; | ||||||
|  |      | ||||||
|  |     demo2.update({ | ||||||
|  |         data: res.data, | ||||||
|  |         autoRow: true, | ||||||
|  |     }) | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
|  | ``` | ||||||
|  | ::: | ||||||
							
								
								
									
										33
									
								
								docs/mds/ZM06.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								docs/mds/ZM06.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | |||||||
|  | ## 远程搜索 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ### layer弹出框 | ||||||
|  | 
 | ||||||
|  | :::demo  | ||||||
|  | ```html | ||||||
|  | <button class="btn" id="demo1-btn">弹出多选</button> | ||||||
|  | 
 | ||||||
|  | <script> | ||||||
|  | document.getElementById('demo1-btn').onclick = function(){ | ||||||
|  |     layer.open({ | ||||||
|  |         type: 1, | ||||||
|  |         title: '多选', | ||||||
|  |         content: '<div id="demo1" class="xm-select-demo-alert"></div>', | ||||||
|  |         success: function(layero, index){ | ||||||
|  |             //这里因为内容过少, 会被遮挡, 所以简单修改了下样式 | ||||||
|  |             document.getElementById('layui-layer' + index).getElementsByClassName('layui-layer-content')[0].style.overflow = 'unset'; | ||||||
|  |             //渲染多选 | ||||||
|  |             var demo1 = xmSelect.render({ | ||||||
|  |                 el: '#demo1',  | ||||||
|  |                 data: [ | ||||||
|  |                     {name: '张三', value: 1, selected: true}, | ||||||
|  |                     {name: '李四', value: 2, disabled: true}, | ||||||
|  |                     {name: '王五', value: 3}, | ||||||
|  |                 ] | ||||||
|  |             }) | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | ``` | ||||||
|  | ::: | ||||||
| @ -15,6 +15,7 @@ | |||||||
| | searchTips        | 搜索提示 | string           |    -    |    请选择    | | | searchTips        | 搜索提示 | string           |    -    |    请选择    | | ||||||
| | delay             | 搜索延迟 ms | int           |    -    |    500    | | | delay             | 搜索延迟 ms | int           |    -    |    500    | | ||||||
| | filterMethod      | 搜索回调函数 | function(val, item, index, prop)  val: 当前搜索值, item: 每个option选项, index: 位置数据中的下标, prop: 定义key           |    -    |    -    | | | filterMethod      | 搜索回调函数 | function(val, item, index, prop)  val: 当前搜索值, item: 每个option选项, index: 位置数据中的下标, prop: 定义key           |    -    |    -    | | ||||||
|  | | filterDone        | 搜索完成函数 | function(val)  val: 当前搜索值           |    -    |    -    | | ||||||
| | remoteSearch      | 是否开启自定义搜索 (远程搜索)| boolean           |    true / false   |    false    | | | remoteSearch      | 是否开启自定义搜索 (远程搜索)| boolean           |    true / false   |    false    | | ||||||
| | remoteMethod      | 自定义搜索回调函数 | function(val, cb, show)  val: 当前搜索值, cb: 回调函数, 需要回调一个数组, 结构同data, show: 下拉框显示状态         |    -    |    -    | | | remoteMethod      | 自定义搜索回调函数 | function(val, cb, show)  val: 当前搜索值, cb: 回调函数, 需要回调一个数组, 结构同data, show: 下拉框显示状态         |    -    |    -    | | ||||||
| | direction         | 下拉方向| string           |    auto / up / down   |    auto    | | | direction         | 下拉方向| string           |    auto / up / down   |    auto    | | ||||||
| @ -31,7 +32,7 @@ | |||||||
| | show              | 展开下拉的回调 | function           |   -  |    -    | | | show              | 展开下拉的回调 | function           |   -  |    -    | | ||||||
| | hide              | 隐藏下拉的回调 | function           |   -  |    -    | | | hide              | 隐藏下拉的回调 | function           |   -  |    -    | | ||||||
| | template          | 自定义渲染选项 | function({ item, sels, name, value })  |   -  |    -    | | | template          | 自定义渲染选项 | function({ item, sels, name, value })  |   -  |    -    | | ||||||
| | on                | 监听选中变化 | function({ arr, item, selected })  |   -  |    -    | | | on                | 监听选中变化 | function({ arr, change, isAdd })  |   -  |    -    | | ||||||
| | max               | 设置多选选中上限 | int  |   -  |    0    | | | max               | 设置多选选中上限 | int  |   -  |    0    | | ||||||
| | maxMethod         | 达到选中上限的回到 | function(sels, item), sels: 已选中数据, item: 当前选中的值  |   -  |    -    | | | maxMethod         | 达到选中上限的回到 | function(sels, item), sels: 已选中数据, item: 当前选中的值  |   -  |    -    | | ||||||
| | name              | 表单提交时的name  |  string  |   -  |    select    | | | name              | 表单提交时的name  |  string  |   -  |    select    | | ||||||
| @ -45,13 +46,41 @@ | |||||||
| | 参数              | 说明                             | 类型            | 可选值 | 默认值 | | | 参数              | 说明                             | 类型            | 可选值 | 默认值 | | ||||||
| | ----------------- | ------------------------------  | --------------- | ------ | ------ | | | ----------------- | ------------------------------  | --------------- | ------ | ------ | | ||||||
| | name        | 显示名称      | string     |    -    |    name      | | | name        | 显示名称      | string     |    -    |    name      | | ||||||
| | value       | 选中值        | string     |    -    |    value     | | | value       | 选中值, 当前多选唯一        | string     |    -    |    value     | | ||||||
| | selected    | 是否选中      | string     |    -    |    selected      | | | selected    | 是否选中      | string     |    -    |    selected      | | ||||||
| | disabled    | 是否禁用      | string     |    -    |    disabled      | | | disabled    | 是否禁用      | string     |    -    |    disabled      | | ||||||
| | children    | 分组children | string     |    -    |    children      | | | children    | 分组children | string     |    -    |    children      | | ||||||
| | optgroup    | 分组optgroup | string     |    -    |    optgroup      | | | optgroup    | 分组optgroup | string     |    -    |    optgroup      | | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | ### 分组说明 | ||||||
|  | 
 | ||||||
|  | 如果children属性为数组, 或者optgroup=true的时候开启分组模式 | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | //平级结构下面的数据为一组 | ||||||
|  | {name: '城市', optgroup: true}, | ||||||
|  | 
 | ||||||
|  | //children下的数组为一组 | ||||||
|  | {name: '销售员', children: [ | ||||||
|  |     {name: '李四', value: 4, selected: true}, | ||||||
|  |     {name: '王五', value: 5}, | ||||||
|  | ]}, | ||||||
|  | 
 | ||||||
|  | //可在分组上定义click属性, 来定义点击事件 | ||||||
|  | //这里以optgroup模式为例, children模式同理 | ||||||
|  | {name: '选中', optgroup: true, click: 'SELECT'}, | ||||||
|  | {name: '清空', optgroup: true, click: 'CLEAR'}, | ||||||
|  | {name: '自动', optgroup: true, click: 'AUTO'}, | ||||||
|  | {name: '自定义', optgroup: true, click: function(item){ | ||||||
|  |     alert('自定义的, 想干嘛干嘛'); | ||||||
|  | }}, | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| ### theme | ### theme | ||||||
| 
 | 
 | ||||||
| | 参数          | 说明      | 类型            | 可选值 | 默认值 | | | 参数          | 说明      | 类型            | 可选值 | 默认值 | | ||||||
| @ -109,7 +138,7 @@ model: { | |||||||
| | showIcon     | 是否显示工具图标 | boolean     |    true / false    |    true   | | | showIcon     | 是否显示工具图标 | boolean     |    true / false    |    true   | | ||||||
| | list         | 工具条数组 (默认有 全选/清空, 可以自定义)     | array       |    -    |   [ "ALL", "CLEAR" ] | | | list         | 工具条数组 (默认有 全选/清空, 可以自定义)     | array       |    -    |   [ "ALL", "CLEAR" ] | | ||||||
| 
 | 
 | ||||||
| - 自定义方式 | > 自定义方式 | ||||||
| 
 | 
 | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| @ -141,9 +170,10 @@ xmSelect.render()后会返回一个xmSelect对象, 可以进行方法调用 | |||||||
| | 事件名 | 说明               | 参数 | | | 事件名 | 说明               | 参数 | | ||||||
| | ------ | ------------------ | -------- | | | ------ | ------------------ | -------- | | ||||||
| | getValue  | 获取当前选中的数据 | (type: 类型), 可选值: name, nameStr, value, valueStr | | | getValue  | 获取当前选中的数据 | (type: 类型), 可选值: name, nameStr, value, valueStr | | ||||||
| | setValue  | 动态设置数据 | (array: 选中的数据, show: 是否展开下拉) | | | setValue  | 动态设置数据 | (array: 选中的数据, show: 是否展开下拉, 不传默认当前显示状态, 取值: true/false) | | ||||||
|  | | append  | 追加赋值 | (array: 追加的数据) | | ||||||
|  | | delete  | 删除赋值 | (array: 删除的数据) | | ||||||
| | opened  | 主动展开下拉 | - | | | opened  | 主动展开下拉 | - | | ||||||
| | closed  | 主动关闭下拉 | - | | | closed  | 主动关闭下拉 | - | | ||||||
| | render  | 重新渲染多选 | (options: 见配置项) | |  | ||||||
| | reset  | 重置为上一次的render状态 | - | | | reset  | 重置为上一次的render状态 | - | | ||||||
| | update  | 更新多选选中, reset不保留 | - | | | update  | 更新多选选中, reset不保留 | (options: 见配置项) | | ||||||
|  | |||||||
| @ -78,7 +78,10 @@ export default [{ | |||||||
| 		children: [ | 		children: [ | ||||||
|             { path: '/example-custom/ZM01', name: '赋值与取值', component: importMd('/ZM01') }, |             { path: '/example-custom/ZM01', name: '赋值与取值', component: importMd('/ZM01') }, | ||||||
|             { path: '/example-custom/ZM02', name: '表单提交', component: importMd('/ZM02') }, |             { path: '/example-custom/ZM02', name: '表单提交', component: importMd('/ZM02') }, | ||||||
|             // { path: '/example-custom/ZM03', name: '表格中多选', component: importMd('/ZM03') },
 |             { path: '/example-custom/ZM03', name: '表格中多选', component: importMd('/ZM03') }, | ||||||
|  |             { path: '/example-custom/ZM04', name: '远程搜索', component: importMd('/ZM04') }, | ||||||
|  |             { path: '/example-custom/ZM05', name: '动态数据', component: importMd('/ZM05') }, | ||||||
|  |             { path: '/example-custom/ZM06', name: '弹框中的多选', component: importMd('/ZM06') }, | ||||||
|             // { path: '/example-custom/ZTEST', name: '测试', component: importMd('/ZTEST') },
 |             // { path: '/example-custom/ZTEST', name: '测试', component: importMd('/ZTEST') },
 | ||||||
|         ] |         ] | ||||||
| 	}, { | 	}, { | ||||||
|  | |||||||
| @ -169,3 +169,27 @@ export function findSelected(arr, data, prop){ | |||||||
|         } |         } | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | export function addGroupLabel(arr, prop){ | ||||||
|  |     const { disabled, children, optgroup, value } = prop; | ||||||
|  |     let group; | ||||||
|  |     for(let i = 0; i < arr.length; i++){ | ||||||
|  |         let item = arr[i]; | ||||||
|  |         if(item[optgroup]){ | ||||||
|  |             group = item; | ||||||
|  |             group.__value = []; | ||||||
|  |             continue; | ||||||
|  |         } | ||||||
|  |         let child = item[children]; | ||||||
|  |         if(child && child.length > 0){ | ||||||
|  |             group = null; | ||||||
|  |             item.__value = child.filter(c => !c[disabled]).map(c => c[value]); | ||||||
|  |             continue; | ||||||
|  |         } | ||||||
|  |         if(!group || item[disabled]){ | ||||||
|  |             continue; | ||||||
|  |         } | ||||||
|  |         group.__value.push(item[value]); | ||||||
|  |     } | ||||||
|  |     return arr; | ||||||
|  | } | ||||||
|  | |||||||
| @ -71,6 +71,7 @@ export default function (lan = 'zn') { | |||||||
| 			disabled: 'disabled', | 			disabled: 'disabled', | ||||||
|             children: 'children', |             children: 'children', | ||||||
|             optgroup: 'optgroup', |             optgroup: 'optgroup', | ||||||
|  |             click: 'click', | ||||||
| 		}, | 		}, | ||||||
| 		//主题配置
 | 		//主题配置
 | ||||||
| 		theme: { | 		theme: { | ||||||
|  | |||||||
| @ -119,10 +119,33 @@ class xmOptions { | |||||||
| 			warn('请传入数组结构...') | 			warn('请传入数组结构...') | ||||||
| 			return ; | 			return ; | ||||||
| 		} | 		} | ||||||
| 		childs[this.options.el].value(sels, !!show); | 		childs[this.options.el].value(sels, show); | ||||||
| 		return this; | 		return this; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * 追加赋值 | ||||||
|  |      */ | ||||||
|  |     append(sels){ | ||||||
|  |         if(!isArray(sels)){ | ||||||
|  |         	warn('请传入数组结构...') | ||||||
|  |         	return ; | ||||||
|  |         } | ||||||
|  |         childs[this.options.el].append(sels); | ||||||
|  |         return this; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     /** | ||||||
|  |      * 删除赋值 | ||||||
|  |      */ | ||||||
|  |     delete(sels){ | ||||||
|  |         if(!isArray(sels)){ | ||||||
|  |         	warn('请传入数组结构...') | ||||||
|  |         	return ; | ||||||
|  |         } | ||||||
|  |         childs[this.options.el].del(sels); | ||||||
|  |         return this; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -24,7 +24,7 @@ class Framework extends Component{ | |||||||
|         //用于多选上限的边框颜色变化
 |         //用于多选上限的边框颜色变化
 | ||||||
|         this.updateBorderColor(''); |         this.updateBorderColor(''); | ||||||
| 		this.resetDate(props.data); | 		this.resetDate(props.data); | ||||||
| 		this.value(props.initValue ? props.initValue : this.findValue(this.state.data), false); | 		this.value(props.initValue ? props.initValue : this.findValue(this.state.data), !!this.state.show); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|     findValue(data){ |     findValue(data){ | ||||||
| @ -33,21 +33,57 @@ class Framework extends Component{ | |||||||
|         return list; |         return list; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     resetSelectValue(sels = [], change = [], isAdd){ | ||||||
|  |         let on = this.props.on; | ||||||
|  |         if(isFunction(on)){ | ||||||
|  |             on({ arr: sels, change, isAdd }); | ||||||
|  |         } | ||||||
|  |         this.setState({ sels }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
| 	resetDate(data = []){ | 	resetDate(data = []){ | ||||||
| 		this.setState({ data }); | 		this.setState({ data }); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	value(sels, show){ | 	value(sels, show){ | ||||||
|  |         if(show !== false && show !== true){ | ||||||
|  |             show = this.state.show; | ||||||
|  |         } | ||||||
|  |         let changeData = this.exchangeValue(sels); | ||||||
|  |         this.resetSelectValue(changeData, changeData, true); | ||||||
|  | 		this.setState({ show }) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  |     exchangeValue(sels){ | ||||||
|         let data = this.state.data; |         let data = this.state.data; | ||||||
|         let value = this.props.prop.value; |         let value = this.props.prop.value; | ||||||
| 
 |  | ||||||
|         let list = []; |         let list = []; | ||||||
|         filterGroupOption(list, data, this.props.prop); |         filterGroupOption(list, data, this.props.prop); | ||||||
| 		this.setState({ |         return sels.map(sel => typeof sel === 'object' ? sel[value] : sel).map(val => list.find(item => item[value] == val)).filter(a => a); | ||||||
| 			sels: sels.map(sel => typeof sel === 'object' ? sel[value] : sel).map(val => list.find(item => item[value] == val)).filter(a => a), |     } | ||||||
| 			//下拉框是否展开
 | 
 | ||||||
| 			show, |     append(arr){ | ||||||
| 		}) |         let changeData = this.exchangeValue(arr); | ||||||
|  |         this.resetSelectValue(mergeArr(changeData, this.state.sels, this.props.prop), changeData, true); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     del(arr){ | ||||||
|  |         let value = this.props.prop.value; | ||||||
|  |         let sels = this.state.sels; | ||||||
|  |         arr = this.exchangeValue(arr); | ||||||
|  |         arr.forEach(v => { | ||||||
|  |             let index = sels.findIndex(item => item[value] === v[value]); | ||||||
|  |             if(index != -1){ | ||||||
|  |                 sels.splice(index, 1); | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |         this.resetSelectValue(sels, arr, false); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     auto(arr){ | ||||||
|  |         let value = this.props.prop.value; | ||||||
|  |         let sels = arr.filter(v => this.state.sels.findIndex(item => item[value] === v) != -1); | ||||||
|  |         sels.length == arr.length ? this.del(arr) : this.append(arr); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     updateBorderColor(tmpColor){ |     updateBorderColor(tmpColor){ | ||||||
| @ -57,11 +93,25 @@ class Framework extends Component{ | |||||||
| 	onReset(data, type){ | 	onReset(data, type){ | ||||||
|         //重置数据
 |         //重置数据
 | ||||||
|         if(type === 'data'){ |         if(type === 'data'){ | ||||||
|             this.setState({ sels: mergeArr(this.findValue(data), this.state.sels, this.props.prop), data }); |             let changeData = this.findValue(data); | ||||||
|  |             this.resetSelectValue(mergeArr(changeData, this.state.sels, this.props.prop), changeData, true); | ||||||
|  |             this.setState({ data }); | ||||||
|         }else |         }else | ||||||
|         //重置选中数据
 |         //重置选中数据
 | ||||||
|         if(type === 'sels'){ |         if(type === 'sels'){ | ||||||
|             this.setState({ sels: data }); |             this.resetSelectValue(data, data, true); | ||||||
|  |         }else | ||||||
|  |         //追加数据
 | ||||||
|  |         if(type === 'append'){ | ||||||
|  |             this.append(data); | ||||||
|  |         }else | ||||||
|  |         //清理数据
 | ||||||
|  |         if(type === 'delete'){ | ||||||
|  |             this.del(data); | ||||||
|  |         }else | ||||||
|  |         //自动判断模式
 | ||||||
|  |         if(type === 'auto'){ | ||||||
|  |             this.auto(data); | ||||||
|         } |         } | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -157,7 +207,7 @@ class Framework extends Component{ | |||||||
| 				let index = sels.findIndex(sel => sel[valueProp] == item[valueProp]) | 				let index = sels.findIndex(sel => sel[valueProp] == item[valueProp]) | ||||||
| 				if(index != -1){ | 				if(index != -1){ | ||||||
| 					sels.splice(index, 1); | 					sels.splice(index, 1); | ||||||
| 					this.setState({ sels }); | 					this.resetSelectValue(sels, [item], !selected); | ||||||
| 				} | 				} | ||||||
| 			}else{ | 			}else{ | ||||||
|                 //查看是否设置了多选上限
 |                 //查看是否设置了多选上限
 | ||||||
| @ -173,14 +223,12 @@ class Framework extends Component{ | |||||||
| 
 | 
 | ||||||
| 				//如果是单选模式
 | 				//如果是单选模式
 | ||||||
| 				if(radio){ | 				if(radio){ | ||||||
| 					this.setState({ sels: [item] }); | 					this.resetSelectValue([item], [item], !selected); | ||||||
| 				}else{ | 				}else{ | ||||||
| 					this.setState({ sels: [...sels, item] }); | 					this.resetSelectValue([...sels, item], [item], !selected); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			on && on({ arr: this.state.sels, item, selected: !selected }); |  | ||||||
| 
 |  | ||||||
| 			//检查是否为选择即关闭状态, 强制删除情况下不做处理
 | 			//检查是否为选择即关闭状态, 强制删除情况下不做处理
 | ||||||
| 			clickClose && !mandatoryDelete && this.onClick(); | 			clickClose && !mandatoryDelete && this.onClick(); | ||||||
| 		}; | 		}; | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| import { h, Component, render } from '@/components/preact' | import { h, Component, render } from '@/components/preact' | ||||||
| import { isFunction, isArray, safety, mergeArr, IEVersion, filterGroupOption } from '@/components/common/util' | import { isFunction, isArray, safety, deepMerge, mergeArr, IEVersion, filterGroupOption, addGroupLabel } from '@/components/common/util' | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * 普通的多选渲染 |  * 普通的多选渲染 | ||||||
| @ -28,6 +28,21 @@ class General extends Component{ | |||||||
| 		this.blockClick(e); | 		this.blockClick(e); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |     groupClick(item, e){ | ||||||
|  |         let m = item[this.props.prop.click]; | ||||||
|  |         if(m === 'SELECT'){ | ||||||
|  |             this.props.onReset(item.__value, 'append'); | ||||||
|  |         }else if(m === 'CLEAR'){ | ||||||
|  |             this.props.onReset(item.__value, 'delete'); | ||||||
|  |         }else if(m === 'AUTO'){ | ||||||
|  |             this.props.onReset(item.__value, 'auto'); | ||||||
|  |         }else if(isFunction(m)){ | ||||||
|  |             m(item); | ||||||
|  |         } | ||||||
|  |         //阻止父组件上的事件冒泡
 | ||||||
|  |         this.blockClick(e); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
| 	blockClick(e){ | 	blockClick(e){ | ||||||
| 		e.stopPropagation(); | 		e.stopPropagation(); | ||||||
| 	} | 	} | ||||||
| @ -69,6 +84,7 @@ class General extends Component{ | |||||||
|             this.searchCid = setTimeout(() => this.setState({ |             this.searchCid = setTimeout(() => this.setState({ | ||||||
|                 filterValue: this.__value, |                 filterValue: this.__value, | ||||||
|                 remote: true, |                 remote: true, | ||||||
|  |                 callback: true, | ||||||
|             }), this.props.delay); |             }), this.props.delay); | ||||||
|         } |         } | ||||||
| 	} | 	} | ||||||
| @ -107,13 +123,24 @@ class General extends Component{ | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |     componentDidUpdate(){ | ||||||
|  |         if(this.state.callback){ | ||||||
|  |             this.setState({ callback: false }); | ||||||
|  |              | ||||||
|  |             let done = this.props.filterDone; | ||||||
|  |             if(isFunction(done)){ | ||||||
|  |                 done(this.state.filterValue); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
| 	render(config) { | 	render(config) { | ||||||
| 
 | 
 | ||||||
| 		let { data, prop, template, theme, radio, sels, empty, filterable, filterMethod, remoteSearch, remoteMethod, delay, searchTips } = config | 		let { data, prop, template, theme, radio, sels, empty, filterable, filterMethod, remoteSearch, remoteMethod, delay, searchTips } = config | ||||||
| 
 | 
 | ||||||
| 		const { name, value, disabled, children, optgroup } = prop; | 		const { name, value, disabled, children, optgroup } = prop; | ||||||
| 
 | 
 | ||||||
| 		let arr = safety(data); | 		let arr = deepMerge([], data); | ||||||
| 		//是否开启了搜索
 | 		//是否开启了搜索
 | ||||||
| 		if(filterable){ | 		if(filterable){ | ||||||
| 			if(remoteSearch){//是否进行远程搜索
 | 			if(remoteSearch){//是否进行远程搜索
 | ||||||
| @ -232,7 +259,8 @@ class General extends Component{ | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         let safetyArr = safety(arr); |         let safetyArr = deepMerge([], arr); | ||||||
|  | 
 | ||||||
|         //工具条操作
 |         //工具条操作
 | ||||||
|         const toolbar = ( |         const toolbar = ( | ||||||
|             <div class='xm-toolbar'> |             <div class='xm-toolbar'> | ||||||
| @ -294,28 +322,28 @@ class General extends Component{ | |||||||
|             	</div> |             	</div> | ||||||
|             ) |             ) | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|         const renderGroup = item => { |         const renderGroup = item => { | ||||||
|             const isGroup = item[optgroup]; |             const isGroup = item[optgroup]; | ||||||
|             if(isGroup){//分组模式
 |             if(isGroup){//分组模式
 | ||||||
|                 return ( |                 return ( | ||||||
|                     <div class="xm-group"> |                     <div class="xm-group"> | ||||||
|                         <div class="xm-group-item">{ item[name] }</div> |                         <div class="xm-group-item" onClick={ this.groupClick.bind(this, item) }>{ item[name] }</div> | ||||||
|                     </div> |                     </div> | ||||||
|                 ) |                 ) | ||||||
|             } |             } | ||||||
| 
 |  | ||||||
|             const child = item[children]; |             const child = item[children]; | ||||||
|             if(isArray(child) && child.length > 0){//分组模式
 |             if(isArray(child) && child.length > 0){//分组模式
 | ||||||
|                 return ( |                 return ( | ||||||
|                     <div class="xm-group"> |                     <div class="xm-group"> | ||||||
|                         <div class="xm-group-item">{ item[name] }</div> |                         <div class="xm-group-item" onClick={ this.groupClick.bind(this, item) }>{ item[name] }</div> | ||||||
|                         { child.map(renderItem) } |                         { child.map(renderItem) } | ||||||
|                     </div> |                     </div> | ||||||
|                 ) |                 ) | ||||||
|             } |             } | ||||||
|             return renderItem(item); |             return renderItem(item); | ||||||
|         } |         } | ||||||
| 		arr = arr.map(renderGroup); | 		arr = addGroupLabel(arr, prop).map(renderGroup); | ||||||
| 
 | 
 | ||||||
| 		if(!arr.length){ | 		if(!arr.length){ | ||||||
| 			arr.push( | 			arr.push( | ||||||
|  | |||||||
| @ -68,7 +68,7 @@ xm-select{ | |||||||
| 	& > .xm-tips{ | 	& > .xm-tips{ | ||||||
| 		color: #999999; | 		color: #999999; | ||||||
| 		padding: 0 10px; | 		padding: 0 10px; | ||||||
| 		height: 100%; | 		position: absolute; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	& > .xm-icon{ | 	& > .xm-icon{ | ||||||
| @ -116,16 +116,9 @@ xm-select{ | |||||||
| 
 | 
 | ||||||
| 		.scroll{ | 		.scroll{ | ||||||
| 			.label-content{ | 			.label-content{ | ||||||
|                 line-height: @heightLabel; |  | ||||||
| 				height: calc(100% - 20px); |  | ||||||
| 				display: flex; | 				display: flex; | ||||||
| 				align-items: baseline; |                 line-height: @heightLabel; | ||||||
|                 white-space: pre; |  | ||||||
|                 padding: 3px 30px 3px 10px; |                 padding: 3px 30px 3px 10px; | ||||||
| 				&:after{ |  | ||||||
| 					content: '-'; |  | ||||||
| 					opacity: 0; |  | ||||||
| 				} |  | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user