web-dev-qa-db-ja.com

ヘッダーにフィルターがあるBootstrap-vue Bテーブル

システム検索の結果を示すbootstrap-vueで生成されたテーブルがあります。

結果テーブルはユーザーにレコードを表示し、ユーザーはそれらをソートしてフィルターすることができます。

テーブルヘッダーの下に検索フィールドを追加するにはどうすればよいですか<th> bootstrap-vueで生成<b-table>要素?

現在のテーブルのスクリーンショットenter image description here

必要なテーブルのモックアップMockup of the wanted table

5
Adriano

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>

注::filterb-tableプロップの代わりに、計算されたプロパティを使用してアイテムをフィルターしました。カスタムの最初の行を含めます。これにより、結果が空の場合にダミーのデータ行を提供できます。

5
Phil

フィルの答えを賛成し、より一般的なものにします

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;
            }, {})
          ];
    }
1
Abhishek

間違い

      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]))
      })
0

これらの有用な回答をありがとうございます。今日は私の時間の一部を節約できました。ただし、アイテムが非同期で指定されている場合は、このようなアイテムサイズのテストを追加する必要がありました。

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)
            }
0
bdamay