element-ui-for-gov
Version:
element-ui for gov
331 lines (319 loc) • 10.9 kB
JavaScript
import ElRow from 'element-ui-for-gov/packages/row';
import ElCol from 'element-ui-for-gov/packages/col';
import ElButton from 'element-ui-for-gov/packages/button';
import ElTree from 'element-ui-for-gov/packages/tree';
import Store from 'element-ui-for-gov/src/utils/tree-store';
import SectionHeader from './section-header';
import SelectedList from './selected-list';
const prefix = 'el-user-picker';
export default {
name: 'Transfer',
inject: ['handleChangeUser', 'clearChecked', 'nodeKey', 'setTreeInstance'],
props: {
treeProps: Object,
fieldNames: Object,
grid: Object,
checkedUsers: Array,
filterNodeMethod: Function,
defaultChecked: Array,
renderChecked: Function,
renderCheckedItem: Function,
selectPanelButton: Function,
radio: Boolean,
isSearchCheckAll: Boolean,
height: Number,
checkOnClickNode: Boolean
},
components: {ElRow, ElCol, ElButton, ElTree, SectionHeader, SelectedList},
data() {
return {
treeData: [],
store: null,
totalData: [],
searchData: [],
prevChecked: [],
searchWrapHeight: 0
};
},
created() {
const {lazy, loadData, children, disabled} = this.treeProps;
const {fieldNames} = this;
this.store = new Store({
key: this.nodeKey,
label: data => data[fieldNames.parent] || data[fieldNames.userName],
isLeaf: (data) => !!data[fieldNames.userName],
hideCheckbox: 'hideCheckbox',
children: children || 'children',
disabled: disabled || 'disabled',
data: []
});
!lazy ? loadData().then((data) => {
this.store.initData(data);
this.treeData = this.store.data;
this.totalData = this.treeData;
this.searchData = this.treeData;
this.setDefaultChecked(this.defaultChecked);
}) : this.setDefaultChecked(this.defaultChecked);
},
mounted() {
this.setTreeInstance(this.treeProps.key, this);
this.initFilterResize();
},
watch: {
defaultChecked(users) {
this.$nextTick(() => {
this.setDefaultChecked(users);
});
},
checkedUsers(arr) {
let nodes = [];
arr.forEach(item => {
const cache = this.store.getNodes(item);
nodes = nodes.concat(cache);
});
this.prevChecked = [].concat(nodes);
// console.log('selected nodes: ', nodes);
this.$nextTick(() => {
this.setCheckedNodes(nodes);
});
}
},
methods: {
initFilterResize() {
const filterWrapper = this.$el.querySelector('.custom-filter-wrapper');
if (filterWrapper) {
try {
const resizeObserver = new ResizeObserver(entries => {
for (let entry of entries) {
if (entry.contentRect.height > 0) {
this.searchWrapHeight = filterWrapper.offsetHeight;
}
}
});
resizeObserver.observe(filterWrapper);
} catch (e) {
this.$nextTick(() => {
this.searchWrapHeight = filterWrapper.offsetHeight;
});
}
}
},
setDefaultChecked(keys) {
// console.log(ids);
let users = [];
keys.forEach(user => {
// console.log(user);
let nodes = typeof user === 'object' ? [{data: user}] : this.store.getNodesByKey(user);
if (nodes.length) {
users.push(nodes[0].data);
}
});
this.handleChangeUser(users);
},
handleCheck(node, {checkedNodes}) {
if (this.radio) {
let users = [];
if (checkedNodes.includes(node)) {
users = [node.data];
}
this.handleChangeUser(users);
} else {
const deleteArr = this.store.difference(this.prevChecked, checkedNodes.filter(node => node.isLeaf));
// console.log(deleteArr);
const users = checkedNodes.filter(node => node.isLeaf).map(item => item.data);
const deleteUsers = deleteArr.filter(node => node.isLeaf).map(item => item.data);
this.handleChangeUser(users, deleteUsers);
}
},
getCheckedNodes() {
const nodes = this.$refs['tree'].getCheckedNodes();
const users = nodes.filter(node => node.isLeaf).map(item => item.data);
if (this.radio) {
if (users && users.length) {
this.handleChangeUser(users, []);
}
} else {
this.handleChangeUser(users, []);
}
},
checkAll() {
console.log('checkAll');
const {checkAllMethod} = this.treeProps;
if (checkAllMethod) {
checkAllMethod(this, (users) => {
this.handleChangeUser(users);
});
} else {
const users = [];
const traverse = (arr) => {
arr.forEach(item => {
if (item.isLeaf && !item.disabled) {
users.push(item.data);
} else if (item.children) {
traverse(item.children);
}
});
};
if (this.isSearchCheckAll) {
traverse(this.searchData);
} else {
traverse(this.totalData);
}
this.handleChangeUser(users);
}
},
setCheckedNodes(nodes) {
this.$refs['tree'].setCheckedNodes(nodes);
},
filter(value) {
const filteredData = [];
const traverse = (arr) => {
arr.forEach(item => {
if (this.filterNodeMethod(value, item, item)) {
filteredData.push(item);
} else if (item.children) {
traverse(item.children);
}
});
};
traverse(this.totalData);
this.searchData = filteredData;
this.$refs['tree'].filter(value);
},
setTreeData(data) {
this.store.initData(data, this.treeProps.lazy);
this.treeData = this.store.data;
this.searchData = this.store.data;
this.setDefaultChecked(this.defaultChecked);
},
bfsRegisterNode(data, current) {
const getChildren = (node) => {
const children = this.treeProps.children || 'children';
return typeof children === 'function' ? children(node) : node[children];
};
const queue = [{root: true, children: data}];
const queueNode = [current];
while (queue.length) {
const head = queue.shift();
const parent = queueNode.shift();
if (Array.isArray(head.children)) {
for (let i = 0, len = head.children.length; i < len; i++) {
const node = this.store.registerNode(head.children[i]);
node.parent = parent;
parent.children.push(node);
queue.push({
...head.children[i],
children: getChildren(head.children[i])
});
queueNode.push(node);
}
}
}
},
bfsTravel(node, cb) {
const queue = [node];
while (queue.length) {
const head = queue.shift();
cb && cb(head);
if (Array.isArray(head.children)) {
for (let i = 0; i < head.children.length ; i++) {
queue.push(head.children[i]);
}
}
}
},
loadDataAsync(node, resolve, isCheck) {
const {loadDataAsync} = this.treeProps;
// console.log('load', node);
loadDataAsync(node.data ? node.data : node, data => {
// console.log(data);
if (data && data.length > 0) {
const current = !node.parent ? {children: []} : node.data;
this.bfsRegisterNode(data, current);
if (!node.parent) {
this.store.data = current.children;
this.totalData = this.store.data;
this.searchData = this.store.data;
}
if (!isCheck) {
if (this.radio) {
if (this.checkedUsers && this.checkedUsers.length && this.defaultChecked.length) {
if (this.checkedUsers[0].id && this.checkedUsers[0].id === this.defaultChecked[0].id) {
this.setDefaultChecked([this.defaultChecked[0]]);
}
}
} else {
const sList = [];
this.checkedUsers.forEach((node) => {
this.defaultChecked.forEach((nodeD) => {
if (nodeD.key && nodeD.key === node.key) {
sList.push(node);
}
});
});
this.setDefaultChecked(sList);
}
} else {
const selectList = [];
this.bfsTravel(current, (node) => {
if (!node.disabled && node.isLeaf) {
selectList.push(node.key);
}
});
this.defaultChecked.forEach((item) => {
if (!selectList.includes(item)) {
selectList.push(item);
}
});
this.setDefaultChecked(selectList);
}
return resolve(current.children);
} else {
return resolve([]);
}
}, isCheck);
}
},
render() {
const {treeData, fieldNames, treeProps, checkedUsers, $slots, renderChecked, renderCheckedItem, selectPanelButton, height, checkOnClickNode} = this;
return (<ElRow>
<ElCol span={10}>
<div class={`${prefix}__section-wrapper`}>
<SectionHeader title="待选列表" />
{$slots.filter && <div class="custom-filter-wrapper">{$slots.filter}</div> }
<div class={`${prefix}__section-content`} style={{height: `${height ? height - this.searchWrapHeight - 1 : 464 - this.searchWrapHeight}px`}}>
<ElTree ref="tree"
lazy={treeProps.lazy}
data={treeData}
nodeKey="id"
load={this.loadDataAsync}
props={{
hideCheckbox: 'hideCheckbox',
isLeaf: item => item.isLeaf
}}
show-checkbox
checkOnClickNode={checkOnClickNode}
expand-on-check={treeProps.lazy}
filterNodeMethod={this.filterNodeMethod}
{...{
on: {
// 'check-change': treeProps.lazy ? this.handleCheckChange : this.getCheckedNodes,
'node-expand': treeProps.lazy ? this.getCheckedNodes : () => {},
'check': this.handleCheck
}
}}
/>
</div>
</div>
</ElCol>
<ElCol span={4} class={`${prefix}__section-btns`}>
{!this.radio && <ElButton {...{on: {click: this.checkAll}}}>全选<i class="el-icon-arrow-right"/></ElButton>}
<br />
<ElButton {...{on: {click: this.clearChecked}}}>清空已选</ElButton>
</ElCol>
<ElCol span={10}>
<SelectedList height={this.height} checkedUsers={checkedUsers} label={fieldNames.userName} renderChecked={renderChecked} renderCheckedItem={renderCheckedItem} selectPanelButton={selectPanelButton} />
</ElCol>
</ElRow>);
}
};