admin管理员组文章数量:1312778
I'm using Vue2.js
and Element UI
as a framework. I would like to be able to filter a table which is sliced. To do so, I use the table
and filter
ponents whose documentation could be found here.
Situation OK
The table is not sliced. When you picked a filter, a loop goes trough each row and check if the value of the column is equal to the filter.
Situation NOT OK
The table is sliced. When you picked a filter, a loop goes trough each row that results of the slice and check if the value of the column is equal to the filter. By doing that we don't filter the "hidden" values.
I've made a little / so it is easier to understand.
All of this make sense since I'm not working on the whole data, but on a sliced version.
One solution could be to hide rows instead of excluding them by slicing the data, but I'm wondering if there is a better solution ?
What I want to achieve
- In the
jsfiddle
, display only 2 items. - Filter the
tag
to display only rows whose tag isOffice
Actual result
There is no row displayed since the row whose tag
was office was not part of the sliced table.
Expected result
When filtering, I would like to take into account rows that are not necessarily displayed.
Important
This should work fine with a multiple filter (ie I select several tags)
EDIT
In the same extent if you want to sort the name by alphabetical order, Albert won't be displayed if you displayed only 2 items.
I'm using Vue2.js
and Element UI
as a framework. I would like to be able to filter a table which is sliced. To do so, I use the table
and filter
ponents whose documentation could be found here.
Situation OK
The table is not sliced. When you picked a filter, a loop goes trough each row and check if the value of the column is equal to the filter.
Situation NOT OK
The table is sliced. When you picked a filter, a loop goes trough each row that results of the slice and check if the value of the column is equal to the filter. By doing that we don't filter the "hidden" values.
I've made a little https://jsfiddle/acm3q6q8/3/ so it is easier to understand.
All of this make sense since I'm not working on the whole data, but on a sliced version.
One solution could be to hide rows instead of excluding them by slicing the data, but I'm wondering if there is a better solution ?
What I want to achieve
- In the
jsfiddle
, display only 2 items. - Filter the
tag
to display only rows whose tag isOffice
Actual result
There is no row displayed since the row whose tag
was office was not part of the sliced table.
Expected result
When filtering, I would like to take into account rows that are not necessarily displayed.
Important
This should work fine with a multiple filter (ie I select several tags)
EDIT
In the same extent if you want to sort the name by alphabetical order, Albert won't be displayed if you displayed only 2 items.
Share Improve this question edited Jun 20, 2020 at 9:12 CommunityBot 11 silver badge asked Apr 17, 2017 at 18:15 Léo CocoLéo Coco 4,28211 gold badges59 silver badges100 bronze badges 11- The tag filter doesn't appear to work on that fiddle. – Bert Commented Apr 17, 2017 at 18:32
- Yes it does. If you have all items displayed everything's fine. As soon as you start to slice the table, it filters only on the sliced table and not the whole one. – Léo Coco Commented Apr 17, 2017 at 18:34
-
I mean, when I pick a tag, nothing happens.
filterTag
is never called. – Bert Commented Apr 17, 2017 at 18:35 -
It does work on my side. I added a
console.log
infilterTag
. Could you check again ? – Léo Coco Commented Apr 17, 2017 at 18:38 -
1
Tag is fine, you should just
Confirm
"Office" selection in order to filter rows (click left chineese word under tag selection). – Egor Stambakio Commented Apr 17, 2017 at 18:38
2 Answers
Reset to default 2You can handle the filter-change
event on the table ponent (documented here), and filter/slice yourself.
var Main = {
data() {
return {
numberItemToShow : 4,
tableData: [...],
filter: []
}
},
puted : {
filterData() {
if (!this.filter.length)
return this.tableData.slice(0, this.numberItemToShow)
else
return this.tableData
.filter(row => this.filter.includes(row.tag))
.slice(0, this.numberItemToShow);
}
},
methods: {
onFilterChange(filters){
if (filters.tag)
this.filter = filters.tag;
}
}
}
And the template
<template>
<input v-model="numberItemToShow" placeholder="edit me">
<p>Number of item to display: {{ numberItemToShow }}</p>
<el-table ref="tab" :data="filterData" border style="width: 100%" @filter-change="onFilterChange">
<el-table-column prop="name" label="Name" sortable>
</el-table-column>
<el-table-column prop="tag" label="Tag" column-key="tag" :filters="[{ text: 'Home', value: 'Home' }, { text: 'Office', value: 'Office' }]">
<template scope="scope">
<el-tag :type="scope.row.tag === 'Home' ? 'primary' : 'success'" close-transition>{{scope.row.tag}}</el-tag>
</template>
</el-table-column>
</el-table>
</template>
Example.
The problem is that the slicing is done before the filtering. The filter has to see the original data, and the row-counting must be part of the filtering.
Since the filter looks at one row at a time, keeping track of the matched rows is a little tricky. What I did here is keep a counter of matched rows that resets to zero when the row being looked at is the first row of data. This is hacky, but it works. There may be a better way; I am not familiar with the table widget.
var Main = {
data() {
return {
numberItemToShow : 4,
tableData: [{
name: 'One',
tag: 'Home'
}, {
name: 'Two',
tag: 'Home'
}, {
name: 'Three',
tag: 'Home'
}, {
name: 'Four',
tag: 'Office'
}],
scratchCounter: 0
}
},
methods: {
filterTag(value, row) {
const matched = row.tag === value;
if (row === this.tableData[0]) {
this.scratchCounter = 0;
}
if (matched) {
++this.scratchCounter;
}
return this.scratchCounter <= this.numberItemToShow && matched;
}
}
}
var Ctor = Vue.extend(Main)
new Ctor().$mount('#app')
@import url("//unpkg./element-ui/lib/theme-default/index.css");
<script src="//unpkg./vue/dist/vue.js"></script>
<script src="//unpkg./element-ui/lib/index.js"></script>
<div id="app">
<template>
<input v-model="numberItemToShow" placeholder="edit me">
<p>Number of item to display: {{ numberItemToShow }}</p>
<el-table :data="tableData" border style="width: 100%">
<el-table-column prop="name" label="Name">
</el-table-column>
<el-table-column prop="tag" label="Tag" :filters="[{ text: 'Home', value: 'Home' }, { text: 'Office', value: 'Office' }]" :filter-method="filterTag">
<template scope="scope">
<el-tag :type="scope.row.tag === 'Home' ? 'primary' : 'success'" close-transition>{{scope.row.tag}}</el-tag>
</template>
</el-table-column>
</el-table>
</template>
</div>
本文标签: javascriptVueJsTable pagination and filterStack Overflow
版权声明:本文标题:javascript - VueJs - Table pagination and filter - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741900612a2403846.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论