システム検索の結果を示すbootstrap-vueで生成されたテーブルがあります。
結果テーブルはユーザーにレコードを表示し、ユーザーはそれらをソートしてフィルターすることができます。
テーブルヘッダーの下に検索フィールドを追加するにはどうすればよいですか<th>
bootstrap-vueで生成<b-table>
要素?
top-row
スロットを使用して、独自の最初の行をカスタマイズできます。必要最小限の例については、以下を参照してください...
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>
注::filter
のb-table
プロップの代わりに、計算されたプロパティを使用してアイテムをフィルターしました。カスタムの最初の行を含めます。これにより、結果が空の場合にダミーのデータ行を提供できます。
フィルの答えを賛成し、より一般的なものにします
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;
}, {})
];
}
間違い
const filtered = this.items.filter(item => {
return Object.keys(this.filters).every(key =>
// String(item[key]).includes(this.filters[key]))
return String(item[key]).includes(this.filters[key]))
})
これらの有用な回答をありがとうございます。今日は私の時間の一部を節約できました。ただし、アイテムが非同期で指定されている場合は、このようなアイテムサイズのテストを追加する必要がありました。
filtered() {
if (this.items.length > 0) {
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;
}, {})
];
}
},
一方、フィルターなしの列が必要な場合は、このテストを以下に追加しました
テンプレート内
<td v-for="field in fields" :key="field.key">
<input v-if="fieldIsFiltered(field)" v-model="filters[field.key]" :placeholder="field.label">
</td>
およびコンポーネントメソッド内
fieldIsFiltered(field) {
return Object.keys(this.filters).includes(field.key)
}