sarathiscookie's avatar

Vue js sorting is not working

Currently this is for listing customer data from database. Data is fetching using Laravel 5. At present data is fetching and listing properly. This page contains pagination, filter search and sorting functionality. My problem is sorting is not working properly. Could you please help me to sort out this issue? I am using Vue js version 1.0.25.

I have found a sorting feature in vue js website 'https://vuejs.org/examples/grid-component.html'. I have not too much experience in Vue js side for merging this sorting feature with my code. Please help me to merge this sorting feature in my code. I think it is easier than solving my current code issue.

My purpose is, In a listing page I need sorting feature and pagination feature. Please help.

Here is the short code

View
<th v-for="key in columns" @click="sortBy(key)" :class="{active: sortKey == key}">
                            @{{ colTitles[key] }}
 </th>
<tr v-for="(index, item) in items | filterBy searchQuery | orderBy sortKey reverse">
........

JS
data: {
            sortKey: '',
            reverse: false,
.........
sortBy: function(sortKey) {
                this.reverse = (this.sortKey == sortKey) ? ! this.reverse : false;

                this.sortKey = sortKey;
            }

##Complete code

##dashboard.blade.php

<div class="container">
        <div class="row">
            <h1 class="page-header">{{ trans('messages.customerListPageHeadingLabel') }}</h1>
            <div id="app">
                <div class="form-group col-md-4">
                    <form id="search" class="form-inline">
                        <label for="query">{{ trans('messages.customerListPageSearchBox') }} </label>
                        <input name="query" class="form-control" v-model="searchQuery">
                    </form>
                </div>
                <br>
                <table class="table table-hover table-bordered">
                    <thead>
                    <tr>
                        <th v-for="column in columns" @click="sortBy(column)">
                            @{{ colTitles[column] }}
                        </th>
                    </tr>
                    </thead>
                    <tbody>
                    <tr v-for="(index, item) in items | filterBy searchQuery | orderBy sortKey reverse">
                        <td>@{{ item.erp_id }}</td>
                        <td>@{{item.firstname}}</td>
                        <td><a href="{{ url('/customer/details/') }}/@{{ item.id }}">@{{item.lastname}}</a></td>
                        <td>@{{item.email}}</td>
                        <td>@{{item.phone_1}}</td>
                        <td>@{{item.status}}</td>
                        <td>@{{item.created_on}}</td>
                    </tr>
                    </tbody>
                </table>
                <nav>
                    <ul class="pagination">
                        <li v-if="pagination.current_page > 1">
                            <a href="#" aria-label="Previous"
                               @click.prevent="changePage(pagination.current_page - 1)">
                                <span aria-hidden="true">«</span>
                            </a>
                        </li>
                        <li v-for="page in pagesNumber"
                            v-bind:class="[ page == isActived ? 'active' : '']">
                            <a href="#"
                               @click.prevent="changePage(page)">@{{ page }}</a>
                        </li>
                        <li v-if="pagination.current_page < pagination.last_page">
                            <a href="#" aria-label="Next"
                               @click.prevent="changePage(pagination.current_page + 1)">
                                <span aria-hidden="true">»</span>
                            </a>
                        </li>
                    </ul>
                </nav>
            </div>
        </div>
    </div>

##Laravel Controller

public function listCustomers()
    {
        $results =  Customer::select('id', 'erp_id', 'firstname', 'lastname', 'email', 'phone_1', 'status', DB::raw("DATE_FORMAT(created_at, '%d.%m.%Y %H:%i') AS created_on"))
            ->orderBy('id', 'desc')->latest()->paginate(25);

        $response = [
            'pagination' => [
                'total' => $results->total(),
                'per_page' => $results->perPage(),
                'current_page' => $results->currentPage(),
                'last_page' => $results->lastPage(),
                'from' => $results->firstItem(),
                'to' => $results->lastItem()
            ],
            'data' => $results
        ];

        return $response;
    }

##Vue JS

new Vue({
        el: '#app',

        data: {
            sortKey: '',

            reverse: false,

            columns: ['erp_id', 'firstname', 'lastname', 'email', 'phone_1', 'status', 'created_on'],

            colTitles: {'erp_id':'@lang('messages.customerListPageTableCustomerNo')', 'firstname':'@lang('messages.customerListPageTableFirstname')', 'lastname':'@lang('messages.customerListPageTableLastname')', 'email':'E-Mail', 'phone_1':'@lang('messages.customerListPageTablePhone')', 'status':'Status', 'created_on':'@lang('messages.customerListPageTableAddedDate')'},

            pagination: {
                total: 0,
                per_page: 7,
                from: 1,
                to: 0,
                current_page: 1
            },

            offset: 4,// left and right padding from the pagination <span>,just change it to see effects

            items: []
        },

        ready: function () {
            this.fetchItems(this.pagination.current_page);
        },

        computed: {
            isActived: function () {
                return this.pagination.current_page;
            },
            pagesNumber: function () {
                if (!this.pagination.to) {
                    return [];
                }
                var from = this.pagination.current_page - this.offset;
                if (from < 1) {
                    from = 1;
                }
                var to = from + (this.offset * 2);
                if (to >= this.pagination.last_page) {
                    to = this.pagination.last_page;
                }
                var pagesArray = [];
                while (from <= to) {
                    pagesArray.push(from);
                    from++;
                }

                return pagesArray;
            }
        },

        methods: {
            fetchItems: function (page) {
                var data = {page: page};
                this.$http.get('/list/customers', data).then(function (response) {
                    //look into the routes file and format your response
                    this.$set('items', response.data.data.data);
                    this.$set('pagination', response.data.pagination);
                }, function (error) {
                    // handle error
                });
            },
            changePage: function (page) {
                this.pagination.current_page = page;
                this.fetchItems(page);
            },
            sortBy: function(sortKey) {
                this.reverse = (this.sortKey == sortKey) ? ! this.reverse : false;

                this.sortKey = sortKey;
            }
        }

    });
0 likes
0 replies

Please or to participate in this conversation.