Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(table): Emit event when local filtering changes number of result items - issue #650 #652

Merged
merged 12 commits into from
Jul 6, 2017
70 changes: 39 additions & 31 deletions docs/components/table/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
</div>
</div>

<div class="justify-content-center my-1">
<b-pagination size="md" :total-rows="items.length" :per-page="perPage" v-model="currentPage" />
<div class="justify-content-center row my-1">
<b-pagination size="md" :total-rows="totalRows" :per-page="perPage" v-model="currentPage" />
</div>

<!-- Main table element -->
Expand All @@ -30,6 +30,7 @@
:current-page="currentPage"
:per-page="perPage"
:filter="filter"
@repaginate="repaginate"
>
<template slot="name" scope="item">
{{item.value.first}} {{item.value.last}}
Expand All @@ -46,37 +47,40 @@
</template>

<script>
const items = [
{
isActive: true, age: 40, name: { first: 'Dickerson', last: 'Macdonald' }
}, {
isActive: false, age: 21, name: { first: 'Larsen', last: 'Shaw' }
}, {
_rowVariant: 'success',
isActive: false, age: 9, name: { first: 'Mitzi', last: 'Navarro' }
}, {
isActive: false, age: 89, name: { first: 'Geneva', last: 'Wilson' }
}, {
isActive: true, age: 38, name: { first: 'Jami', last: 'Carney' }
}, {
isActive: false, age: 27, name: { first: 'Essie', last: 'Dunlap' }
}, {
isActive: true, age: 40, name: { first: 'Dickerson', last: 'Macdonald' }
}, {
_cellVariants: { age: 'danger', isActive: 'warning' },
isActive: true, age: 87, name: { first: 'Larsen', last: 'Shaw' }
}, {
isActive: false, age: 26, name: { first: 'Mitzi', last: 'Navarro' }
}, {
isActive: false, age: 22, name: { first: 'Geneva', last: 'Wilson' }
}, {
isActive: true, age: 38, name: { first: 'Jami', last: 'Carney' }
}, {
isActive: false, age: 27, name: { first: 'Essie', last: 'Dunlap' }
}
];

export default {
data: {
items: [
{
isActive: true, age: 40, name: { first: 'Dickerson', last: 'Macdonald' }
}, {
isActive: false, age: 21, name: { first: 'Larsen', last: 'Shaw' }
}, {
_rowVariant: 'success',
isActive: false, age: 9, name: { first: 'Mitzi', last: 'Navarro' }
}, {
isActive: false, age: 89, name: { first: 'Geneva', last: 'Wilson' }
}, {
isActive: true, age: 38, name: { first: 'Jami', last: 'Carney' }
}, {
isActive: false, age: 27, name: { first: 'Essie', last: 'Dunlap' }
}, {
isActive: true, age: 40, name: { first: 'Dickerson', last: 'Macdonald' }
}, {
_cellVariants: { age: 'danger', name: 'success' },
isActive: false, age: 21, name: { first: 'Larsen', last: 'Shaw' }
}, {
isActive: false, age: 26, name: { first: 'Mitzi', last: 'Navarro' }
}, {
isActive: false, age: 22, name: { first: 'Geneva', last: 'Wilson' }
}, {
isActive: true, age: 38, name: { first: 'Jami', last: 'Carney' }
}, {
isActive: false, age: 27, name: { first: 'Essie', last: 'Dunlap' }
}
],
items: items,
totalRows: items.length,
fields: {
name: {
label: 'Person Full name',
Expand All @@ -100,6 +104,10 @@ export default {
methods: {
details(item) {
alert(JSON.stringify(item));
},
repaginate(filteredRows) {
// Trigger pagination to update the number of buttons/pages due to filtering
this.totalRows = filteredRows;
}
}
}
Expand Down
10 changes: 10 additions & 0 deletions docs/components/table/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,16 @@
}
]
},
{
"event": "repaginate",
"description": "Emitted when local fitering causes a change in the total number of pages.",
"args": [
{
"arg": "filteredRows",
"description": "Total number of data rows after filtering (before pagination)."
}
]
},
{
"event": "refreshed",
"description": "Emitted when the items provider function has returned data."
Expand Down
30 changes: 29 additions & 1 deletion lib/components/table.vue
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@
}
};

const calcNumPages = (rows, perPage) => {
const result = Math.ceil(rows / perPage);
return (result < 1) ? 1 : result;
};

export default {
data() {
return {
Expand All @@ -137,7 +142,7 @@
default() {
if (this && this.itemsProvider) {
// Deprecate itemsProvider
warn('b-table: prop items-provider has been deprecated. Pass a function to items instead');
warn("b-table: prop 'items-provider' has been deprecated. Pass a function to 'items' instead");
return this.itemsProvider;
}
return [];
Expand Down Expand Up @@ -344,8 +349,18 @@
return [];
}

// Shallow copy of items, so we don't mutate the original array order/size
items = items.slice();

// Number of pages before filtering
let numOriginalPages = calcNumPages(items.length, perPage);

// Number of pages after filtering (recalculated once filtering completes)
let numFilteredPages = numOriginalPages;

// Number of Items after filtering (recalculated after filtering completes)
let numFilteredItems = items.length;

// Apply local filter
if (filter && !this.providerFiltering) {
if (filter instanceof Function) {
Expand All @@ -363,6 +378,12 @@
return test;
});
}

// Recalculate the number of items after filtering
numFilteredItems = items.length;

// Calculate number of pages after filtering
numFilteredPages = calcNumPages(numFilteredItems, perPage);
}

// Apply local Sort
Expand All @@ -375,11 +396,18 @@

// Apply local pagination
if (perPage && !this.providerPaging) {
// Grab the current page of data (which may be past filtered items)
items = items.slice((currentPage - 1) * perPage, currentPage * perPage);
}

// Update the value model with the filtered/sorted/paginated data set
this.$emit('input', items);

if (numOriginalPages !== numFilteredPages) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe move this to watcher?
some as

    numFilteredItems(newVal, oldVal) {
        if (newVal !== oldVal)
            this.$emit('repaginate', newVal);
    }

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm that might be an idea, but I would have to make a few more data props to keep state while it is calculating it, since the only pace these values are available is in the _items computed prop.

// Emit a repaginate notification event, as number of pages has changed
this.$emit('repaginate', numFilteredItems);
}

return items;
}
},
Expand Down