v1.1.1
This commit is contained in:
@@ -33,13 +33,16 @@ class Framework extends Component{
|
||||
}
|
||||
|
||||
init(props, refresh){
|
||||
let { data, prop, initValue } = props, sels;
|
||||
let { data, prop, initValue, radio } = props, sels;
|
||||
//如果新数据和旧数据不同 或者 强制刷新 才进行数据处理
|
||||
if(refresh){
|
||||
let dataObj = {};
|
||||
let flatData = [];
|
||||
this.load(data, dataObj, flatData);
|
||||
sels = initValue ? this.exchangeValue(initValue, true, dataObj) : Object.values(dataObj).filter(item => item[prop.selected] === true).filter(item => item[prop.optgroup] !== true)
|
||||
sels = this.exchangeValue(initValue ? initValue : Object.values(dataObj).filter(item => item[prop.selected] === true), dataObj)
|
||||
if(radio && sels.length > 1){
|
||||
sels = sels.slice(0, 1)
|
||||
}
|
||||
this.setState({ sels, dataObj, flatData });
|
||||
}
|
||||
|
||||
@@ -48,8 +51,12 @@ class Framework extends Component{
|
||||
return sels;
|
||||
}
|
||||
|
||||
exchangeValue(arr, filterGroup = true, dataObj = this.state.dataObj){
|
||||
exchangeValue(arr, dataObj = this.state.dataObj){
|
||||
let list = arr.map(sel => typeof sel === 'object' ? sel : dataObj[sel]).filter(a => a)
|
||||
let filterGroup = true, { tree } = this.props;
|
||||
if(tree.show && tree.strict === false){
|
||||
filterGroup = false;
|
||||
}
|
||||
filterGroup && (list = list.filter(item => item[this.props.prop.optgroup] !== true))
|
||||
return list;
|
||||
}
|
||||
@@ -60,7 +67,7 @@ class Framework extends Component{
|
||||
}
|
||||
|
||||
const { prop, tree } = this.props;
|
||||
let changeData = this.exchangeValue(sels, !tree.show);
|
||||
let changeData = this.exchangeValue(sels);
|
||||
if(tree.show && tree.strict){
|
||||
let data = this.state.data;
|
||||
this.clearAndReset(data, changeData);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { h, Component, render } from 'preact'
|
||||
import { isFunction, isArray, safety, deepMerge, mergeArr, IEVersion } from '@/common/util'
|
||||
|
||||
const emptyVal = {};
|
||||
|
||||
/**
|
||||
* 普通的多选渲染
|
||||
@@ -14,16 +16,19 @@ class General extends Component{
|
||||
remote: true,
|
||||
loading: false,
|
||||
pageIndex: 1,
|
||||
totalSize: 0,
|
||||
totalSize: 0,
|
||||
val: emptyVal,
|
||||
});
|
||||
|
||||
this.searchCid = 0;
|
||||
this.inputOver = true;
|
||||
this.__value = '';
|
||||
this.__value = '';
|
||||
this.tempData = [];
|
||||
}
|
||||
|
||||
optionClick(item, selected, disabled, e){
|
||||
this.props.ck(item, selected, disabled);
|
||||
this.props.ck(item, selected, disabled);
|
||||
this.focus();
|
||||
//阻止父组件上的事件冒泡
|
||||
this.blockClick(e);
|
||||
}
|
||||
@@ -129,12 +134,54 @@ class General extends Component{
|
||||
}
|
||||
}
|
||||
|
||||
//键盘事件
|
||||
keydown(e){
|
||||
let keyCode = e.keyCode;
|
||||
|
||||
const { value, optgroup, disabled } = this.props.prop;
|
||||
let data = this.tempData.filter(item => !item[optgroup] && !item[disabled]);
|
||||
let len = data.length - 1;
|
||||
if(len === -1){
|
||||
return ;
|
||||
}
|
||||
|
||||
let index = data.findIndex(item => item[value] === this.state.val);
|
||||
//Up 键
|
||||
if(keyCode === 38){
|
||||
if(index <= 0){
|
||||
index = len
|
||||
}else if(index > 0){
|
||||
index -= 1;
|
||||
}
|
||||
let val = data[index][value];
|
||||
this.setState({ val })
|
||||
}else
|
||||
//Down 键
|
||||
if(keyCode === 40){
|
||||
if(index === -1 || index === len){
|
||||
index = 0
|
||||
}else if(index < len){
|
||||
index += 1;
|
||||
}
|
||||
let val = data[index][value];
|
||||
this.setState({ val })
|
||||
}else
|
||||
//Enter 键
|
||||
if(keyCode === 13){
|
||||
if(this.state.val != emptyVal){
|
||||
let option = data[index];
|
||||
this.optionClick(option, this.props.sels.findIndex(item => item[value] === this.state.val) != -1, option[disabled], e)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//组件将要接收新属性
|
||||
componentWillReceiveProps(props){
|
||||
if(this.props.show != props.show){
|
||||
if(!props.show){
|
||||
//清空输入框的值
|
||||
this.setState({ filterValue: '' });
|
||||
this.setState({ filterValue: '', val: emptyVal });
|
||||
this.__value = '';
|
||||
this.searchInputRef && (this.searchInputRef.value = '');
|
||||
}else{
|
||||
@@ -149,7 +196,8 @@ class General extends Component{
|
||||
|
||||
const { name, value, disabled, children, optgroup } = prop;
|
||||
|
||||
let arr = deepMerge([], flatData), creator;
|
||||
let arr = deepMerge([], flatData), creator;
|
||||
|
||||
//是否开启了搜索
|
||||
if(filterable){
|
||||
if(remoteSearch){//是否进行远程搜索
|
||||
@@ -194,8 +242,8 @@ class General extends Component{
|
||||
);
|
||||
|
||||
//如果是分组模式, 要分页先去除分组, 然后在计算分页, 最后再加上分组
|
||||
let groups = [], groupInfo = {};
|
||||
groups = arr.filter(item => item[optgroup]).forEach(g => {
|
||||
let groupInfo = {};
|
||||
arr.filter(item => item[optgroup]).forEach(g => {
|
||||
g[children].forEach(item => groupInfo[item[value]] = g);
|
||||
});
|
||||
arr = arr.filter(item => !item[optgroup]);
|
||||
@@ -247,16 +295,20 @@ class General extends Component{
|
||||
}
|
||||
}
|
||||
|
||||
let newArr = [], group;
|
||||
let newArr = [], group, tmpGroup = { __tmp: true };
|
||||
tmpGroup[optgroup] = true;
|
||||
arr.forEach(item => {
|
||||
let g = groupInfo[item[value]];
|
||||
if(g != group){
|
||||
if(group && !g){
|
||||
g = tmpGroup
|
||||
}
|
||||
if(g != group){
|
||||
group = g;
|
||||
newArr.push(group);
|
||||
g && newArr.push(group);
|
||||
}
|
||||
newArr.push(item);
|
||||
});
|
||||
arr = newArr;
|
||||
arr = newArr;
|
||||
|
||||
//查看是否创建了条目
|
||||
if(creator){
|
||||
@@ -333,6 +385,9 @@ class General extends Component{
|
||||
if(!showIcon && selected){
|
||||
itemStyle.backgroundColor = theme.color;
|
||||
item[disabled] && (itemStyle.backgroundColor = '#C2C2C2');
|
||||
}
|
||||
if(item[value] === this.state.val){
|
||||
itemStyle.backgroundColor = '#f2f2f2'
|
||||
}
|
||||
const className = ['xm-option', (item[disabled] ? ' disabled' : ''), (selected ? ' selected' : ''), (showIcon ? 'show-icon' : 'hide-icon') ].join(' ');
|
||||
const iconClass = ['xm-option-icon xm-iconfont', radio ? 'xm-icon-danx' : 'xm-icon-duox'].join(' ');
|
||||
@@ -347,9 +402,12 @@ class General extends Component{
|
||||
|
||||
const renderGroup = item => {
|
||||
const isGroup = item[optgroup];
|
||||
if(isGroup){//分组模式
|
||||
return (
|
||||
<div class="xm-group">
|
||||
if(isGroup){//分组模式
|
||||
if(item.__tmp){
|
||||
return <div class="item--divided"></div>
|
||||
}
|
||||
return (
|
||||
<div class="xm-group">
|
||||
<div class="xm-group-item" onClick={ this.groupClick.bind(this, item) }>{ item[name] }</div>
|
||||
</div>
|
||||
)
|
||||
@@ -388,6 +446,7 @@ class General extends Component{
|
||||
input.addEventListener('compositionupdate', this.handleComposition.bind(this));
|
||||
input.addEventListener('compositionend', this.handleComposition.bind(this));
|
||||
input.addEventListener('input', this.searchInput.bind(this));
|
||||
input.addEventListener('keydown', this.keydown.bind(this));
|
||||
this.searchInputRef = input;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { h, Component, render } from 'preact'
|
||||
import { deepMerge, isFunction } from '@/common/util'
|
||||
|
||||
class Tree extends Component{
|
||||
|
||||
@@ -242,11 +243,46 @@ class Tree extends Component{
|
||||
}
|
||||
|
||||
let arr = data.map(item => renderGroup(item, 10 - tree.indent)).filter(a => a);
|
||||
let safetyArr = deepMerge([], arr);
|
||||
let safetySels = deepMerge([], sels);
|
||||
|
||||
if(!arr.length){
|
||||
//查看无数据情况下是否显示分页
|
||||
arr.push(<div class="xm-select-empty">{ empty }</div>)
|
||||
}
|
||||
//工具条操作
|
||||
const toolbar = (
|
||||
<div class='xm-toolbar'>
|
||||
{ config.toolbar.list.map(tool => {
|
||||
const toolClass = 'toolbar-tag';
|
||||
|
||||
let info, name = config.languageProp.toolbar[tool];
|
||||
if(tool === 'ALL'){
|
||||
info = { icon: 'xm-iconfont xm-icon-quanxuan', name, method: (pageData) => {
|
||||
|
||||
} };
|
||||
}else if(tool === 'CLEAR'){
|
||||
info = { icon: 'xm-iconfont xm-icon-qingkong', name, method: (pageData) => {
|
||||
|
||||
} };
|
||||
}else if(tool === 'REVERSE'){
|
||||
info = { icon: 'xm-iconfont xm-icon-fanxuan', name, method: (pageData) => {
|
||||
|
||||
} };
|
||||
}else {
|
||||
info = tool
|
||||
}
|
||||
|
||||
const hoverChange = e => {
|
||||
if(e.type === 'mouseenter') e.target.style.color = theme.color;
|
||||
if(e.type === 'mouseleave') e.target.style.color = '';
|
||||
}
|
||||
|
||||
return (<div class={ toolClass } onClick={ () => {
|
||||
isFunction(info.method) && info.method(safetyArr, safetySels)
|
||||
} } onMouseEnter={ hoverChange } onMouseLeave={ hoverChange }>
|
||||
{ config.toolbar.showIcon && <i class={ info.icon }></i> }
|
||||
<span>{ info.name }</span>
|
||||
</div>)
|
||||
}).filter(a => a) }
|
||||
</div>
|
||||
)
|
||||
|
||||
const search = (
|
||||
<div class='xm-search'>
|
||||
@@ -255,8 +291,14 @@ class Tree extends Component{
|
||||
</div>
|
||||
);
|
||||
|
||||
if(!arr.length){
|
||||
//查看无数据情况下是否显示分页
|
||||
arr.push(<div class="xm-select-empty">{ empty }</div>)
|
||||
}
|
||||
|
||||
return (
|
||||
<div onClick={ this.blockClick } class="xm-body-tree" >
|
||||
{ config.toolbar.show && toolbar }
|
||||
{ filterable && search }
|
||||
<div class="scroll-body" style={ {maxHeight: config.height} }>{ arr }</div>
|
||||
</div>
|
||||
|
||||
@@ -475,6 +475,12 @@ xm-select{
|
||||
background-color: #FFF;
|
||||
}
|
||||
|
||||
.item--divided{
|
||||
border-top: 1px solid #ebeef5;
|
||||
width: calc(100% - 20px);
|
||||
cursor: initial;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//不同尺寸下的数据调整
|
||||
@@ -519,6 +525,9 @@ xm-select{
|
||||
top: @size / 2 - 1px;
|
||||
}
|
||||
}
|
||||
.item--divided{
|
||||
margin: @size / 4;
|
||||
}
|
||||
}
|
||||
xm-select[size='large']{
|
||||
.mixin(40px)
|
||||
|
||||
Reference in New Issue
Block a user