v1.0.8
This commit is contained in:
@@ -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',
|
||||
children: 'children',
|
||||
optgroup: 'optgroup',
|
||||
click: 'click',
|
||||
},
|
||||
//主题配置
|
||||
theme: {
|
||||
|
||||
@@ -94,7 +94,7 @@ class xmOptions {
|
||||
*/
|
||||
getValue(type){
|
||||
let arr = safety(childs[this.options.el].state.sels);
|
||||
|
||||
|
||||
if(type === 'name'){
|
||||
return arr.map(item => item[this.options.prop.name]);
|
||||
}else
|
||||
@@ -107,7 +107,7 @@ class xmOptions {
|
||||
if(type === 'valueStr'){
|
||||
return arr.map(item => item[this.options.prop.value]).join(',');
|
||||
}
|
||||
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
@@ -119,10 +119,33 @@ class xmOptions {
|
||||
warn('请传入数组结构...')
|
||||
return ;
|
||||
}
|
||||
childs[this.options.el].value(sels, !!show);
|
||||
childs[this.options.el].value(sels, show);
|
||||
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.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){
|
||||
@@ -33,22 +33,58 @@ class Framework extends Component{
|
||||
return list;
|
||||
}
|
||||
|
||||
resetSelectValue(sels = [], change = [], isAdd){
|
||||
let on = this.props.on;
|
||||
if(isFunction(on)){
|
||||
on({ arr: sels, change, isAdd });
|
||||
}
|
||||
this.setState({ sels });
|
||||
}
|
||||
|
||||
resetDate(data = []){
|
||||
this.setState({ data });
|
||||
}
|
||||
|
||||
value(sels, show){
|
||||
let data = this.state.data;
|
||||
let value = this.props.prop.value;
|
||||
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 value = this.props.prop.value;
|
||||
let list = [];
|
||||
filterGroupOption(list, data, this.props.prop);
|
||||
this.setState({
|
||||
sels: sels.map(sel => typeof sel === 'object' ? sel[value] : sel).map(val => list.find(item => item[value] == val)).filter(a => a),
|
||||
//下拉框是否展开
|
||||
show,
|
||||
})
|
||||
}
|
||||
return sels.map(sel => typeof sel === 'object' ? sel[value] : sel).map(val => list.find(item => item[value] == val)).filter(a => a);
|
||||
}
|
||||
|
||||
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){
|
||||
this.setState({ tmpColor });
|
||||
@@ -57,11 +93,25 @@ class Framework extends Component{
|
||||
onReset(data, type){
|
||||
//重置数据
|
||||
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
|
||||
//重置选中数据
|
||||
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])
|
||||
if(index != -1){
|
||||
sels.splice(index, 1);
|
||||
this.setState({ sels });
|
||||
this.resetSelectValue(sels, [item], !selected);
|
||||
}
|
||||
}else{
|
||||
//查看是否设置了多选上限
|
||||
@@ -173,14 +223,12 @@ class Framework extends Component{
|
||||
|
||||
//如果是单选模式
|
||||
if(radio){
|
||||
this.setState({ sels: [item] });
|
||||
this.resetSelectValue([item], [item], !selected);
|
||||
}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();
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
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);
|
||||
}
|
||||
|
||||
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){
|
||||
e.stopPropagation();
|
||||
}
|
||||
@@ -69,6 +84,7 @@ class General extends Component{
|
||||
this.searchCid = setTimeout(() => this.setState({
|
||||
filterValue: this.__value,
|
||||
remote: true,
|
||||
callback: true,
|
||||
}), 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) {
|
||||
|
||||
let { data, prop, template, theme, radio, sels, empty, filterable, filterMethod, remoteSearch, remoteMethod, delay, searchTips } = config
|
||||
|
||||
const { name, value, disabled, children, optgroup } = prop;
|
||||
|
||||
let arr = safety(data);
|
||||
let arr = deepMerge([], data);
|
||||
//是否开启了搜索
|
||||
if(filterable){
|
||||
if(remoteSearch){//是否进行远程搜索
|
||||
@@ -232,7 +259,8 @@ class General extends Component{
|
||||
}
|
||||
}
|
||||
|
||||
let safetyArr = safety(arr);
|
||||
let safetyArr = deepMerge([], arr);
|
||||
|
||||
//工具条操作
|
||||
const toolbar = (
|
||||
<div class='xm-toolbar'>
|
||||
@@ -294,28 +322,28 @@ class General extends Component{
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const renderGroup = item => {
|
||||
const isGroup = item[optgroup];
|
||||
if(isGroup){//分组模式
|
||||
return (
|
||||
<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>
|
||||
)
|
||||
}
|
||||
|
||||
const child = item[children];
|
||||
if(isArray(child) && child.length > 0){//分组模式
|
||||
return (
|
||||
<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) }
|
||||
</div>
|
||||
)
|
||||
}
|
||||
return renderItem(item);
|
||||
}
|
||||
arr = arr.map(renderGroup);
|
||||
arr = addGroupLabel(arr, prop).map(renderGroup);
|
||||
|
||||
if(!arr.length){
|
||||
arr.push(
|
||||
|
||||
@@ -68,7 +68,7 @@ xm-select{
|
||||
& > .xm-tips{
|
||||
color: #999999;
|
||||
padding: 0 10px;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
& > .xm-icon{
|
||||
@@ -116,16 +116,9 @@ xm-select{
|
||||
|
||||
.scroll{
|
||||
.label-content{
|
||||
line-height: @heightLabel;
|
||||
height: calc(100% - 20px);
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
white-space: pre;
|
||||
line-height: @heightLabel;
|
||||
padding: 3px 30px 3px 10px;
|
||||
&:after{
|
||||
content: '-';
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user