Membuat Blog dengan Laravel & VueJS - #20 | Paginasi - /allposts

wahyunanangwidodo

wahyunanangwidodo Kamis, 30 Januari 2020

Membuat Blog dengan Laravel & VueJS - #20 | Paginasi

Sebelumnya kita telah mengerjakan beberapa bagian yang kita buat pada halaman homepage, dan terakhir kita membuat untuk bagian sidebar, lalu untuk part ini kita akan kembali dulu ke bagian admin untuk membuat paginasi.

PostController.php

Langkah pertama mari kita buka Postcontroller.php dan pada method index kita tambahkan paginasi dan kita buat json.
//PostController.php
public function index()
{
  $posts = Post::with('category')->latest()->paginate(2); 
  $response = [
    'pagination' => [
    'total' => $posts->total(),
    'per_page' => $posts->perPage(),
    'current_page' => $posts->currentPage(),
    'last_page' => $posts->lastPage(),
    'from' => $posts->firstItem(),
    'to' => $posts->lastItem()
    ],
    'data' => $posts
  ];
  return response()->json($response);
}

Membuat Komponen

Selanjutnya mari kita buat komponen baru pada direktori components dengan nama Pagination.vue dan silahkan copas template dibawah ini.
//Pagination.vue
<template>
    <nav class="pagination is-centered" role="navigation" aria-label="pagination">
      <a class="pagination-previous" @click.prevent="changePage(1)" :disabled="pagination.current_page <= 1"> <i class="fa fa-angle-double-left"></i> </a>
      <a class="pagination-previous" @click.prevent="changePage(pagination.current_page - 1)" :disabled="pagination.current_page <= 1"> <i class="fa fa-angle-left"></i> </a>
      <a class="pagination-next" @click.prevent="changePage(pagination.current_page + 1)" :disabled="pagination.current_page >= pagination.last_page"> <i class="fa fa-angle-right"></i> </a>
      <a class="pagination-next" @click.prevent="changePage(pagination.last_page)" :disabled="pagination.current_page >= pagination.last_page"> <i class="fa fa-angle-double-right"></i> </a>
      <ul class="pagination-list">
        <li v-for="page in pages">
          <a class="pagination-link" :class="isCurrentPage(page) ? 'is-current' : ''" @click.prevent="changePage(page)">{{ page }}</a>
        </li>
      </ul>
    </nav>
</template>

<script>
    export default {
        props: ['pagination', 'offset'],

        methods: {
            isCurrentPage(page) {
                return this.pagination.current_page === page;
            },

            changePage(page) {
                if (page > this.pagination.last_page) {
                    page = this.pagination.last_page;
                }

                this.pagination.current_page = page;
                this.$emit('paginate');
            }
        },

        computed: {
            pages() {
                let pages = [];

                let from = this.pagination.current_page - Math.floor(this.offset / 2);

                if (from < 1) {
                    from = 1;
                }

                let to = from + this.offset - 1;

                if (to > this.pagination.last_page) {
                    to = this.pagination.last_page;
                }

                while (from <= to) {
                    pages.push(from);
                    from++;
                }

                return pages;
            }
        }
    }
</script>
Lalu buka file index.blade.php pada direktori views/admin dan tambahkan link css berikut:
//index.blade.php

<!-- Styles -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.5/css/bulma.min.css">
Kita menggunakan css bulma dalam style paginasi. Ada beberapa pilihan syle paginasi yang dapat kita pilih, silahkan klik disini untuk melihatnya.

Import Komponen

Setelah langkah diatas dikerjakan, selanjutnya kita akan mengimport komponen telah kita buat.

Namun disini sedikit berbeda dimana kita tidak mengimportnya di file entry pointnya / app.js, akan tetapi kita akan import di dalam komponen lain, yaitu komponen AllPosts.vue.

Mari kita buka komponen AllPosts.vue untuk kita import serta membuat fungsi lainnya.
//AllPosts.vue

<!-- Kita lakukan import-->
import pagination from './Pagination.vue';

<!-- buat properti pada instance-->
components: {
   pagination
},

<!-- menambahkan data properti-->
data:function() {
  return {
   posts: [],
    successful: false,
      pagination: {
       'current_page': 1
    },
  }
},

<!-- menambahkan parameter-->
getPosts() {
  axios.get('/api/posts?page=' + this.pagination.current_page)
  // axios.get('/api/posts')
  .then(response => {
  // console.log(response.data.data);
     this.posts = response.data.data.data;  
     this.pagination = response.data.pagination;
  })
  .catch(error => {
    //
  });
},


<!-- rendering komponen-->
<pagination v-if="pagination.last_page > 1" :pagination="pagination" :offset="5" @paginate="getPosts()"></pagination>

Hasil akhir komponen AllPosts.vue:
//AllPosts.vue
<template>
<div>
  <div class="_container">
    <div class="admin-page-title">All Posts</div> 
      <span v-if="successful" class="label label-danger"><h4>deleted!</h4><p>(Pos berhasil dihapus.)</p></span>
      <div class="h_wrap">
        <table class="table table-bordered">
          <thead class="thead-dark">
            <tr>
              <th>Title</th>
              <th>Image</th>
              <th>Categories</th>
              <th>Actions</th>
            </tr>
          </thead>
          <tbody v-for="post in posts">
            <tr >
              <td style="width:500px"><h5>{{ post.title }}</h5></td>
              <td style="width:100px"><img :src="'/images/' + post.image"/></td>
              <td>{{ post.category.name }}</td>
              <td> 
              <router-link :to="{ name: 'editpost', params: { postId : post.id } }">
                <button type="button" class="btn btn-primary">Edit</button>
              </router-link>
              <button type="button" v-on:click="deletePost(post.id)" class="btn btn-danger">Delete</button>
              </td>
            </tr>
          </tbody>
        </table>   
          <pagination v-if="pagination.last_page > 1" :pagination="pagination" :offset="5" @paginate="getPosts()"></pagination>
      </div>
    </div>
  </div>
</div> 
</template>

<script>
import pagination from './Pagination.vue';

  export default {
    components: {
      pagination
    },

    data:function() {
      return {
        posts: [],
        successful: false,
          pagination: {
            'current_page': 1
        },

      }
    },
    created: function () {
      this.getPosts();
    },
    methods: {
      getPosts() {
        axios.get('/api/posts?page=' + this.pagination.current_page)
        // axios.get('/api/posts')
          .then(response => {
              // console.log(response.data.data);
              this.posts = response.data.data.data;  
              this.pagination = response.data.pagination;
          })
          .catch(error => {
              // console.log(error.response.data.data);
          });
        },
        deletePost(id) {
          axios.delete("/api/posts/" + id)
          .then(response => {
            this.getPosts();
            this.successful = true;
            console.log('deleted!');
          });
        } 
      }
  };
</script>

<style scoped>
  .table-bordered{
    background-color: #ffffff;
  }
  .label-danger {
    color: #f1f1f1;
    display: inline-block;
    margin-bottom: 17px;
    background: #dc3545eb;
    width: 100%;
    padding: 5px 15px;
  } 
  .label-danger h4, .label-danger p{
    margin-bottom: 0;
  }
</style>
Jika tidak ada kesalahan maka terlihat seperti gambar dibawah ini:

Membuat Blog dengan Laravel & VueJS - #20 | Paginasi

Pada gambar diatas dari 3 pos ditampilkan 2 perhalaman, jadi terbuat 2 link/nomor paginasi.

Urutan part / bagian dari tutorial ini bisa dilihat disini.

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel

Berlangganan

Berlangganan untuk mendapat pemberitahuan artikel terbaru via email.