忘れないように記録しとこ

カバの樹

ブラウザバックしてもフィルターもページネーションも維持させる方法

2020年1月30日

ページバックしてもページングとフィルターを維持する

以前、ブラウザバックしてもページネーションが維持される方法を記事にしました。
以下がその記事です。

https://www.kabanoki.net/5881/

 

上記の機能を実装後、クライアントからさらなる要望として、テーブルにフィルター機能をつけて欲しいと言われました。

 

フィルター機能を付ける

というわけで、これまた以前書いた記事でページネーションにフィルターを付ける方法を参考にします。

https://www.kabanoki.net/5823/

 

環境

Vue.js 2.6.1
vuejs-paginate 2.1.0
vue-router 3.1.5

 

導入

完成理想像

ライブラリの呼び出し

まず必要なライブラリを呼び出します。
Bootstrapは完全に管理人の好みです。(そのうちVuetifyも使いたいなあ

<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.css">
<script src="https://unpkg.com/vuejs-paginate@2.1.0"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>

スクリプト

ページネーションにルーティングを設定する方法はこちらで、ページネーションにフィルターを設定する方法はこちらをご確認ください。

今回は、ブラウザバックしてもフィルター結果を維持しなければならないので、それようのルーティングパスを設定します。

ページングフィルターパラメーターをそれぞれ起動時にdataに設定します。
パラメーターがない場合は初期設定を入力します。

const items = [];

for(let i=1; i<=105; i++){
  items.push({
    id: i,
    title: 'item-'+i
  });
}

Vue.component('paginate', VuejsPaginate);
const router = new VueRouter({
  routes: [{
    path: '/pages/:page/:select',
    name: 'page-filter'
  },{
    path: '/pages/:page',
    name: 'page' 
  }]
});

new Vue({
  router,
  data: function(){
    return {
      select: this.$route.params.select ? decodeURI(this.$route.params.select) : '',
      items: items,
      parPage: 10,
      currentPage: this.currentPage = Number(this.$route.params.page) || 1
    }
  },
  methods: {
    clickCallback: function () {
      if(this.select != ''){
        this.$router.push({ 
          name: 'page-filter', 
          params: { 
            page: this.currentPage,
            select: encodeURI(this.select) 
          }
        });
      } else {
        this.$router.push({ 
          name: 'page', 
          params: { 
            page: this.currentPage 
          }
        });
      }     
    }
  },
  computed: {
    getItems: function() {
      let self = this;
      return this.items.filter(function(item){
        return String(item.id).indexOf(self.select) !== -1;
      })
    },
    getLists: function(){
      let current = this.currentPage * this.parPage;
      let start = current - this.parPage;
      return this.getItems.slice(start, current);
    },
    getPageCount: function() {
      return Math.ceil(this.getItems.length / this.parPage);
    }
  },
  watch:{
    select: function(){
      this.currentPage = 1;
      this.clickCallback();
    }
  }
}).$mount('#app');

HTML

リストの出力は<table>で行っています。

<div id="app">
  <h2>page {{currentPage}}</h2>
  <input type="text" v-model="select" placeholder="ID search">
  <table class="table table-bordered">
    <thead>
      <tr>
        <th>ID</th>
        <th>Title</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="item in getLists">
        <td>{{item.id}}</td>
        <td>{{item.title}}</td>
      </tr>
    </tbody>
  </table>
  <paginate
    v-model="currentPage"
    :page-count="getPageCount"
    :initial-page="4"
    :page-range="3"
    :margin-pages="2"
    :click-handler="clickCallback"
    :prev-text="'<'"
    :next-text="'>'"
    :container-class="'pagination'"
    :page-class="'page-item'">
  </paginate>
</div>

 

サンプル

>>専用ページで確認する

 

さいごに

ブラウザバックしてもフィルターもページネーションも維持させる方法でした。

今回はフィルターの値をURLのパラメーターに持たせましたが、これで良いのでしょうか・・・?

一先ず動いた感じなので、記事にしてみました。

 

今日はこの辺でー

  • B!