v1.1.9
This commit is contained in:
parent
308e0b64e1
commit
1ae32b8ed1
17
CHANGELOG.md
17
CHANGELOG.md
@ -1,5 +1,22 @@
|
||||
## 更新日志
|
||||
|
||||
### 1.1.9
|
||||
|
||||
*2020-05-04*
|
||||
|
||||
#### 新增
|
||||
|
||||
- tree新增配置`simple`, 代表极简模式, 子级全部被选中后只会显示父级
|
||||
|
||||
#### Bug fixes
|
||||
|
||||
- 设置远程模式`totalSize`默认为1
|
||||
- 修复普通多选模式下设置`max`配置后, 工具条的全选和反选 选中数据错误
|
||||
- 修复`getValue`方法获取到的部分数据中携带`__node`参数无法进行序列化
|
||||
- 修复同时开启远程搜索和远程分页的时候会出发两次`remoteMethod`
|
||||
- 优化`remoteMethod`的内部回调机制
|
||||
|
||||
|
||||
### 1.1.8
|
||||
|
||||
*2020-02-10*
|
||||
|
4
dist/static/2.js
vendored
4
dist/static/2.js
vendored
File diff suppressed because one or more lines are too long
4
dist/static/3.js
vendored
4
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
4
dist/xm-select.js
vendored
4
dist/xm-select.js
vendored
File diff suppressed because one or more lines are too long
@ -18,6 +18,8 @@ tree: {
|
||||
expandedKeys: [],
|
||||
//是否严格遵守父子模式
|
||||
strict: true,
|
||||
//是否开启极简模式
|
||||
simple: false,
|
||||
},
|
||||
```
|
||||
|
||||
@ -32,6 +34,7 @@ tree: {
|
||||
<input type="checkbox" name="showFolderIcon" lay-filter="showFolderIcon" lay-skin="primary" title="是否展示三角图标" checked>
|
||||
<input type="checkbox" name="showLine" lay-filter="showLine" lay-skin="primary" title="是否显示虚线" checked>
|
||||
<input type="checkbox" name="strict" lay-filter="strict" lay-skin="primary" title="严格父子结构" checked>
|
||||
<input type="checkbox" name="simple" lay-filter="simple" lay-skin="primary" title="极简模式">
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 20px">间距</div>
|
||||
@ -41,7 +44,7 @@ tree: {
|
||||
<script>
|
||||
layui.form.render();
|
||||
|
||||
['showFolderIcon', 'showLine', 'strict'].forEach(function(key){
|
||||
['showFolderIcon', 'showLine', 'strict', 'simple'].forEach(function(key){
|
||||
layui.form.on('checkbox('+key+')', function(data){
|
||||
var treeConfig = {};
|
||||
treeConfig[key] = data.elem.checked;
|
||||
|
@ -8,35 +8,29 @@
|
||||
var demo1 = xmSelect.render({
|
||||
el: '#demo1',
|
||||
autoRow: true,
|
||||
filterable: true,
|
||||
cascader: {
|
||||
show: true,
|
||||
indent: 100,
|
||||
height: '300px',
|
||||
tree: {
|
||||
show: false,
|
||||
simple: true,
|
||||
expandedKeys: [-1],
|
||||
},
|
||||
height: '100px',
|
||||
toolbar: {
|
||||
show: true,
|
||||
list: ['ALL', 'REVERSE', 'CLEAR']
|
||||
},
|
||||
filterable: true,
|
||||
data(){
|
||||
return [
|
||||
{name: '销售员', value: -1, disabled: true, children: [
|
||||
paging: true,
|
||||
pageRemote: true,
|
||||
remoteSearch: true,
|
||||
remoteMethod(val, cb, show, pageIndex){
|
||||
cb([
|
||||
{name: '张三11111111111', value: 1, selected: true, children: []},
|
||||
{name: '李四1', value: 2, selected: true},
|
||||
{name: '王五1', value: 3, disabled: true},
|
||||
]},
|
||||
{name: '奖品', value: -2, children: [
|
||||
{name: '奖品3333333333', value: -3, children: [
|
||||
{name: '苹果3', value: 14, selected: true},
|
||||
{name: '香蕉3', value: 15},
|
||||
{name: '葡萄3', value: 16},
|
||||
]},
|
||||
{name: '苹果2', value: 4, selected: true, disabled: true},
|
||||
{name: '香蕉2', value: 5},
|
||||
{name: '葡萄2', value: 6},
|
||||
]},
|
||||
]
|
||||
{name: '王五1', value: 3, disabled: false},
|
||||
])
|
||||
},
|
||||
data(){
|
||||
return []
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -174,6 +174,7 @@ list: [ "ALL", "CLEAR",
|
||||
| indent | 间距 | int | - | 20 |
|
||||
| expandedKeys | 默认展开的节点数组, 为true时展开所有节点 | array / boolean | - | [ ] |
|
||||
| strict | 是否遵循严格父子结构 | boolean | true / false | true |
|
||||
| simple | 是否开启极简模式 | boolean | true / false | false |
|
||||
|
||||
|
||||
### cascader
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "xm-select",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.9",
|
||||
"description": "始于Layui的select多选解决方案",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
@ -164,3 +164,30 @@ export function exchangeOptionsData(arr, { prop }){
|
||||
}
|
||||
return newArr;
|
||||
}
|
||||
|
||||
export function toSimple(data, sels, list, prop){
|
||||
if(!data || !isArray(data)){
|
||||
return;
|
||||
}
|
||||
|
||||
let { children, selected, value } = prop;
|
||||
data.forEach(item => {
|
||||
if(item.__node[selected] || sels.find(i => i[value] === item[value])){
|
||||
list.push(item);
|
||||
}else{
|
||||
toSimple(item[children], sels, list, prop);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function delProp(data, children, props){
|
||||
if(!data || !isArray(data)){
|
||||
return;
|
||||
}
|
||||
return data.map(item => {
|
||||
item = { ...item };
|
||||
props.forEach(prop => delete item[prop]);
|
||||
item[children] = delProp(item[children], children, props);
|
||||
return item;
|
||||
})
|
||||
}
|
||||
|
@ -283,7 +283,6 @@ class Framework extends Component{
|
||||
if(type === 'data'){
|
||||
let changeData = data.filter(item => item[this.props.prop.selected] === true);
|
||||
this.resetSelectValue(mergeArr(changeData, this.state.sels, this.props.prop), changeData, true);
|
||||
|
||||
let dataObj = {}, flatData = [];
|
||||
this.load(data, dataObj, flatData);
|
||||
this.setState({ data, flatData });
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { h, Component, render } from 'preact'
|
||||
import { isFunction } from '@/common/util'
|
||||
import { isFunction, toSimple } from '@/common/util'
|
||||
|
||||
/**
|
||||
* 标签的渲染
|
||||
@ -43,7 +43,7 @@ class Label extends Component{
|
||||
}
|
||||
|
||||
render(config) {
|
||||
const { data, prop, theme, model, sels, autoRow } = config;
|
||||
const { data, prop, theme, model, sels, autoRow, tree } = config;
|
||||
const { name, disabled } = prop;
|
||||
|
||||
//获取配置项
|
||||
@ -51,17 +51,24 @@ class Label extends Component{
|
||||
const type = label.type;
|
||||
const conf = label[type];
|
||||
|
||||
let list = sels;
|
||||
//树结构开启极简显示
|
||||
if(tree.show && tree.strict && tree.simple){
|
||||
list = []
|
||||
toSimple(data, sels, list, prop);
|
||||
}
|
||||
|
||||
//渲染结果
|
||||
let html = '', innerHTML = true;
|
||||
//悬浮显示已选择
|
||||
let title = sels.map(item => item[name]).join(',')
|
||||
let title = list.map(item => item[name]).join(',')
|
||||
|
||||
if(type === 'text'){
|
||||
html = sels.map(sel => `${conf.left}${sel[name]}${conf.right}`).join(conf.separator)
|
||||
html = list.map(sel => `${conf.left}${sel[name]}${conf.right}`).join(conf.separator)
|
||||
}else if(type === 'block'){
|
||||
innerHTML = false;
|
||||
//已选择的数据
|
||||
let arr = [...sels];
|
||||
let arr = [...list];
|
||||
|
||||
const style = { backgroundColor: theme.color }
|
||||
//显示的个数
|
||||
@ -91,10 +98,10 @@ class Label extends Component{
|
||||
)
|
||||
}
|
||||
}else{
|
||||
if(sels.length && conf && conf.template){
|
||||
html = conf.template(data, sels);
|
||||
if(list.length && conf && conf.template){
|
||||
html = conf.template(data, list);
|
||||
}else{
|
||||
html = sels.map(sel => sel[name]).join(',')
|
||||
html = list.map(sel => sel[name]).join(',')
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,13 +125,15 @@ class General extends Component{
|
||||
this.setState({ loading: true, remote: false });
|
||||
//让输入框失去焦点
|
||||
this.blur();
|
||||
this.props.remoteMethod(this.state.filterValue, (result, totalSize) => {
|
||||
this.props.remoteMethod(this.state.filterValue, (result, totalSize = 1) => {
|
||||
//这里同步修改为异步
|
||||
setTimeout(() => {
|
||||
//回调后可以重新聚焦
|
||||
this.focus();
|
||||
|
||||
this.callback = true;
|
||||
this.setState({ loading: false, totalSize });
|
||||
this.props.onReset(result, 'data');
|
||||
}, 10);
|
||||
}, this.props.show, pageIndex);
|
||||
}
|
||||
}
|
||||
@ -215,17 +217,19 @@ class General extends Component{
|
||||
}
|
||||
|
||||
render(config) {
|
||||
let { data, flatData, prop, template, theme, radio, sels, empty, filterable, filterMethod, remoteSearch, remoteMethod, delay, searchTips, create, pageRemote } = config
|
||||
let { data, flatData, prop, template, theme, radio, sels, empty, filterable, filterMethod, remoteSearch, remoteMethod, delay, searchTips, create, pageRemote, max } = config
|
||||
|
||||
const { name, value, disabled, children, optgroup } = prop;
|
||||
|
||||
let arr = deepMerge([], flatData), creator;
|
||||
|
||||
//是否开启了搜索
|
||||
if(filterable){
|
||||
if(remoteSearch){//是否进行远程搜索
|
||||
//远程分页 或者 远程搜索
|
||||
if(pageRemote || filterable && remoteSearch){
|
||||
this.postData();
|
||||
}else{
|
||||
}
|
||||
|
||||
//本地搜索
|
||||
if(filterable && !remoteSearch){
|
||||
const filterData = (item, index) => {
|
||||
const isGroup = item[optgroup];
|
||||
if(isGroup){
|
||||
@ -250,12 +254,6 @@ class General extends Component{
|
||||
//创建条目
|
||||
creator = this.state.filterValue && isFunction(create);
|
||||
}
|
||||
}
|
||||
|
||||
//远程分页
|
||||
if(pageRemote){
|
||||
this.postData();
|
||||
}
|
||||
|
||||
const search = (
|
||||
<div class={ filterable ? 'xm-search' : 'xm-search dis' }>
|
||||
@ -355,7 +353,19 @@ class General extends Component{
|
||||
info = { icon: 'xm-iconfont xm-icon-quanxuan', name, method: (pageData) => {
|
||||
const { optgroup, disabled } = prop;
|
||||
const list = pageData.filter(item => !item[optgroup]).filter(item => !item[disabled])
|
||||
this.props.onReset(radio ? list.slice(0, 1) : mergeArr(list, sels, prop), 'sels');
|
||||
|
||||
const disSels = sels.filter(item => item[prop.disabled]);
|
||||
let result = [];
|
||||
//单选的处理
|
||||
if(radio){
|
||||
result = disSels.length ? disSels : list.slice(0, 1)
|
||||
}else if(max > 0){
|
||||
result = disSels.length >= max ? disSels : mergeArr(list.slice(0, max - disSels.length), disSels, prop)
|
||||
}else{
|
||||
result = mergeArr(list, sels, prop)
|
||||
}
|
||||
|
||||
this.props.onReset(result, 'sels');
|
||||
} };
|
||||
}else if(tool === 'CLEAR'){
|
||||
info = { icon: 'xm-iconfont xm-icon-qingkong', name, method: (pageData) => {
|
||||
@ -375,7 +385,19 @@ class General extends Component{
|
||||
list.splice(index, 1);
|
||||
}
|
||||
})
|
||||
this.props.onReset(radio ? selectedList.slice(0, 1) : mergeArr(list, selectedList, prop), 'sels');
|
||||
|
||||
const disSels = selectedList.filter(item => item[prop.disabled]);
|
||||
let result = [];
|
||||
//单选的处理
|
||||
if(radio){
|
||||
result = disSels.length ? disSels : list.slice(0, 1)
|
||||
}else if(max > 0){
|
||||
result = disSels.length >= max ? disSels : mergeArr(list.slice(0, max - disSels.length), disSels, prop)
|
||||
}else{
|
||||
result = mergeArr(list, selectedList, prop)
|
||||
}
|
||||
|
||||
this.props.onReset(result, 'sels');
|
||||
} };
|
||||
}else {
|
||||
info = tool
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { h, Component, render } from 'preact'
|
||||
import { datas, optionData, childData } from '@/index.js';
|
||||
import { warn, listenerClose, isArray, deepMerge, exchangeOptionsData } from '@/common/util'
|
||||
import { warn, listenerClose, isArray, deepMerge, exchangeOptionsData, toSimple, delProp } from '@/common/util'
|
||||
import Framework from '@/components/framework'
|
||||
import defaultOptions from '@/config/options'
|
||||
|
||||
@ -84,11 +84,17 @@ class xmOptions {
|
||||
* 获取多选选中的数据
|
||||
*/
|
||||
getValue(type){
|
||||
let arr = childData[this.options.el].state.sels.map(item => {
|
||||
item = { ...item };
|
||||
delete item.__node;
|
||||
return item;
|
||||
});
|
||||
const { tree, prop, data } = this.options;
|
||||
let sels = childData[this.options.el].state.sels;
|
||||
let list = sels;
|
||||
|
||||
//树结构开启极简显示
|
||||
if(tree.show && tree.strict && tree.simple){
|
||||
list = []
|
||||
toSimple(data, sels, list, prop);
|
||||
}
|
||||
|
||||
let arr = delProp(list, prop.children, [ '__node' ]);;
|
||||
|
||||
if(type === 'name'){
|
||||
return arr.map(item => item[this.options.prop.name]);
|
||||
|
@ -101,6 +101,8 @@ export default function (lan = 'zn') {
|
||||
lazy: false,
|
||||
//懒加载回调
|
||||
load: null,
|
||||
//是否开启极简模式
|
||||
simple: false,
|
||||
},
|
||||
//级联结构
|
||||
cascader: {
|
||||
|
Loading…
Reference in New Issue
Block a user