I have a table generated with bootstrap-vue that shows the results of a system search.
The Results Table shows the records to the user, and the user can sort them and filter them.
How can I add the search field underneath the table header <th>
generated with the bootstrap-vue <b-table>
element?
Screenshot of the current table:
Mockup of the wanted table:
BootstrapVue table contents can be filtered. To add built-in filtering features, we can add the filter prop. For example, we can write:
Table | Components | BootstrapVue For displaying tabular data. <b-table> supports pagination, filtering, sorting, custom rendering, events, and asynchronous data. For simple display of tabular data without all the fancy features, BootstrapVue also provides lightweight alternative components <b-table-lite> and <b-table-simple>.
The Results Table shows the records to the user, and the user can sort them and filter them. How can I add the search field underneath the table header <th> generated with the bootstrap-vue <b-table> element?
Inside the component, via the default slot, you can use any or all of the BootstrapVue table helper components: <b-thead>, <b-tfoot>, <b-tbody>, <b-tr>, <b-th>, <b-td>, and the HTML5 elements <caption>, <colgroup> and <col>. Contrary to the component's name, one can create simple or complex table layouts with <b-table-simple>.
You can use the top-row
slot to customise your own first-row. See below for a bare-bones example.
new Vue({
el: '#app',
data: {
filters: {
id: '',
issuedBy: '',
issuedTo: ''
},
items: [{id:1234,issuedBy:'Operator',issuedTo:'abcd-efgh'},{id:5678,issuedBy:'User',issuedTo:'ijkl-mnop'}]
},
computed: {
filtered () {
const filtered = this.items.filter(item => {
return Object.keys(this.filters).every(key =>
String(item[key]).includes(this.filters[key]))
})
return filtered.length > 0 ? filtered : [{
id: '',
issuedBy: '',
issuedTo: ''
}]
}
}
})
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css"/><link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.css"/><script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script><script src="//unpkg.com/babel-polyfill@latest/dist/polyfill.min.js"></script><script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.js"></script>
<div id="app">
<b-table striped show-empty :items="filtered">
<template slot="top-row" slot-scope="{ fields }">
<td v-for="field in fields" :key="field.key">
<input v-model="filters[field.key]" :placeholder="field.label">
</td>
</template>
</b-table>
</div>
Note: I've used a computed property to filter the items instead of the :filter
prop in b-table
because it doesn't render rows if all the items are filtered out, including your custom first-row. This way I can provide a dummy data row if the result is empty.
Have upvoted phil's answer, just making it more generic
filtered() {
const filtered = this.items.filter(item => {
return Object.keys(this.filters).every(key =>
String(item[key]).includes(this.filters[key])
);
});
return filtered.length > 0
? filtered
: [
Object.keys(this.items[0]).reduce(function(obj, value) {
obj[value] = '';
return obj;
}, {})
];
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With