Tree: checkbox can be disabled

This commit is contained in:
Dreamacro
2017-07-19 18:36:26 +08:00
committed by 杨奕
parent 6f724ea6a3
commit 476f76875c
7 changed files with 327 additions and 75 deletions

View File

@@ -1,28 +1,45 @@
import objectAssign from 'element-ui/src/utils/merge';
import { markNodeData, NODE_KEY } from './util';
const reInitChecked = function(node) {
const siblings = node.childNodes;
export const getChildState = node => {
let all = true;
let none = true;
let allWithoutDisable = true;
for (let i = 0, j = siblings.length; i < j; i++) {
const sibling = siblings[i];
if (sibling.checked !== true || sibling.indeterminate) {
for (let n of node) {
if (n.checked !== true || n.indeterminate) {
all = false;
if (!n.disabled) {
allWithoutDisable = false;
}
}
if (sibling.checked !== false || sibling.indeterminate) {
if (n.checked !== false || n.indeterminate) {
none = false;
}
}
return { all, none, allWithoutDisable, half: !all && !none };
};
const reInitChecked = function(node) {
const {all, none, half} = getChildState(node.childNodes);
if (all) {
node.setChecked(true);
} else if (!all && !none) {
node.setChecked('half');
node.checked = true;
node.indeterminate = false;
} else if (half) {
node.checked = false;
node.indeterminate = true;
} else if (none) {
node.setChecked(false);
node.checked = false;
node.indeterminate = false;
}
const parent = node.parent;
if (!parent || parent.level === 0) return;
if (!node.store.checkStrictly) {
reInitChecked(parent);
}
};
@@ -145,6 +162,10 @@ export default class Node {
return null;
}
get disabled() {
return getPropertyFromData(this, 'disabled');
}
insertChild(child, index) {
if (!child) throw new Error('insertChild error: child is required.');
@@ -260,16 +281,30 @@ export default class Node {
this.isLeaf = false;
}
setChecked(value, deep) {
setChecked(value, deep, recursion, passValue) {
this.indeterminate = value === 'half';
this.checked = value === true;
let { allWithoutDisable } = getChildState(this.childNodes);
if (this.childNodes.length && allWithoutDisable) {
this.checked = false;
value = false;
}
const handleDescendants = () => {
if (deep) {
const childNodes = this.childNodes;
for (let i = 0, j = childNodes.length; i < j; i++) {
const child = childNodes[i];
child.setChecked(value !== false, deep);
passValue = passValue || value !== false;
const isCheck = child.disabled ? child.checked : passValue;
child.setChecked(isCheck, deep, true, passValue);
}
const { half, all } = getChildState(childNodes);
console.log(this.data.label, all);
if (!all) {
this.checked = all;
this.indeterminate = half;
}
}
};
@@ -288,7 +323,7 @@ export default class Node {
const parent = this.parent;
if (!parent || parent.level === 0) return;
if (!this.store.checkStrictly) {
if (!this.store.checkStrictly && !recursion) {
reInitChecked(parent);
}
}

View File

@@ -1,4 +1,4 @@
import Node from './node';
import Node, { getChildState } from './node';
import { getNodeKey } from './util';
export default class TreeStore {
@@ -188,61 +188,47 @@ export default class TreeStore {
}
_setCheckedKeys(key, leafOnly = false, checkedKeys) {
const allNodes = this._getAllNodes();
allNodes.sort((a, b) => b.level - a.level);
let allNodes = this._getAllNodes().sort((a, b) => a.level - b.level);
const keys = Object.keys(checkedKeys);
allNodes.forEach((node) => {
let checked = keys.indexOf(node.data[key] + '') > -1;
for (let node of allNodes) {
let checked = keys.indexOf(node.data[key].toString()) > -1;
if (!checked) {
node.setChecked(false, false);
continue;
}
if (!node.isLeaf) {
if (!this.checkStrictly) {
if (node.isLeaf || this.checkStrictly) {
node.setChecked(checked, false);
continue;
}
const { all, none, half } = getChildState(node.childNodes);
if (all) {
node.setChecked(true, !this.checkStrictly);
} else if (half) {
checked = checked ? true : 'half';
node.setChecked(checked, !this.checkStrictly && checked === true);
} else if (none) {
node.setChecked(checked, !this.checkStrictly);
}
if (leafOnly) {
node.setChecked(false, false);
const traverse = function(node) {
const childNodes = node.childNodes;
let all = true;
let none = true;
for (let i = 0, j = childNodes.length; i < j; i++) {
const child = childNodes[i];
if (child.checked !== true || child.indeterminate) {
all = false;
childNodes.forEach((child) => {
if (!child.isLeaf) {
child.setChecked(false, false);
}
if (child.checked !== false || child.indeterminate) {
none = false;
}
}
if (all) {
node.setChecked(true, !this.checkStrictly);
} else if (!all && !none) {
checked = checked ? true : 'half';
node.setChecked(checked, !this.checkStrictly && checked === true);
} else if (none) {
node.setChecked(checked, !this.checkStrictly);
}
} else {
node.setChecked(checked, false);
}
if (leafOnly) {
node.setChecked(false, false);
const traverse = function(node) {
const childNodes = node.childNodes;
childNodes.forEach((child) => {
if (!child.isLeaf) {
child.setChecked(false, false);
}
traverse(child);
});
};
traverse(node);
}
} else {
node.setChecked(checked, false);
traverse(child);
});
};
traverse(node);
}
});
}
}
setCheckedNodes(array, leafOnly = false) {