tree添加一级项
This commit is contained in:
parent
1689e32097
commit
b64188f9dd
|
@ -1,3 +1,29 @@
|
||||||
|
@mixin tree-input {
|
||||||
|
> i {
|
||||||
|
display: inline-block;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-left: px2rem(5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
> input {
|
||||||
|
margin-left: px2rem(15px);
|
||||||
|
padding: px2rem(5px);
|
||||||
|
width: px2rem(150px);
|
||||||
|
height: px2rem(25px);
|
||||||
|
color: $Form-input-color;
|
||||||
|
|
||||||
|
&::placeholder {
|
||||||
|
color: $Form-input-placeholderColor;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
border: $borderWidth solid $info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// todo
|
// todo
|
||||||
.#{$ns}TreeControl {
|
.#{$ns}TreeControl {
|
||||||
border: 1px solid $Form-input-borderColor;
|
border: 1px solid $Form-input-borderColor;
|
||||||
|
@ -31,30 +57,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
> li {
|
> li {
|
||||||
> i {
|
@include tree-input;
|
||||||
display: inline-block;
|
|
||||||
cursor: pointer;
|
|
||||||
margin-left: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
> input {
|
|
||||||
margin-left: 15px;
|
|
||||||
padding: px2rem(5px);
|
|
||||||
width: px2rem(150px);
|
|
||||||
height: px2rem(25px);
|
|
||||||
color: $Form-input-color;
|
|
||||||
//height: $Form-input-lineHeight * $Form-input-fontSize;
|
|
||||||
|
|
||||||
&::placeholder {
|
|
||||||
color: $Form-input-placeholderColor;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:focus {
|
|
||||||
outline: none;
|
|
||||||
border: $borderWidth solid $info;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +75,7 @@
|
||||||
> span > i {
|
> span > i {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
margin-left: 5px;
|
margin-left: px2rem(5px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,35 +85,28 @@
|
||||||
|
|
||||||
&--isEdit {
|
&--isEdit {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
> i {
|
@include tree-input;
|
||||||
display: inline-block;
|
|
||||||
cursor: pointer;
|
|
||||||
margin-left: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
> input {
|
|
||||||
margin-left: 15px;
|
|
||||||
padding: px2rem(5px);
|
|
||||||
width: px2rem(150px);
|
|
||||||
height: px2rem(25px);
|
|
||||||
color: $Form-input-color;
|
|
||||||
//height: $Form-input-lineHeight * $Form-input-fontSize;
|
|
||||||
|
|
||||||
&::placeholder {
|
|
||||||
color: $Form-input-placeholderColor;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:focus {
|
|
||||||
outline: none;
|
|
||||||
border: $borderWidth solid $info;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&-rootItem > a > i {
|
&-rootItem {
|
||||||
margin-left: 0 !important;
|
> a > i {
|
||||||
|
margin-left: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}Tree-addTop {
|
||||||
|
height: px2rem(25px);
|
||||||
|
line-height: px2rem(25px);
|
||||||
|
cursor: pointer;
|
||||||
|
padding-left: $Tree-indent;
|
||||||
|
> p > span {
|
||||||
|
padding-left: px2rem(5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
&-input {
|
||||||
|
@include tree-input
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&-itemArrow {
|
&-itemArrow {
|
||||||
|
|
|
@ -9,7 +9,6 @@ import {eachTree, isVisible, isObject} from '../utils/helper';
|
||||||
import {Option, Options, value2array} from './Checkboxes';
|
import {Option, Options, value2array} from './Checkboxes';
|
||||||
import {ClassNamesFn, themeable} from '../theme';
|
import {ClassNamesFn, themeable} from '../theme';
|
||||||
import {highlight} from '../renderers/Form/Options';
|
import {highlight} from '../renderers/Form/Options';
|
||||||
import debounce = require('lodash/debounce');
|
|
||||||
|
|
||||||
interface TreeSelectorProps {
|
interface TreeSelectorProps {
|
||||||
classPrefix: string;
|
classPrefix: string;
|
||||||
|
@ -72,6 +71,7 @@ interface TreeSelectorState {
|
||||||
addItem: Option | null;
|
addItem: Option | null;
|
||||||
addingItem: Option | null;
|
addingItem: Option | null;
|
||||||
editingItem: Option | null;
|
editingItem: Option | null;
|
||||||
|
addTop: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TreeSelector extends React.Component<TreeSelectorProps, TreeSelectorState> {
|
export class TreeSelector extends React.Component<TreeSelectorProps, TreeSelectorState> {
|
||||||
|
@ -135,7 +135,8 @@ export class TreeSelector extends React.Component<TreeSelectorProps, TreeSelecto
|
||||||
editItem: null, // 点击编辑时的 item
|
editItem: null, // 点击编辑时的 item
|
||||||
addItem: null, // 点击添加时的 item
|
addItem: null, // 点击添加时的 item
|
||||||
addingItem: null, // 添加后的 item
|
addingItem: null, // 添加后的 item
|
||||||
editingItem: null // 编辑后的 item
|
editingItem: null, // 编辑后的 item
|
||||||
|
addTop: false // 添加一级
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,25 +331,34 @@ export class TreeSelector extends React.Component<TreeSelectorProps, TreeSelecto
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
addItem(item: Option, isFolder: boolean) {
|
addItem(item: Option | null, isFolder: boolean) {
|
||||||
const {addMode, openAddDialog, valueField} = this.props;
|
const {addMode, openAddDialog, valueField} = this.props;
|
||||||
let {hoverItem, unfolded} = this.state;
|
let {hoverItem, unfolded} = this.state;
|
||||||
if (addMode === 'dialog') {
|
if (addMode === 'dialog') {
|
||||||
openAddDialog && openAddDialog(hoverItem)
|
openAddDialog && openAddDialog(item ? hoverItem : null)
|
||||||
} else if (addMode === 'normal') {
|
} else if (addMode === 'normal') {
|
||||||
// 添加时,默认折叠的文件夹需要展开
|
// item 为 null 时为添加一级
|
||||||
if (isFolder && !unfolded[item[valueField as string]]) {
|
if (item) {
|
||||||
unfolded = {
|
// 添加时,默认折叠的文件夹需要展开
|
||||||
...unfolded,
|
if (isFolder && !unfolded[item[valueField as string]]) {
|
||||||
[item[valueField as string]]: !unfolded[item[valueField as string]],
|
unfolded = {
|
||||||
|
...unfolded,
|
||||||
|
[item[valueField as string]]: !unfolded[item[valueField as string]],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
addItem: item,
|
addItem: item,
|
||||||
editItem: null,
|
editItem: null,
|
||||||
unfolded
|
unfolded
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
this.setState({
|
||||||
|
addTop: true,
|
||||||
|
editItem: null,
|
||||||
|
addItem: null
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,13 +397,15 @@ export class TreeSelector extends React.Component<TreeSelectorProps, TreeSelecto
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
addingItem: null,
|
addingItem: null,
|
||||||
addItem: null
|
addItem: null,
|
||||||
|
addTop: false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
cancelAddItem() {
|
cancelAddItem() {
|
||||||
this.setState({
|
this.setState({
|
||||||
addItem: null
|
addItem: null,
|
||||||
|
addTop: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -461,6 +473,14 @@ export class TreeSelector extends React.Component<TreeSelectorProps, TreeSelecto
|
||||||
editMode,
|
editMode,
|
||||||
deletable
|
deletable
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
const {
|
||||||
|
addItem,
|
||||||
|
editItem,
|
||||||
|
hoverItem,
|
||||||
|
unfolded,
|
||||||
|
addTop,
|
||||||
|
value: stateValue
|
||||||
|
} = this.state;
|
||||||
|
|
||||||
let childrenChecked = 0;
|
let childrenChecked = 0;
|
||||||
let ret = list.map((item, key) => {
|
let ret = list.map((item, key) => {
|
||||||
|
@ -497,8 +517,8 @@ export class TreeSelector extends React.Component<TreeSelectorProps, TreeSelecto
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!nodeDisabled &&
|
!nodeDisabled &&
|
||||||
((maxLength && !selfChecked && this.state.value.length >= maxLength) ||
|
((maxLength && !selfChecked && stateValue.length >= maxLength) ||
|
||||||
(minLength && selfChecked && this.state.value.length <= minLength))
|
(minLength && selfChecked && stateValue.length <= minLength))
|
||||||
) {
|
) {
|
||||||
nodeDisabled = true;
|
nodeDisabled = true;
|
||||||
}
|
}
|
||||||
|
@ -543,13 +563,13 @@ export class TreeSelector extends React.Component<TreeSelectorProps, TreeSelecto
|
||||||
!nodeDisabled && this.handleLeave()
|
!nodeDisabled && this.handleLeave()
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{!this.state.editItem || isObject(this.state.editItem) && (this.state.editItem as Option)[valueField] !== item[valueField] ? (
|
{!editItem || isObject(editItem) && (editItem as Option)[valueField] !== item[valueField] ? (
|
||||||
<a>
|
<a>
|
||||||
{!isLeaf ? (
|
{!isLeaf ? (
|
||||||
<i
|
<i
|
||||||
onClick={() => this.toggleUnfolded(item)}
|
onClick={() => this.toggleUnfolded(item)}
|
||||||
className={cx('Tree-itemArrow', {
|
className={cx('Tree-itemArrow', {
|
||||||
'is-folded': !this.state.unfolded[item[valueField]],
|
'is-folded': !unfolded[item[valueField]],
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
|
@ -579,10 +599,11 @@ export class TreeSelector extends React.Component<TreeSelectorProps, TreeSelecto
|
||||||
{highlightTxt ? highlight(item[nameField], highlightTxt) : item[nameField]}
|
{highlightTxt ? highlight(item[nameField], highlightTxt) : item[nameField]}
|
||||||
</span>
|
</span>
|
||||||
{/* 非添加时 && 非编辑时 && 鼠标覆盖时是当前item时,显示添加/编辑/删除图标 */}
|
{/* 非添加时 && 非编辑时 && 鼠标覆盖时是当前item时,显示添加/编辑/删除图标 */}
|
||||||
{!this.state.addItem
|
{!addTop
|
||||||
&& !this.state.editItem
|
&& !addItem
|
||||||
&& isObject(this.state.hoverItem)
|
&& !editItem
|
||||||
&& (this.state.hoverItem as Option)[valueField as string] === item[valueField] ? (
|
&& isObject(hoverItem)
|
||||||
|
&& (hoverItem as Option)[valueField as string] === item[valueField] ? (
|
||||||
<span>
|
<span>
|
||||||
{addMode ? <i className="fa fa-plus" onClick={() => this.addItem(item, !isLeaf)}></i> : null}
|
{addMode ? <i className="fa fa-plus" onClick={() => this.addItem(item, !isLeaf)}></i> : null}
|
||||||
{deletable ? <i className="fa fa-minus" onClick={() => this.deleteItem(item)}></i> : null}
|
{deletable ? <i className="fa fa-minus" onClick={() => this.deleteItem(item)}></i> : null}
|
||||||
|
@ -592,19 +613,19 @@ export class TreeSelector extends React.Component<TreeSelectorProps, TreeSelecto
|
||||||
</a>
|
</a>
|
||||||
) : (
|
) : (
|
||||||
<div className={cx('Tree-item--isEdit')}>
|
<div className={cx('Tree-item--isEdit')}>
|
||||||
<input placeholder='label' defaultValue={item['label']} onChange={(e) => this.onChangeEditItem(item, e.currentTarget.value)}/>
|
<input defaultValue={item['label']} onChange={(e) => this.onChangeEditItem(item, e.currentTarget.value)}/>
|
||||||
<i className="fa fa-check" onClick={this.confirmEditItem}></i>
|
<i className="fa fa-check" onClick={this.confirmEditItem}></i>
|
||||||
<i className="fa fa-close" onClick={this.cancelEditItem}></i>
|
<i className="fa fa-close" onClick={this.cancelEditItem}></i>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{/* 有children而且为展开状态 或者 添加child时 */}
|
{/* 有children而且为展开状态 或者 添加child时 */}
|
||||||
{((childrenItems && this.state.unfolded[item[valueField]]) || this.state.addItem && (this.state.addItem[valueField] === item[valueField])) ? (
|
{((childrenItems && unfolded[item[valueField]]) || addItem && (addItem[valueField] === item[valueField])) ? (
|
||||||
<ul
|
<ul
|
||||||
className={cx('Tree-sublist')}
|
className={cx('Tree-sublist')}
|
||||||
>
|
>
|
||||||
{this.state.addItem && this.state.addItem[valueField] === item[valueField] ? (
|
{addItem && addItem[valueField] === item[valueField] ? (
|
||||||
<li>
|
<li>
|
||||||
<input placeholder='label' onChange={(e) => this.onChangeAddItem(e.currentTarget.value)}/>
|
<input onChange={(e) => this.onChangeAddItem(e.currentTarget.value)}/>
|
||||||
<i className="fa fa-check" onClick={this.confirmAddItem}></i>
|
<i className="fa fa-check" onClick={this.confirmAddItem}></i>
|
||||||
<i className="fa fa-close" onClick={this.cancelAddItem}></i>
|
<i className="fa fa-close" onClick={this.cancelAddItem}></i>
|
||||||
</li>
|
</li>
|
||||||
|
@ -623,10 +644,10 @@ export class TreeSelector extends React.Component<TreeSelectorProps, TreeSelecto
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {className, placeholder, hideRoot, rootLabel, showIcon, classnames: cx} = this.props;
|
const {className, placeholder, hideRoot, rootLabel, showIcon, classnames: cx, addMode} = this.props;
|
||||||
let data = this.props.data;
|
let data = this.props.data;
|
||||||
|
const {value, addTop} = this.state;
|
||||||
|
|
||||||
const value = this.state.value;
|
|
||||||
return (
|
return (
|
||||||
<div className={cx(`Tree ${className || ''}`)}>
|
<div className={cx(`Tree ${className || ''}`)}>
|
||||||
{data && data.length ? (
|
{data && data.length ? (
|
||||||
|
@ -648,6 +669,23 @@ export class TreeSelector extends React.Component<TreeSelectorProps, TreeSelecto
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
</a>
|
</a>
|
||||||
|
{addMode ? (
|
||||||
|
<div className={cx('Tree-addTop')}>
|
||||||
|
{!addTop ? (
|
||||||
|
<p onClick={() => this.addItem(null, false)}>
|
||||||
|
<i className="fa fa-plus"></i>
|
||||||
|
<span>添加一级</span>
|
||||||
|
</p>
|
||||||
|
) : null }
|
||||||
|
{addTop ? (
|
||||||
|
<div className={cx('Tree-addTop-input')}>
|
||||||
|
<input onChange={(e) => this.onChangeAddItem(e.currentTarget.value)}/>
|
||||||
|
<i className="fa fa-check" onClick={this.confirmAddItem}></i>
|
||||||
|
<i className="fa fa-close" onClick={this.cancelAddItem}></i>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
<ul className={cx('Tree-sublist')}>{this.renderList(data, value, false).dom}</ul>
|
<ul className={cx('Tree-sublist')}>{this.renderList(data, value, false).dom}</ul>
|
||||||
</li>
|
</li>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -130,7 +130,7 @@ export default class TreeControl extends React.Component<TreeProps, TreeState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
openAddDialog(parent: Option) {
|
openAddDialog(parent: Option | null) {
|
||||||
this.setState({
|
this.setState({
|
||||||
isAddModalOpened: true,
|
isAddModalOpened: true,
|
||||||
parent
|
parent
|
||||||
|
|
Loading…
Reference in New Issue