u
This commit is contained in:
parent
e928c6a038
commit
f8fa44c94c
17
CHANGELOG.md
17
CHANGELOG.md
@ -1,5 +1,22 @@
|
||||
## 更新日志
|
||||
|
||||
### 1.2.3
|
||||
|
||||
*2021-05-28*
|
||||
|
||||
#### 新增
|
||||
|
||||
- 新增`submitConversion`配置方法, 用于拓展表单提交数据, 默认是value数组
|
||||
|
||||
#### Bug fixes
|
||||
|
||||
- 修复级联模式下第一组数据过多时不显示滚动条
|
||||
- 修复级联模式下隐藏图标背景色透明的bug
|
||||
- 修复级联模式下如果子节点是空数组也显示右箭头的bug
|
||||
- 修复级联/树模式下,如果子节点是空数组,然后操作选中状态异常
|
||||
- 修复工具条点击清空, `on`监听到的`isAdd`为`true`的bug [#I3T2KE](https://gitee.com/maplemei/xm-select/issues/I3T2KE)
|
||||
- 修复setValue时对多选上限的判断异常 [#I3SABO](https://gitee.com/maplemei/xm-select/issues/I3SABO)
|
||||
|
||||
|
||||
### 1.2.2
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
- xm-select技术群②: `938624691` (500人)
|
||||
- xm-select技术群③: `1145047250` (500人)
|
||||
|
||||
[issues 需求记录](https://gitee.com/maplemei/xm-select/issues/I1NSO7)
|
||||
[issues 需求记录](https://gitee.com/maplemei/xm-select/issues)
|
||||
|
||||
|
||||
[更新日志](CHANGELOG.md)
|
||||
|
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
8
dist/static/docs.js
vendored
8
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
@ -4,10 +4,7 @@
|
||||
<div class="container">
|
||||
<h1>
|
||||
<router-link :to="`/`">
|
||||
<!-- logo -->
|
||||
<slot>
|
||||
<!-- <img src="../assets/images/element-logo.svg" alt="element-logo" class="nav-logo"> -->
|
||||
<!-- <img src="../assets/images/element-logo-small.svg" alt="element-logo" class="nav-logo-small"> -->
|
||||
xm-select
|
||||
</slot>
|
||||
</router-link>
|
||||
@ -19,7 +16,7 @@
|
||||
<router-link active-class="active" :to="`/`">使用手册</router-link>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href='https://gitee.com/maplemei/xm-select/issues/I1NSO7' target="_blank" style="opacity: 1;">提新需求↗</a>
|
||||
<a href='https://gitee.com/maplemei/xm-select/issues' target="_blank" style="opacity: 1;">提新需求↗</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
|
@ -7,18 +7,53 @@
|
||||
<script>
|
||||
xmSelect.render({
|
||||
el: '#demo1',
|
||||
model: {
|
||||
label: {
|
||||
type: 'search'
|
||||
autoRow: true,
|
||||
cascader: {
|
||||
show: true,
|
||||
indent: 200,
|
||||
},
|
||||
height: '200px',
|
||||
max: 1,
|
||||
maxMethod(a, item){
|
||||
console.log(item)
|
||||
},
|
||||
radio: true,
|
||||
filterable: true,
|
||||
data: [
|
||||
{name: '张三', value: 1, selected: true},
|
||||
{name: '李四', value: 2},
|
||||
{name: '王五', value: 3},
|
||||
submitConversion(sels, prop){
|
||||
return sels.map(item => item[prop.name]).join(',')
|
||||
},
|
||||
data(){
|
||||
return [
|
||||
{name: '销售员', value: -1, disabled: false, children: [
|
||||
{name: '张三1', value: 1, selected: true, children: []},
|
||||
{name: '王五1', value: 13, disabled: true},
|
||||
{name: '王五1', value: 131, disabled: true},
|
||||
{name: '王五1', value: 132, disabled: true},
|
||||
{name: '王五1', value: 133, disabled: true},
|
||||
{name: '王五1', value: 134, disabled: true},
|
||||
{name: '王五1', value: 135, disabled: true},
|
||||
{name: '王五1', value: 136, disabled: true},
|
||||
{name: '王五1', value: 137, disabled: true},
|
||||
{name: '王五1', value: 138, disabled: true},
|
||||
]},
|
||||
{name: '奖品', value: -2, children: [
|
||||
{name: '奖品3', value: -3, children: [
|
||||
|
||||
]},
|
||||
{name: '苹果2', value: 4, disabled: true},
|
||||
{name: '香蕉2', value: 5},
|
||||
{name: '葡萄2', value: 6},
|
||||
]},
|
||||
{name: '李四1', value: 2},
|
||||
{name: '王五1', value: 3, disabled: true},
|
||||
{name: '王五1', value: 31, disabled: true},
|
||||
{name: '王五1', value: 32, disabled: true},
|
||||
{name: '王五1', value: 33, disabled: true},
|
||||
{name: '王五1', value: 34, disabled: true},
|
||||
{name: '王五1', value: 35, disabled: true},
|
||||
{name: '王五1', value: 36, disabled: true},
|
||||
{name: '王五1', value: 37, disabled: true},
|
||||
{name: '王五1', value: 38, disabled: true},
|
||||
]
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
|
@ -52,6 +52,7 @@
|
||||
| create | 创建条目 | function(val, data), val: 搜索的数据, data: 当前下拉数据 | - | null |
|
||||
| tree | 树形结构, 具体看下表 | object | - | - |
|
||||
| cascader | 级联结构, 具体看下表 | object | - | - |
|
||||
| submitConversion | 配置表单提交数据 | function(sels, prop), sels: 已选中数据, prop: 自定义的prop | - | - |
|
||||
|
||||
|
||||
### prop
|
||||
@ -211,7 +212,7 @@ list: [ "ALL", "CLEAR",
|
||||
| render | 渲染多选 | (options: 配置项) | 实例对象 |
|
||||
| get | 获取页面中已经渲染的多选 | (filter: 过滤`el`, single: 是否返回单实例) | 符合条件的实例数组 |
|
||||
| batch | 批量操作已渲染的多选 | (filter: 过滤`el`, method: 方法, ...方法参数) | 符合条件的实例数组 |
|
||||
| arrr2tree | 把列表数据转化为树状结构 | (arr: 数据, pid: 父节点ID的key, id: 对应key, children: 对应key, topParentId: 顶级节点的ID) | 符合条件的数组 |
|
||||
| arr2tree | 把列表数据转化为树状结构 | (arr: 数据, pid: 父节点ID的key, id: 对应key, children: 对应key, topParentId: 顶级节点的ID) | 符合条件的数组 |
|
||||
|
||||
```
|
||||
//render 使用方式
|
||||
|
@ -120,7 +120,7 @@ class Framework extends Component{
|
||||
return cgList;
|
||||
}
|
||||
|
||||
value(sels, show, listenOn, jsChangeData){
|
||||
value(sels, show, listenOn, jsChangeData, isAdd = true){
|
||||
if(show !== false && show !== true){
|
||||
show = this.state.show;
|
||||
}
|
||||
@ -129,7 +129,7 @@ class Framework extends Component{
|
||||
let changeData = this.exchangeValue(sels);
|
||||
|
||||
//检测是否超选了
|
||||
if(this.checkMax(changeData, changeData)){
|
||||
if(this.checkMax(changeData, changeData, true)){
|
||||
return ;
|
||||
}
|
||||
|
||||
@ -138,7 +138,7 @@ class Framework extends Component{
|
||||
this.clearAndReset(data, changeData, false);
|
||||
changeData = this.init({ data, prop }, true);
|
||||
}
|
||||
this.resetSelectValue(changeData, jsChangeData ? jsChangeData : changeData, true, listenOn);
|
||||
this.resetSelectValue(changeData, jsChangeData ? jsChangeData : changeData, isAdd, listenOn);
|
||||
this.setState({ show })
|
||||
}
|
||||
|
||||
@ -147,7 +147,7 @@ class Framework extends Component{
|
||||
data.forEach(item => {
|
||||
item[selected] = changeData.findIndex(c => c[value] === item[value]) != -1 || parentCK;
|
||||
let child = item[children];
|
||||
if(child && isArray(child)){
|
||||
if(child && isArray(child) && child.length > 0){
|
||||
this.clearAndReset(child, changeData, item[selected])
|
||||
let len = child.length;
|
||||
let slen = child.filter(i => i[selected] === true || i.__node.selected === true).length;
|
||||
@ -250,11 +250,12 @@ class Framework extends Component{
|
||||
}
|
||||
}
|
||||
|
||||
checkMax(item, sels){
|
||||
checkMax(item, sels, contains){
|
||||
const { max, maxMethod, theme } = this.props
|
||||
//查看是否设置了多选上限
|
||||
let maxCount = toNum(max);
|
||||
if(maxCount > 0 && sels.length >= maxCount){
|
||||
let flag = (contains ? sels.length : (isArray(item) ? item.length : 1) + sels.length) > maxCount;
|
||||
if(maxCount > 0 && flag){
|
||||
this.updateBorderColor(theme.maxColor);
|
||||
//查看是否需要回调
|
||||
maxMethod && isFunction(maxMethod) && maxMethod(sels, item);
|
||||
@ -265,14 +266,14 @@ class Framework extends Component{
|
||||
//选项, 选中状态, 禁用状态, 是否强制删除:在label上点击删除
|
||||
itemClick(item, itemSelected, itemDisabled, mandatoryDelete){
|
||||
|
||||
const { theme, prop, radio, repeat, clickClose, max, maxMethod, tree, data } = this.props
|
||||
const { theme, prop, radio, repeat, clickClose, max, maxMethod, tree, cascader, data } = this.props
|
||||
let sels = [ ...this.state.sels ]
|
||||
const { value, selected, disabled, children, optgroup } = prop
|
||||
|
||||
//如果是禁用状态, 不能进行操作
|
||||
if(itemDisabled) return;
|
||||
|
||||
if(item[optgroup] && tree.strict){
|
||||
if(item[optgroup] && (tree.strict || cascader.strict)){
|
||||
let child = item[children], change = [], isAdd = true, handlerType;
|
||||
if(item.__node.selected){
|
||||
handlerType = 'del';
|
||||
@ -293,7 +294,7 @@ class Framework extends Component{
|
||||
this.treeHandler(sels, item, change, handlerType);
|
||||
}
|
||||
|
||||
if(this.checkMax(change, change)){
|
||||
if(this.checkMax(change, sels)){//TODO 这里还是有问题, 如果是取消的
|
||||
return ;
|
||||
}
|
||||
sels = [ ...this.state.sels ], change = [];
|
||||
@ -401,7 +402,7 @@ class Framework extends Component{
|
||||
}else
|
||||
//树状结构数据更新
|
||||
if(type === 'treeData'){
|
||||
this.value(data, null, true)
|
||||
this.value(data, null, true, false, false)
|
||||
}else
|
||||
//树状结构数据更新
|
||||
if(type === 'close'){
|
||||
@ -436,7 +437,7 @@ class Framework extends Component{
|
||||
sels.splice(index, 1);
|
||||
}
|
||||
});
|
||||
this.value(sels, this.props.show, true, changeData)
|
||||
this.value(sels, this.props.show, true, changeData, false)
|
||||
}
|
||||
|
||||
auto(arr){
|
||||
@ -478,7 +479,7 @@ class Framework extends Component{
|
||||
}
|
||||
|
||||
render(config, state) {
|
||||
const { theme, prop, radio, repeat, clickClose, on, max, maxMethod, content, disabled, tree } = config;
|
||||
const { theme, prop, radio, repeat, clickClose, on, max, maxMethod, content, disabled, tree, submitConversion } = config;
|
||||
const borderStyle = { borderColor: theme.color };
|
||||
let { data, dataObj, flatData, sels, show, tmpColor, bodyClass } = state;
|
||||
|
||||
@ -519,7 +520,7 @@ class Framework extends Component{
|
||||
lay-verType={ config.layVerType }
|
||||
lay-reqText={ config.layReqText }
|
||||
name={ config.name }
|
||||
value={ sels.map(item => item[prop.value]).join(',') }
|
||||
value={ submitConversion(sels, prop) }
|
||||
></input>
|
||||
<i class={ show ? 'xm-icon xm-icon-expand' : 'xm-icon' } />
|
||||
{ sels.length === 0 && <div class="xm-tips">{ config.tips }</div> }
|
||||
|
@ -37,6 +37,65 @@ class Label extends Component{
|
||||
input && input.blur();
|
||||
}
|
||||
|
||||
labelDrag(item, e){
|
||||
let type = e.type;
|
||||
let node = e.target;
|
||||
while(true){
|
||||
if(!node || node.tagName === 'I'){
|
||||
return ;
|
||||
}
|
||||
if(node.tagName === 'DIV' && node.style.position !== 'fixed'){
|
||||
break;
|
||||
}
|
||||
node = node.parentNode;
|
||||
}
|
||||
|
||||
console.log(e)
|
||||
|
||||
if(type === 'mousedown'){
|
||||
let dragNode = node.cloneNode(true);
|
||||
let { pageX, pageY, offsetX, offsetY } = e;//鼠标当前位置
|
||||
|
||||
console.log(pageX, pageY, offsetX, offsetY)
|
||||
|
||||
dragNode.style.position = 'fixed';
|
||||
dragNode.style.left = (pageX - offsetX) + 'px';
|
||||
dragNode.style.top = (pageY - offsetY) + 'px';
|
||||
node.appendChild(dragNode);
|
||||
|
||||
console.log(dragNode)
|
||||
|
||||
|
||||
dragNode.onmousemove = (ev) => {
|
||||
dragNode.style.left = (ev.pageX - offsetX) + 'px';
|
||||
dragNode.style.top = (ev.pageY - offsetY) + 'px';
|
||||
}
|
||||
|
||||
dragNode.mouseup = () => {
|
||||
dragNode.parentNode.removeChild(dragNode);
|
||||
dragNode.onmousemove = null;
|
||||
dragNode.mouseup = null;
|
||||
dragNode.mouseleave = null;
|
||||
}
|
||||
dragNode.mouseleave = () => {
|
||||
console.log('mouseleave')
|
||||
}
|
||||
}else if(type === 'mouseup'){
|
||||
let childs = node.childNodes;
|
||||
for(let i = 0; i < childs.length; i++) {
|
||||
let f = childs[i];
|
||||
if(f.tagName === 'DIV'){
|
||||
node.removeChild(f);
|
||||
f.onmousemove = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
componentDidMount(){
|
||||
if (this.labelRef.addEventListener) {
|
||||
this.labelRef.addEventListener('DOMMouseScroll', this.scrollFunc.bind(this), false);
|
||||
@ -82,8 +141,12 @@ class Label extends Component{
|
||||
html = arr.splice(0, count).map(sel => {
|
||||
const styleProps = { width: conf.showIcon ? 'calc(100% - 20px)' : '100%', }
|
||||
const className = ['xm-label-block', sel[disabled] ? 'disabled':''].join(' ');
|
||||
// onMouseDown = { this.labelDrag.bind(this, sel) }
|
||||
// onMouseUp = { this.labelDrag.bind(this, sel) }
|
||||
return (
|
||||
<div class={className} style={ style }>
|
||||
<div class={className} style={ style }
|
||||
|
||||
>
|
||||
{ conf.template && isFunction(conf.template) ? (
|
||||
<span style={ styleProps } dangerouslySetInnerHTML={{ __html: conf.template(sel, arr) }}></span>
|
||||
) : (
|
||||
|
@ -18,7 +18,7 @@ class Cascader extends Component{
|
||||
|
||||
optionClick(item, selected, disabled, type, index, e){
|
||||
if(type === 'line'){
|
||||
if(disabled){
|
||||
if(!item.optgroup && disabled){
|
||||
return ;
|
||||
}
|
||||
//加载中的不需要进行处理
|
||||
@ -57,7 +57,7 @@ class Cascader extends Component{
|
||||
render(config, state) {
|
||||
|
||||
const { prop, empty, sels, theme, radio, template, data, cascader } = config;
|
||||
let { name, value, disabled, children } = prop;
|
||||
let { name, value, disabled, children, optgroup } = prop;
|
||||
const showIcon = config.model.icon != 'hidden';
|
||||
|
||||
const renderItem = (item, indent, index, checked) => {
|
||||
@ -108,6 +108,12 @@ class Cascader extends Component{
|
||||
itemStyle.backgroundColor = theme.hover
|
||||
}
|
||||
|
||||
//隐藏图标的处理
|
||||
if(!showIcon && selected){
|
||||
itemStyle.backgroundColor = theme.color;
|
||||
dis && (itemStyle.backgroundColor = '#C2C2C2');
|
||||
}
|
||||
|
||||
const contentStyle = {}, checkedStyle = {};
|
||||
if(checked){
|
||||
contentStyle.color = theme.color
|
||||
@ -133,7 +139,7 @@ class Cascader extends Component{
|
||||
} onMouseEnter={ hoverChange } onMouseLeave={ hoverChange }>
|
||||
{ showIcon && <i class={ iconClass } style={ iconStyle } onClick={ this.optionClick.bind(this, item, selected, dis, 'checkbox', index) }></i> }
|
||||
<div class='xm-option-content' style={ contentStyle } dangerouslySetInnerHTML={{ __html: template({ data, item, arr: sels, name: item[name], value: item[value] }) }}></div>
|
||||
{ item[children] && <div class={ checkedClass } style={ checkedStyle }></div> }
|
||||
{ item[optgroup] && <div class={ checkedClass } style={ checkedStyle }></div> }
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@ -146,7 +152,7 @@ class Cascader extends Component{
|
||||
const checked = child && this.state.expand[index] === item[value];
|
||||
checked && boxArr.push(
|
||||
<div class="xm-cascader-box" index={ index % 4 } style={{ left: indent + 'px', width: cascader.indent + 'px'}}>
|
||||
<div class="xm-cascader-scroll">{ child.map(c => renderGroup(c, indent, index + 1)) }</div>
|
||||
<div class="xm-cascader-scroll scroll-body">{ child.map(c => renderGroup(c, indent, index + 1)) }</div>
|
||||
</div>
|
||||
)
|
||||
return renderItem(item, indent, index, checked)
|
||||
@ -161,7 +167,7 @@ class Cascader extends Component{
|
||||
}
|
||||
|
||||
return (
|
||||
<div onClick={ this.blockClick } class="xm-body-cascader" style={{ width: cascader.indent + 'px', maxHeight: config.height }}>
|
||||
<div onClick={ this.blockClick } class="xm-body-cascader scroll-body" style={{ width: cascader.indent + 'px', maxHeight: config.height }}>
|
||||
{ arr }
|
||||
</div>
|
||||
)
|
||||
|
@ -184,6 +184,9 @@ export default function (lan = 'zn') {
|
||||
//监听选中事件
|
||||
on({ arr, item, selected }){
|
||||
|
||||
},
|
||||
submitConversion(sels, prop){
|
||||
return sels.map(item => item[prop.value]).join(',')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -488,6 +488,9 @@ xm-select{
|
||||
.disabled .xm-right-arrow{
|
||||
color: #C2C2C2 !important;
|
||||
}
|
||||
.hide-icon.disabled .xm-right-arrow{
|
||||
color: #999 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user