iview/src/components/transfer/transfer.vue

261 lines
9.4 KiB
Vue
Raw Normal View History

<script>
import List from './list.vue';
import Operation from './operation.vue';
import Locale from '../../mixins/locale';
import Emitter from '../../mixins/emitter';
const prefixCls = 'ivu-transfer';
export default {
2017-06-08 10:20:11 +08:00
name: 'Transfer',
mixins: [ Emitter, Locale ],
2017-07-12 11:37:06 +08:00
render (h) {
2017-03-08 17:04:07 +08:00
function cloneVNode (vnode) {
2017-03-08 17:08:10 +08:00
const clonedChildren = vnode.children && vnode.children.map(vnode => cloneVNode(vnode));
2017-07-12 11:37:06 +08:00
const cloned = h(vnode.tag, vnode.data, clonedChildren);
2017-03-08 17:04:07 +08:00
cloned.text = vnode.text;
cloned.isComment = vnode.isComment;
cloned.componentOptions = vnode.componentOptions;
cloned.elm = vnode.elm;
cloned.context = vnode.context;
cloned.ns = vnode.ns;
cloned.isStatic = vnode.isStatic;
cloned.key = vnode.key;
return cloned;
}
const vNodes = this.$slots.default === undefined ? [] : this.$slots.default;
const clonedVNodes = this.$slots.default === undefined ? [] : vNodes.map(vnode => cloneVNode(vnode));
2017-03-08 17:04:07 +08:00
2017-07-12 11:37:06 +08:00
return h('div', {
2017-03-08 17:04:07 +08:00
'class': this.classes
}, [
2017-07-12 11:37:06 +08:00
h(List, {
2017-03-08 17:04:07 +08:00
ref: 'left',
props: {
prefixCls: this.prefixCls + '-list',
data: this.leftData,
renderFormat: this.renderFormat,
checkedKeys: this.leftCheckedKeys,
validKeysCount: this.leftValidKeysCount,
listStyle: this.listStyle,
title: this.localeTitles[0],
2017-03-08 17:04:07 +08:00
filterable: this.filterable,
filterPlaceholder: this.localeFilterPlaceholder,
2017-03-08 17:04:07 +08:00
filterMethod: this.filterMethod,
notFoundText: this.localeNotFoundText
2017-03-08 17:04:07 +08:00
},
on: {
'on-checked-keys-change': this.handleLeftCheckedKeysChange
}
}, vNodes),
2017-07-12 11:37:06 +08:00
h(Operation, {
2017-03-08 17:04:07 +08:00
props: {
prefixCls: this.prefixCls,
operations: this.operations,
leftActive: this.leftValidKeysCount > 0,
rightActive: this.rightValidKeysCount > 0
}
}),
2017-07-12 11:37:06 +08:00
h(List, {
2017-03-08 17:04:07 +08:00
ref: 'right',
props: {
prefixCls: this.prefixCls + '-list',
data: this.rightData,
renderFormat: this.renderFormat,
checkedKeys: this.rightCheckedKeys,
validKeysCount: this.rightValidKeysCount,
listStyle: this.listStyle,
title: this.localeTitles[1],
2017-03-08 17:04:07 +08:00
filterable: this.filterable,
filterPlaceholder: this.localeFilterPlaceholder,
2017-03-08 17:04:07 +08:00
filterMethod: this.filterMethod,
notFoundText: this.localeNotFoundText
2017-03-08 17:04:07 +08:00
},
on: {
'on-checked-keys-change': this.handleRightCheckedKeysChange
}
2017-03-15 19:59:46 +08:00
}, clonedVNodes)
2017-03-08 17:04:07 +08:00
]);
},
props: {
data: {
type: Array,
default () {
2016-12-25 22:49:42 +08:00
return [];
}
},
renderFormat: {
type: Function,
default (item) {
return item.label || item.key;
}
},
targetKeys: {
type: Array,
default () {
2016-12-25 22:49:42 +08:00
return [];
}
},
selectedKeys: {
type: Array,
default () {
2016-12-25 22:49:42 +08:00
return [];
}
},
listStyle: {
type: Object,
default () {
2016-12-25 22:49:42 +08:00
return {};
}
},
titles: {
type: Array
},
operations: {
type: Array,
default () {
2016-12-25 22:49:42 +08:00
return [];
}
},
filterable: {
type: Boolean,
default: false
},
filterPlaceholder: {
type: String
},
filterMethod: {
type: Function,
default (data, query) {
const type = ('label' in data) ? 'label' : 'key';
return data[type].indexOf(query) > -1;
}
},
notFoundText: {
type: String
}
},
data () {
return {
prefixCls: prefixCls,
leftData: [],
rightData: [],
leftCheckedKeys: [],
rightCheckedKeys: []
2016-12-25 22:49:42 +08:00
};
},
computed: {
classes () {
return [
`${prefixCls}`
2016-12-25 22:49:42 +08:00
];
},
leftValidKeysCount () {
return this.getValidKeys('left').length;
},
rightValidKeysCount () {
return this.getValidKeys('right').length;
},
localeFilterPlaceholder () {
if (this.filterPlaceholder === undefined) {
return this.t('i.transfer.filterPlaceholder');
} else {
return this.filterPlaceholder;
}
},
localeNotFoundText () {
if (this.notFoundText === undefined) {
return this.t('i.transfer.notFoundText');
} else {
return this.notFoundText;
}
},
localeTitles () {
if (this.titles === undefined) {
return [this.t('i.transfer.titles.source'), this.t('i.transfer.titles.target')];
} else {
return this.titles;
}
}
},
methods: {
getValidKeys (direction) {
return this[`${direction}Data`].filter(data => !data.disabled && this[`${direction}CheckedKeys`].indexOf(data.key) > -1).map(data => data.key);
},
splitData (init = false) {
this.leftData = [...this.data];
this.rightData = [];
if (this.targetKeys.length > 0) {
this.targetKeys.forEach((targetKey) => {
2017-06-14 17:40:29 +08:00
const filteredData = this.leftData.filter((data, index) => {
if (data.key === targetKey) {
this.leftData.splice(index, 1);
return true;
}
return false;
2017-06-14 17:48:25 +08:00
});
if (filteredData && filteredData.length > 0) this.rightData.push(filteredData[0]);
});
}
if (init) {
this.splitSelectedKey();
}
},
splitSelectedKey () {
const selectedKeys = this.selectedKeys;
if (selectedKeys.length > 0) {
this.leftCheckedKeys = this.leftData
.filter(data => selectedKeys.indexOf(data.key) > -1)
.map(data => data.key);
this.rightCheckedKeys = this.rightData
.filter(data => selectedKeys.indexOf(data.key) > -1)
.map(data => data.key);
}
},
moveTo (direction) {
const targetKeys = this.targetKeys;
const opposite = direction === 'left' ? 'right' : 'left';
const moveKeys = this.getValidKeys(opposite);
const newTargetKeys = direction === 'right' ?
moveKeys.concat(targetKeys) :
targetKeys.filter(targetKey => !moveKeys.some(checkedKey => targetKey === checkedKey));
this.$refs[opposite].toggleSelectAll(false);
this.$emit('on-change', newTargetKeys, direction, moveKeys);
this.dispatch('FormItem', 'on-form-change', {
tarketKeys: newTargetKeys,
direction: direction,
moveKeys: moveKeys
});
2017-03-07 15:06:38 +08:00
},
handleLeftCheckedKeysChange (keys) {
this.leftCheckedKeys = keys;
},
handleRightCheckedKeysChange (keys) {
this.rightCheckedKeys = keys;
2017-11-07 17:54:36 +08:00
},
handleCheckedKeys () {
const sourceSelectedKeys = this.getValidKeys('left');
const targetSelectedKeys = this.getValidKeys('right');
this.$emit('on-selected-change', sourceSelectedKeys, targetSelectedKeys);
}
},
watch: {
targetKeys () {
this.splitData(false);
2017-04-01 11:21:35 +08:00
},
data () {
this.splitData(false);
}
},
2017-07-12 16:22:00 +08:00
mounted () {
this.splitData(true);
}
2016-12-25 22:49:42 +08:00
};
</script>