VueJs - pagination and filter

I use Vue2.js and Element UI as a framework. I would like to be able to filter a chopped table. To do this, I use the table and filter components, the documentation of which can be found here .

OK position

The table is not chopped. When you select a filter, the loop goes through each row and checks if the column value is equal to the filter.

The situation is not OK

The table is chopped. When you select a filter, the loop goes through each row that is the result of the slice and checks if the column value matches the filter. By doing this, we do not filter the "hidden" values.

I did a bit of https://jsfiddle.net/acm3q6q8/3/ , so it’s easier to understand.

All this makes sense, since I'm not working on whole data, but on a sparse version.

One solution might be to hide the lines, rather than exclude them by cutting the data, but I wonder if there is a better solution?

What i want to achieve

  • Only 2 elements jsfiddle displayed in jsfiddle .
  • Filter the tag to display only those lines whose Office tag

Actual result

The row is not displayed because the row in which the tag was an office was not part of a sliced ​​table.

Expected Result

When filtering, I would like to consider lines that are not necessarily displayed.

Attention!

This should work fine with multiple filters (i.e. I select multiple tags)

EDIT

To the same extent, if you want to sort the name alphabetically, Albert will not be displayed if you displayed only 2 elements.

+5
source share
2 answers

You can handle the filter-change event in the table component (documented here ) and filter / chop yourself.

 var Main = { data() { return { numberItemToShow : 4, tableData: [...], filter: [] } }, computed : { 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 pattern

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

An example .

+2
source

The problem is that slicing is done before filtering. The filter should see the source data, and row counting should be part of the filtering.

Because the filter looks at one line at a time, keeping track of matching lines is a bit tricky. What I did here is a matching row counter, which is reset to zero when the row in question is the first row of data. These are hacks, but it works. There may be a better way; I am not familiar with table widgets.

 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.com/element-ui/lib/theme-default/index.css"); 
 <script src="//unpkg.com/vue/dist/vue.js"></script> <script src="//unpkg.com/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> 
+1
source

Source: https://habr.com/ru/post/1266828/


All Articles