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>
|
||||||
@ -25,8 +29,8 @@ var demo1 = xmSelect.render({
|
|||||||
|
|
||||||
document.getElementById('demo1-test1').onclick = function(){
|
document.getElementById('demo1-test1').onclick = function(){
|
||||||
demo1.setValue([
|
demo1.setValue([
|
||||||
{name: '张三', value: 1},
|
{name: '张三', value: 1},
|
||||||
])
|
])
|
||||||
};
|
};
|
||||||
|
|
||||||
document.getElementById('demo1-test2').onclick = function(){
|
document.getElementById('demo1-test2').onclick = function(){
|
||||||
@ -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,22 +33,58 @@ 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){
|
||||||
let data = this.state.data;
|
if(show !== false && show !== true){
|
||||||
let value = this.props.prop.value;
|
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 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){
|
||||||
this.setState({ tmpColor });
|
this.setState({ 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…
Reference in New Issue
Block a user