1

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

Here is the short code, only the sorting part

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;
            }

Full 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;
            }
        }

    });

1 Answer 1

2

the last parameter of orderBy should be 1 or -1, while you provide either true or false with the value of reverse

https://jsfiddle.net/Linusborg/spwwxLvy/

change this:

this.reverse = (this.sortKey == sortKey) ? ! this.reverse : false;

to this:

this.reverse = (this.sortKey == sortKey) ? 1 : -1;

also change the initial value in data() accordingly.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for your reply. Where should I add, 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; }
of course it is working. Change the value of direction to 1 (and click 'Run' in the upper left) to sort ascending, then change it to -1 and it will sort in reverse. But when it's false, it will not work.
Thank you. I have edited but it is sorting only one time. When I click again it won't work. At present data(reverse: false).
I have found sorting feature in vue js website "vuejs.org/examples/grid-component.html". But I have not too much experience in vue js to merge this sorting feature with my code. If it possible could you please help me for merging this code?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.