Commit 9ea47cb3d276e779dbc4c88a70ae746b0a1c0d0f

Authored by 梁灏
1 parent c1e965c3

fixed Table multiple head filter & sort bug

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 };