Commit 9ea47cb3d276e779dbc4c88a70ae746b0a1c0d0f
1 parent
c1e965c3
fixed Table multiple head filter & sort bug
Showing
2 changed files
with
148 additions
and
20 deletions
Show diff stats
examples/routers/table.vue
@@ -3,7 +3,11 @@ | @@ -3,7 +3,11 @@ | ||
3 | <br><br><br><br><br> | 3 | <br><br><br><br><br> |
4 | <Table border :columns="columns1" height="500" :data="data1"></Table> | 4 | <Table border :columns="columns1" height="500" :data="data1"></Table> |
5 | <br><br><br><br><br> | 5 | <br><br><br><br><br> |
6 | - <Table width="550" height="200" border :columns="columns2" :data="data4"></Table> | 6 | + <!--<Table width="550" height="200" border :columns="columns2" :data="data4"></Table>--> |
7 | + <!--<br><br><br><br><br>--> | ||
8 | + <Table border :columns="columns5" :data="data5"></Table> | ||
9 | + <br><br><br><br><br> | ||
10 | + <Table border :columns="columns6" :data="data5"></Table> | ||
7 | <br><br><br><br><br> | 11 | <br><br><br><br><br> |
8 | </div> | 12 | </div> |
9 | </template> | 13 | </template> |
@@ -17,7 +21,25 @@ | @@ -17,7 +21,25 @@ | ||
17 | key: 'name', | 21 | key: 'name', |
18 | align: 'center', | 22 | align: 'center', |
19 | width: 200, | 23 | width: 200, |
20 | - fixed: 'left' | 24 | + fixed: 'left', |
25 | + filters: [ | ||
26 | + { | ||
27 | + label: 'Joe', | ||
28 | + value: 1 | ||
29 | + }, | ||
30 | + { | ||
31 | + label: 'John', | ||
32 | + value: 2 | ||
33 | + } | ||
34 | + ], | ||
35 | + filterMultiple: false, | ||
36 | + filterMethod (value, row) { | ||
37 | + if (value === 1) { | ||
38 | + return row.name === 'Joe'; | ||
39 | + } else if (value === 2) { | ||
40 | + return row.name === 'John Brown'; | ||
41 | + } | ||
42 | + } | ||
21 | }, | 43 | }, |
22 | { | 44 | { |
23 | title: 'Other', | 45 | title: 'Other', |
@@ -27,7 +49,8 @@ | @@ -27,7 +49,8 @@ | ||
27 | title: 'Age', | 49 | title: 'Age', |
28 | key: 'age', | 50 | key: 'age', |
29 | align: 'center', | 51 | align: 'center', |
30 | - width: 200 | 52 | + width: 200, |
53 | + sortable: true | ||
31 | }, | 54 | }, |
32 | { | 55 | { |
33 | title: 'Address', | 56 | title: 'Address', |
@@ -47,7 +70,8 @@ | @@ -47,7 +70,8 @@ | ||
47 | title: 'Building', | 70 | title: 'Building', |
48 | key: 'building', | 71 | key: 'building', |
49 | align: 'center', | 72 | align: 'center', |
50 | - width: 200 | 73 | + width: 200, |
74 | + sortable: true | ||
51 | }, | 75 | }, |
52 | { | 76 | { |
53 | title: 'Door No.', | 77 | title: 'Door No.', |
@@ -210,12 +234,111 @@ | @@ -210,12 +234,111 @@ | ||
210 | city: 'Ottawa', | 234 | city: 'Ottawa', |
211 | zip: 100000 | 235 | zip: 100000 |
212 | } | 236 | } |
213 | - ] | 237 | + ], |
238 | + columns5: [ | ||
239 | + { | ||
240 | + title: 'Date', | ||
241 | + key: 'date', | ||
242 | + sortable: true | ||
243 | + }, | ||
244 | + { | ||
245 | + title: 'Name', | ||
246 | + key: 'name' | ||
247 | + }, | ||
248 | + { | ||
249 | + title: 'Age', | ||
250 | + key: 'age', | ||
251 | + sortable: true | ||
252 | + }, | ||
253 | + { | ||
254 | + title: 'Address', | ||
255 | + key: 'address' | ||
256 | + } | ||
257 | + ], | ||
258 | + data5: [ | ||
259 | + { | ||
260 | + name: 'John Brown', | ||
261 | + age: 18, | ||
262 | + address: 'New York No. 1 Lake Park', | ||
263 | + date: '2016-10-03' | ||
264 | + }, | ||
265 | + { | ||
266 | + name: 'Jim Green', | ||
267 | + age: 24, | ||
268 | + address: 'London No. 1 Lake Park', | ||
269 | + date: '2016-10-01' | ||
270 | + }, | ||
271 | + { | ||
272 | + name: 'Joe Black', | ||
273 | + age: 30, | ||
274 | + address: 'Sydney No. 1 Lake Park', | ||
275 | + date: '2016-10-02' | ||
276 | + }, | ||
277 | + { | ||
278 | + name: 'Jon Snow', | ||
279 | + age: 26, | ||
280 | + address: 'Ottawa No. 2 Lake Park', | ||
281 | + date: '2016-10-04' | ||
282 | + } | ||
283 | + ], | ||
284 | + columns6: [ | ||
285 | + { | ||
286 | + title: 'Date', | ||
287 | + key: 'date' | ||
288 | + }, | ||
289 | + { | ||
290 | + title: 'Name', | ||
291 | + key: 'name' | ||
292 | + }, | ||
293 | + { | ||
294 | + title: 'Age', | ||
295 | + key: 'age', | ||
296 | + filters: [ | ||
297 | + { | ||
298 | + label: 'Greater than 25', | ||
299 | + value: 1 | ||
300 | + }, | ||
301 | + { | ||
302 | + label: 'Less than 25', | ||
303 | + value: 2 | ||
304 | + } | ||
305 | + ], | ||
306 | + filterMultiple: false, | ||
307 | + filterMethod (value, row) { | ||
308 | + if (value === 1) { | ||
309 | + return row.age > 25; | ||
310 | + } else if (value === 2) { | ||
311 | + return row.age < 25; | ||
312 | + } | ||
313 | + } | ||
314 | + }, | ||
315 | + { | ||
316 | + title: 'Address', | ||
317 | + key: 'address', | ||
318 | + filters: [ | ||
319 | + { | ||
320 | + label: 'New York', | ||
321 | + value: 'New York' | ||
322 | + }, | ||
323 | + { | ||
324 | + label: 'London', | ||
325 | + value: 'London' | ||
326 | + }, | ||
327 | + { | ||
328 | + label: 'Sydney', | ||
329 | + value: 'Sydney' | ||
330 | + } | ||
331 | + ], | ||
332 | + filterMethod (value, row) { | ||
333 | + return row.address.indexOf(value) > -1; | ||
334 | + } | ||
335 | + } | ||
336 | + ], | ||
214 | } | 337 | } |
215 | }, | 338 | }, |
216 | mounted () { | 339 | mounted () { |
217 | const data = []; | 340 | const data = []; |
218 | - for (let i = 0; i < 100; i++) { | 341 | + for (let i = 0; i < 20; i++) { |
219 | data.push({ | 342 | data.push({ |
220 | key: i, | 343 | key: i, |
221 | name: 'John Brown', | 344 | name: 'John Brown', |
src/components/table/table-head.vue
@@ -17,42 +17,42 @@ | @@ -17,42 +17,42 @@ | ||
17 | </template> | 17 | </template> |
18 | <template v-else-if="column.type === 'selection'"><Checkbox :value="isSelectAll" :disabled="!data.length" @on-change="selectAll"></Checkbox></template> | 18 | <template v-else-if="column.type === 'selection'"><Checkbox :value="isSelectAll" :disabled="!data.length" @on-change="selectAll"></Checkbox></template> |
19 | <template v-else> | 19 | <template v-else> |
20 | - <span v-if="!column.renderHeader" @click="handleSortByHead(index)">{{ column.title || '#' }}</span> | 20 | + <span v-if="!column.renderHeader" @click="handleSortByHead(getColumn(rowIndex, index)._index)">{{ column.title || '#' }}</span> |
21 | <render-header v-else :render="column.renderHeader" :column="column" :index="index"></render-header> | 21 | <render-header v-else :render="column.renderHeader" :column="column" :index="index"></render-header> |
22 | <span :class="[prefixCls + '-sort']" v-if="column.sortable"> | 22 | <span :class="[prefixCls + '-sort']" v-if="column.sortable"> |
23 | - <i class="ivu-icon ivu-icon-arrow-up-b" :class="{on: column._sortType === 'asc'}" @click="handleSort(index, 'asc')"></i> | ||
24 | - <i class="ivu-icon ivu-icon-arrow-down-b" :class="{on: column._sortType === 'desc'}" @click="handleSort(index, 'desc')"></i> | 23 | + <i class="ivu-icon ivu-icon-arrow-up-b" :class="{on: getColumn(rowIndex, index)._sortType === 'asc'}" @click="handleSort(getColumn(rowIndex, index)._index, 'asc')"></i> |
24 | + <i class="ivu-icon ivu-icon-arrow-down-b" :class="{on: getColumn(rowIndex, index)._sortType === 'desc'}" @click="handleSort(getColumn(rowIndex, index)._index, 'desc')"></i> | ||
25 | </span> | 25 | </span> |
26 | <Poptip | 26 | <Poptip |
27 | v-if="isPopperShow(column)" | 27 | v-if="isPopperShow(column)" |
28 | - v-model="column._filterVisible" | 28 | + v-model="getColumn(rowIndex, index)._filterVisible" |
29 | placement="bottom" | 29 | placement="bottom" |
30 | popper-class="ivu-table-popper" | 30 | popper-class="ivu-table-popper" |
31 | transfer | 31 | transfer |
32 | - @on-popper-hide="handleFilterHide(column._index)"> | 32 | + @on-popper-hide="handleFilterHide(getColumn(rowIndex, index)._index)"> |
33 | <span :class="[prefixCls + '-filter']"> | 33 | <span :class="[prefixCls + '-filter']"> |
34 | - <i class="ivu-icon ivu-icon-funnel" :class="{on: column._isFiltered}"></i> | 34 | + <i class="ivu-icon ivu-icon-funnel" :class="{on: getColumn(rowIndex, index)._isFiltered}"></i> |
35 | </span> | 35 | </span> |
36 | - <div slot="content" :class="[prefixCls + '-filter-list']" v-if="column._filterMultiple"> | 36 | + <div slot="content" :class="[prefixCls + '-filter-list']" v-if="getColumn(rowIndex, index)._filterMultiple"> |
37 | <div :class="[prefixCls + '-filter-list-item']"> | 37 | <div :class="[prefixCls + '-filter-list-item']"> |
38 | - <checkbox-group v-model="column._filterChecked"> | 38 | + <checkbox-group v-model="getColumn(rowIndex, index)._filterChecked"> |
39 | <checkbox v-for="(item, index) in column.filters" :key="index" :label="item.value">{{ item.label }}</checkbox> | 39 | <checkbox v-for="(item, index) in column.filters" :key="index" :label="item.value">{{ item.label }}</checkbox> |
40 | </checkbox-group> | 40 | </checkbox-group> |
41 | </div> | 41 | </div> |
42 | <div :class="[prefixCls + '-filter-footer']"> | 42 | <div :class="[prefixCls + '-filter-footer']"> |
43 | - <i-button type="text" size="small" :disabled="!column._filterChecked.length" @click.native="handleFilter(column._index)">{{ t('i.table.confirmFilter') }}</i-button> | ||
44 | - <i-button type="text" size="small" @click.native="handleReset(column._index)">{{ t('i.table.resetFilter') }}</i-button> | 43 | + <i-button type="text" size="small" :disabled="!getColumn(rowIndex, index)._filterChecked.length" @click.native="handleFilter(getColumn(rowIndex, index)._index)">{{ t('i.table.confirmFilter') }}</i-button> |
44 | + <i-button type="text" size="small" @click.native="handleReset(getColumn(rowIndex, index)._index)">{{ t('i.table.resetFilter') }}</i-button> | ||
45 | </div> | 45 | </div> |
46 | </div> | 46 | </div> |
47 | <div slot="content" :class="[prefixCls + '-filter-list']" v-else> | 47 | <div slot="content" :class="[prefixCls + '-filter-list']" v-else> |
48 | <ul :class="[prefixCls + '-filter-list-single']"> | 48 | <ul :class="[prefixCls + '-filter-list-single']"> |
49 | <li | 49 | <li |
50 | - :class="itemAllClasses(column)" | ||
51 | - @click="handleReset(column._index)">{{ t('i.table.clearFilter') }}</li> | 50 | + :class="itemAllClasses(getColumn(rowIndex, index))" |
51 | + @click="handleReset(getColumn(rowIndex, index)._index)">{{ t('i.table.clearFilter') }}</li> | ||
52 | <li | 52 | <li |
53 | - :class="itemClasses(column, item)" | 53 | + :class="itemClasses(getColumn(rowIndex, index), item)" |
54 | v-for="item in column.filters" | 54 | v-for="item in column.filters" |
55 | - @click="handleSelect(column._index, item.value)">{{ item.label }}</li> | 55 | + @click="handleSelect(getColumn(rowIndex, index)._index, item.value)">{{ item.label }}</li> |
56 | </ul> | 56 | </ul> |
57 | </div> | 57 | </div> |
58 | </Poptip> | 58 | </Poptip> |
@@ -186,6 +186,11 @@ | @@ -186,6 +186,11 @@ | ||
186 | }, | 186 | }, |
187 | handleFilterHide (index) { | 187 | handleFilterHide (index) { |
188 | this.$parent.handleFilterHide(index); | 188 | this.$parent.handleFilterHide(index); |
189 | + }, | ||
190 | + // 因为表头嵌套不是深拷贝,所以没有 _ 开头的方法,在 isGroup 下用此列 | ||
191 | + getColumn (rowIndex, index) { | ||
192 | + const isGroup = this.columnRows.length > 1; | ||
193 | + return isGroup ? this.columns[rowIndex] : this.headRows[rowIndex][index]; | ||
189 | } | 194 | } |
190 | } | 195 | } |
191 | }; | 196 | }; |