From 0b2a1eb784f74190e023d1dcad0c0ed06800c0c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E5=A5=95?= Date: Tue, 22 May 2018 18:20:04 +0800 Subject: [PATCH] Table: add sort-orders (#11283) --- examples/docs/en-US/table.md | 1 + examples/docs/es/table.md | 1 + examples/docs/zh-CN/table.md | 3 ++- packages/table/src/table-column.js | 14 ++++++++++++-- packages/table/src/table-header.js | 8 +++++--- test/unit/specs/table.spec.js | 16 ++++++++++++++++ types/table-column.d.ts | 4 ++++ 7 files changed, 41 insertions(+), 6 deletions(-) diff --git a/examples/docs/en-US/table.md b/examples/docs/en-US/table.md index 61a9606b9..cf73247d0 100644 --- a/examples/docs/en-US/table.md +++ b/examples/docs/en-US/table.md @@ -2029,6 +2029,7 @@ You can customize row index in `type=index` columns. | sortable | whether column can be sorted. Remote sorting can be done by setting this attribute to 'custom' and listening to the `sort-change` event of Table | boolean, string | true, false, custom | false | | sort-method | sorting method, works when `sortable` is `true`. Should return a number, just like Array.sort | Function(a, b) | — | — | | sort-by | specify which property to sort by, works when `sortable` is `true` and `sort-method` is `undefined`. If set to an Array, the column will sequentially sort by the next property if the previous one is equal | Function(row, index)/String/Array | — | — | +| sort-orders | the order of the sorting strategies used when sorting the data, works when `sortable` is `true`. Accepts an array, as the user clicks on the header, the column is sorted in order of the elements in the array | array | the elements in the array need to be one of the following: `ascending`, `descending` and `null` (restores to the original order) | ['ascending', 'descending', null] | | resizable | whether column width can be resized, works when `border` of `el-table` is `true` | boolean | — | false | | formatter | function that formats cell content | Function(row, column, cellValue, index) | — | — | | show-overflow-tooltip | whether to hide extra content and show them in a tooltip when hovering on the cell | boolean | — | false | diff --git a/examples/docs/es/table.md b/examples/docs/es/table.md index ec5155331..27b40123e 100644 --- a/examples/docs/es/table.md +++ b/examples/docs/es/table.md @@ -2031,6 +2031,7 @@ Puede personalizar el índice de la fila con la propiedad `type=index` de las co | sortable | especifica que columna puede ser ordenado. El ordenamiento remoto puede ser hecho configurando el atributo `custom` y escucha al evento de tabla `sort-change` | boolean, string | true, false, custom | false | | sort-method | método de ordenamiento, funciona cuando `sortable` está en `true`. Debería devolver un número, al igual que Array.sort | Function(a, b) | — | — | | sort-by | especifica por cual propiedad de va a ordenar, funciona cuando `sortable` es `true` y `sort-method` es `undefined`. Si se establece a un arreglo, la columna ordenara secuencialmente por la siguiente propiedad si la anterior es igual | Function(row, index)/String/Array | — | — | +| sort-orders | the order of the sorting strategies used when sorting the data, works when `sortable` is `true`. Accepts an array, as the user clicks on the header, the column is sorted in order of the elements in the array | array | the elements in the array need to be one of the following: `ascending`, `descending` and `null` (restores to the original order) | ['ascending', 'descending', null] | | resizable | especifica si el ancho de la columna puede ser redimensionado, funciona cuando `border` de `el-table` está en `true` | boolean | — | false | | formatter | función que formatea el contenido de la celda | Function(row, column, cellValue, index) | — | — | | show-overflow-tooltip | especifica si el _tooltip_ debe ocultarse o mostrarse al hacer _hover_ en la celda | boolean | — | false | diff --git a/examples/docs/zh-CN/table.md b/examples/docs/zh-CN/table.md index c8e13f3d9..1ffa0e251 100644 --- a/examples/docs/zh-CN/table.md +++ b/examples/docs/zh-CN/table.md @@ -2088,7 +2088,8 @@ | render-header | 列标题 Label 区域渲染使用的 Function | Function(h, { column, $index }) | — | — | | sortable | 对应列是否可以排序,如果设置为 'custom',则代表用户希望远程排序,需要监听 Table 的 sort-change 事件 | boolean, string | true, false, 'custom' | false | | sort-method | 对数据进行排序的时候使用的方法,仅当 sortable 设置为 true 的时候有效,需返回一个数字,和 Array.sort 表现一致 | Function(a, b) | — | — | -| sort-by | 指定数据按照哪个属性进行排序,仅当 sortable 设置为 true 且没有设置 sort-method 的时候有效。如果 sort-by 为数组,则先按照第 1 个属性排序,如果第 1 个相等,再按照第 2 个排序,以此类推。 | String/Array/Function(row, index) | — | — | +| sort-by | 指定数据按照哪个属性进行排序,仅当 sortable 设置为 true 且没有设置 sort-method 的时候有效。如果 sort-by 为数组,则先按照第 1 个属性排序,如果第 1 个相等,再按照第 2 个排序,以此类推 | String/Array/Function(row, index) | — | — | +| sort-orders | 数据在排序时所使用排序策略的轮转顺序,仅当 sortable 为 true 时有效。需传入一个数组,随着用户点击表头,该列依次按照数组中元素的顺序进行排序 | array | 数组中的元素需为以下三者之一:`ascending` 表示升序,`descending` 表示降序,`null` 表示还原为原始顺序 | ['ascending', 'descending', null] | | resizable | 对应列是否可以通过拖动改变宽度(需要在 el-table 上设置 border 属性为真) | boolean | — | true | | formatter | 用来格式化内容 | Function(row, column, cellValue, index) | — | — | | show-overflow-tooltip | 当内容过长被隐藏时显示 tooltip | Boolean | — | false | diff --git a/packages/table/src/table-column.js b/packages/table/src/table-column.js index ab006dfc1..8377e90ba 100644 --- a/packages/table/src/table-column.js +++ b/packages/table/src/table-column.js @@ -180,7 +180,16 @@ export default { type: Boolean, default: true }, - index: [Number, Function] + index: [Number, Function], + sortOrders: { + type: Array, + default() { + return ['ascending', 'descending', null]; + }, + validator(val) { + return val.every(order => ['ascending', 'descending', null].indexOf(order) > -1); + } + } }, data() { @@ -266,7 +275,8 @@ export default { filterOpened: false, filteredValue: this.filteredValue || [], filterPlacement: this.filterPlacement || '', - index: this.index + index: this.index, + sortOrders: this.sortOrders }); objectAssign(column, forced[type] || {}); diff --git a/packages/table/src/table-header.js b/packages/table/src/table-header.js index cfb445585..5fcc8935a 100644 --- a/packages/table/src/table-header.js +++ b/packages/table/src/table-header.js @@ -475,13 +475,15 @@ export default { document.body.style.cursor = ''; }, - toggleOrder(order) { - return !order ? 'ascending' : order === 'ascending' ? 'descending' : null; + toggleOrder({ order, sortOrders }) { + if (order === '') return sortOrders[0]; + const index = sortOrders.indexOf(order || null); + return sortOrders[index > sortOrders.length - 2 ? 0 : index + 1]; }, handleSortClick(event, column, givenOrder) { event.stopPropagation(); - let order = givenOrder || this.toggleOrder(column.order); + let order = givenOrder || this.toggleOrder(column); let target = event.target; while (target && target.tagName !== 'TH') { diff --git a/test/unit/specs/table.spec.js b/test/unit/specs/table.spec.js index ad34ecec3..cfacb3734 100644 --- a/test/unit/specs/table.spec.js +++ b/test/unit/specs/table.spec.js @@ -1062,6 +1062,22 @@ describe('Table', () => { }, DELAY); }); + it('sortable orders', done => { + const vm = createTable('', '', '', 'sortable :sort-orders="[\'descending\', \'ascending\']"', {}); + + setTimeout(_ => { + const elm = vm.$el.querySelector('.caret-wrapper'); + elm.click(); + + setTimeout(_ => { + const lastCells = vm.$el.querySelectorAll('.el-table__body-wrapper tbody tr td:last-child'); + expect(toArray(lastCells).map(node => node.textContent)).to.eql(['100', '95', '92', '92', '80']); + destroyVM(vm); + done(); + }, DELAY); + }, DELAY); + }); + it('sortable method', done => { const vm = createTable( 'sortable :sort-method="sortMethod"', '', '', '', { diff --git a/types/table-column.d.ts b/types/table-column.d.ts index 3c3f14287..193ce25ee 100644 --- a/types/table-column.d.ts +++ b/types/table-column.d.ts @@ -4,6 +4,7 @@ import { PopoverPlacement } from './popover' export type TableColumnType = 'default' | 'selection' | 'index' | 'expand' export type TableColumnFixedType = 'left' | 'right' +export type SortOrders = 'ascending' | 'descending' | null export type TableColumn = { /** Label of the column */ @@ -69,6 +70,9 @@ export declare class ElTableColumn extends ElementUIComponent { /** Sorting method. Works when `sortable` is `true` */ sortMethod: (a: any, b: any) => number + /** The order of the sorting strategies used when sorting the data. Works when `sortable` is `true`. */ + sortOrders: SortOrders[] + /** Whether column width can be resized. Works when border of `el-table` is `true` */ resizable: boolean