This commit is contained in:
maplemei
2019-11-26 12:20:02 +08:00
parent 3fcd41969c
commit c604a398ff
14 changed files with 239 additions and 113 deletions

View File

@@ -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);

View File

@@ -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;
}
}

View File

@@ -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>

View File

@@ -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)