depsimon's avatar

Vue and Laravel Pagination

Hey guys,

I have these Pages that I can manage in my back-end. So I made a template with the paginated Pages using Laravel Pagination. It all worked fine, but I wanted to manage that view with Vue.js

Here's how I implemented this, the difficulty was to rebuild the pagination links. In my case I wanted it like this : "< 1 2 ... 4 5 6 ... 9 10 >" (pretty much like the default pagination in laravel 5.2, but instead of having 3 links on each side of the current page I set it up to 1)

My Controller :

// PagesController.php

use App\Models\Pagination\PaginationPresenter;

public function index(Request $request)
{
    $pages = Page:paginate(10);

    if ($request->wantsJson()) {
        $pagination = $pages->toArray();
        $pagination['paginationHtml'] = (new PaginationPresenter($pages))->render()->toHtml();

        return response()->json($pagination);
    } else {
        return view('admin.pages.index')->with(compact('pages'));
    }
}

My view (admin/pages/index.blade.php

<div id="pagination-app">
{!! (new App\Models\Presenters\PaginationPresenter($pages))->render() !!}

<table class="table table-hover">
    <thead>
        <tr>
            <th>Title</th>
            <th>Status</th>
            <th>Last Edit</th>
        </tr>
    </thead>
    <tbody>
        <tr v-for="page in pagination.data">
            <td><a href="#">@{{ page.title }}</a></td>
            <td>@{{ page.status }}</td>
            <td>@{{ page.updated_at }}</td>
        </tr>
    </tbody>
</table>
</div>

My Vue configuration

    // later in the view

    var paginationApp = new Vue({
        el: "#pagination-app",
        data: {
            pagination: {!! $pages->toJson() !!},
        },
        methods: {
            fetchPage: function(page) {
                this.$http.get(page).then(function(response) {
                    this.pagination = response.data;
                    this.updatePagination();
                }, function(response) {
                    // handle error
                });
            },
            updatePagination: function() {
                var $element = $(this.pagination.paginationHtml);
                this.$compile($element.get(0));
                $(this.$el).find('.pagination').replaceWith($element);
            }
        }
    });

And my custom Pagination Presenter

// app/Models/Presenters/PaginationPresenter.php

protected function getAvailablePageWrapper($url, $page, $rel = null)
{
    $rel = is_null($rel) ? '' : ' rel="'.$rel.'"';

    return '<li><a href="#" @click="fetchPage(\''. $url .'\')"'.$rel.'>'.$page.'</a></li>';
}

It all works as I want, but it bugs me that I have to add the paginationHtml to the pagination in my controller. Is there something I could do better ?

0 likes
0 replies

Please or to participate in this conversation.