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 | 3 | <br><br><br><br><br> |
4 | 4 | <Table border :columns="columns1" height="500" :data="data1"></Table> |
5 | 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 | 11 | <br><br><br><br><br> |
8 | 12 | </div> |
9 | 13 | </template> |
... | ... | @@ -17,7 +21,25 @@ |
17 | 21 | key: 'name', |
18 | 22 | align: 'center', |
19 | 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 | 45 | title: 'Other', |
... | ... | @@ -27,7 +49,8 @@ |
27 | 49 | title: 'Age', |
28 | 50 | key: 'age', |
29 | 51 | align: 'center', |
30 | - width: 200 | |
52 | + width: 200, | |
53 | + sortable: true | |
31 | 54 | }, |
32 | 55 | { |
33 | 56 | title: 'Address', |
... | ... | @@ -47,7 +70,8 @@ |
47 | 70 | title: 'Building', |
48 | 71 | key: 'building', |
49 | 72 | align: 'center', |
50 | - width: 200 | |
73 | + width: 200, | |
74 | + sortable: true | |
51 | 75 | }, |
52 | 76 | { |
53 | 77 | title: 'Door No.', |
... | ... | @@ -210,12 +234,111 @@ |
210 | 234 | city: 'Ottawa', |
211 | 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 | 339 | mounted () { |
217 | 340 | const data = []; |
218 | - for (let i = 0; i < 100; i++) { | |
341 | + for (let i = 0; i < 20; i++) { | |
219 | 342 | data.push({ |
220 | 343 | key: i, |
221 | 344 | name: 'John Brown', | ... | ... |
src/components/table/table-head.vue
... | ... | @@ -17,42 +17,42 @@ |
17 | 17 | </template> |
18 | 18 | <template v-else-if="column.type === 'selection'"><Checkbox :value="isSelectAll" :disabled="!data.length" @on-change="selectAll"></Checkbox></template> |
19 | 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 | 21 | <render-header v-else :render="column.renderHeader" :column="column" :index="index"></render-header> |
22 | 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 | 25 | </span> |
26 | 26 | <Poptip |
27 | 27 | v-if="isPopperShow(column)" |
28 | - v-model="column._filterVisible" | |
28 | + v-model="getColumn(rowIndex, index)._filterVisible" | |
29 | 29 | placement="bottom" |
30 | 30 | popper-class="ivu-table-popper" |
31 | 31 | transfer |
32 | - @on-popper-hide="handleFilterHide(column._index)"> | |
32 | + @on-popper-hide="handleFilterHide(getColumn(rowIndex, index)._index)"> | |
33 | 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 | 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 | 37 | <div :class="[prefixCls + '-filter-list-item']"> |
38 | - <checkbox-group v-model="column._filterChecked"> | |
38 | + <checkbox-group v-model="getColumn(rowIndex, index)._filterChecked"> | |
39 | 39 | <checkbox v-for="(item, index) in column.filters" :key="index" :label="item.value">{{ item.label }}</checkbox> |
40 | 40 | </checkbox-group> |
41 | 41 | </div> |
42 | 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 | 45 | </div> |
46 | 46 | </div> |
47 | 47 | <div slot="content" :class="[prefixCls + '-filter-list']" v-else> |
48 | 48 | <ul :class="[prefixCls + '-filter-list-single']"> |
49 | 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 | 52 | <li |
53 | - :class="itemClasses(column, item)" | |
53 | + :class="itemClasses(getColumn(rowIndex, index), item)" | |
54 | 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 | 56 | </ul> |
57 | 57 | </div> |
58 | 58 | </Poptip> |
... | ... | @@ -186,6 +186,11 @@ |
186 | 186 | }, |
187 | 187 | handleFilterHide (index) { |
188 | 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 | }; | ... | ... |