Transfer: add target-order (#9960)

pull/9640/merge
杨奕 2018-03-02 14:43:10 +08:00 committed by GitHub
parent c5d76d7910
commit aa5f015cd9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 89 additions and 4 deletions

View File

@ -264,6 +264,7 @@ By default, Transfer looks for `key`, `label` and `disabled` in a data item. If
| filterable | whether Transfer is filterable | boolean | — | false |
| filter-placeholder | placeholder for the filter input | string | — | Enter keyword |
| filter-method | custom filter method | function | — | — |
| target-order | order strategy for elements in the target list. If set to `original`, the elements will keep the same order as the data source. If set to `push`, the newly added elements will be pushed to the bottom. If set to `unshift`, the newly added elements will be inserted on the top | string | original / push / unshift | original |
| titles | custom list titles | array | — | ['List 1', 'List 2'] |
| button-texts | custom button texts | array | — | [ ] |
| render-content | custom render function for data items | function(h, option) | — | — |

View File

@ -265,6 +265,7 @@ Por defecto Transfer busca los atributos `key`, `label`, y `disabled` en cada el
| filterable | Si se puede filtrar | boolean | — | false |
| filter-placeholder | Placeholder para el input del filtro | string | — | Enter keyword |
| filter-method | Método de filtrado | function | — | — |
| target-order | order strategy for elements in the target list. If set to `original`, the elements will keep the same order as the data source. If set to `push`, the newly added elements will be pushed to the bottom. If set to `unshift`, the newly added elements will be inserted on the top | string | original / push / unshift | original |
| titles | Títulos de las listas | array | — | ['List 1', 'List 2'] |
| button-texts | Texto de los botones | array | — | [ ] |
| render-content | Función de renderizado | function(h, option) | — | — |

View File

@ -261,6 +261,7 @@
| filterable | 是否可搜索 | boolean | — | false |
| filter-placeholder | 搜索框占位符 | string | — | 请输入搜索内容 |
| filter-method | 自定义搜索方法 | function | — | — |
| target-order | 右侧列表元素的排序策略:若为 `original`,则保持与数据源相同的顺序;若为 `push`,则新加入的元素排在最后;若为 `unshift`,则新加入的元素排在最前 | string | original / push / unshift | original |
| titles | 自定义列表标题 | array | — | ['列表 1', '列表 2'] |
| button-texts | 自定义按钮文案 | array | — | [ ] |
| render-content | 自定义数据项渲染函数 | function(h, option) | — | — |

View File

@ -117,6 +117,10 @@
disabled: 'disabled'
};
}
},
targetOrder: {
type: String,
default: 'original'
}
},
@ -128,12 +132,19 @@
},
computed: {
dataObj() {
const key = this.props.key;
return this.data.reduce((o, cur) => (o[cur[key]] = cur) && o, {});
},
sourceData() {
return this.data.filter(item => this.value.indexOf(item[this.props.key]) === -1);
},
targetData() {
return this.data.filter(item => this.value.indexOf(item[this.props.key]) > -1);
return this.targetOrder === 'original'
? this.data.filter(item => this.value.indexOf(item[this.props.key]) > -1)
: this.value.map(key => this.dataObj[key]);
},
hasButtonTexts() {
@ -178,11 +189,20 @@
addToRight() {
let currentValue = this.value.slice();
this.leftChecked.forEach(item => {
if (this.value.indexOf(item) === -1) {
currentValue = currentValue.concat(item);
const itemsToBeMoved = [];
const key = this.props.key;
this.data.forEach(item => {
const itemKey = item[key];
if (
this.leftChecked.indexOf(itemKey) > -1 &&
this.value.indexOf(itemKey) === -1
) {
itemsToBeMoved.push(itemKey);
}
});
currentValue = this.targetOrder === 'unshift'
? itemsToBeMoved.concat(currentValue)
: currentValue.concat(itemsToBeMoved);
this.$emit('input', currentValue);
this.$emit('change', currentValue, 'right', this.leftChecked);
},

View File

@ -122,4 +122,63 @@ describe('Transfer', () => {
leftList.handleAllCheckedChange({ target: { checked: true } });
expect(leftList.checked.length).to.equal(12);
});
describe('target order', () => {
it('original(default)', done => {
vm = createTransfer('v-model="value" :left-default-checked="[2, 3]"', {
data() {
return {
value: [1, 4]
};
}
});
const transfer = vm.$refs.transfer;
setTimeout(() => {
transfer.addToRight();
setTimeout(() => {
const targetItems = [].slice.call(vm.$el.querySelectorAll('.el-transfer__buttons + .el-transfer-panel .el-transfer-panel__body .el-checkbox__label span'));
expect(targetItems.map(item => item.innerText)).to.deep.equal(['备选项 1', '备选项 2', '备选项 3', '备选项 4']);
done();
}, 50);
}, 50);
});
it('push', done => {
vm = createTransfer('v-model="value" :left-default-checked="[2, 3]" target-order="push"', {
data() {
return {
value: [1, 4]
};
}
});
const transfer = vm.$refs.transfer;
setTimeout(() => {
transfer.addToRight();
setTimeout(() => {
const targetItems = [].slice.call(vm.$el.querySelectorAll('.el-transfer__buttons + .el-transfer-panel .el-transfer-panel__body .el-checkbox__label span'));
expect(targetItems.map(item => item.innerText)).to.deep.equal(['备选项 1', '备选项 4', '备选项 2', '备选项 3']);
done();
}, 50);
}, 50);
});
it('unshift', done => {
vm = createTransfer('v-model="value" :left-default-checked="[2, 3]" target-order="unshift"', {
data() {
return {
value: [1, 4]
};
}
});
const transfer = vm.$refs.transfer;
setTimeout(() => {
transfer.addToRight();
setTimeout(() => {
const targetItems = [].slice.call(vm.$el.querySelectorAll('.el-transfer__buttons + .el-transfer-panel .el-transfer-panel__body .el-checkbox__label span'));
expect(targetItems.map(item => item.innerText)).to.deep.equal(['备选项 2', '备选项 3', '备选项 1', '备选项 4']);
done();
}, 50);
}, 50);
});
});
});

3
types/transfer.d.ts vendored
View File

@ -42,6 +42,9 @@ export declare class ElTransfer extends ElementUIComponent {
/** Custom filter method */
filterMethod: (query: string, item: TransferData) => boolean
/** Order strategy for elements in the target list */
targetOrder: string
/** Custom list titles */
titles: string[]