Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

UsmanBasharmal's avatar

Laravel Vuejs sorting a table is not working

When you click a column header, why does my sorting not work? What is the solution? I follow this video to create a table https://www.youtube.com/watch?v=PuxibXGHeEo What I am missing I don't know The code is like below

Below is the API response for /api/students before and after sorting in the newtwrok tab in xhr tab name section it shows the below code

students?page=1&paginate=10&q=a&selectedClass=&selectedSection=&sort_direction=desc&sort_field=name

and

students?page=1&paginate=10&q=a&selectedClass=&selectedSection=&sort_direction=asc&sort_field=name

but in the network tab in the preview section, nothing is sorted it stays the same no sorting is applied

Code in the Controller is like below

public function index()
    {
        $paginate = request('paginate', 10);
        $search_term = request('q', '');

        $selectedClass = request('selectedClass');
        $selectedSection = request('selectedSection');

        $sort_direction = request('sort_direction', 'desc');

        if (!in_array($sort_direction, ['asc', 'desc'])) {
            $sort_direction = 'desc';
        }

        $sort_field = request('sort_field', 'created_at');
        if (!in_array($sort_field, ['name', 'email', 'address', 'phone_number', 'created_at'])) {
            $sort_field = 'created_at';
        }

        $students = Student::with(['class', 'section'])
            ->when($selectedClass, function ($query) use ($selectedClass) {
                $query->where('class_id', $selectedClass);
            })
            ->when($selectedSection, function ($query) use ($selectedSection) {
                $query->where('section_id', $selectedSection);
            })

            ->search(trim($search_term))
            ->paginate($paginate);

        return StudentResource::collection($students);

    }

Code in the Vue components is like below

 <template>
    <div>
        <div class="d-flex justify-content-between align-content-center mb-2">


        <div class="card-body table-responsive p-0">
            <table class="table table-hover">
                <tbody>
                    <tr>
                        <th><input type="checkbox" v-model="selectPage" /></th>
                        <th>
                            <a href="#" @click.prevent="change_sort('name')">Student's Name</a>
                            <span v-if="sort_direction == 'desc' && sort_field == 'name'">&uarr;</span>
                            <span v-if="sort_direction == 'asc' && sort_field == 'name'">&darr;</span>
                        </th>
                        <th>
                            <a href="#" @click.prevent="change_sort('email')">Email</a>
                            <span v-if="sort_direction == 'desc' && sort_field == 'email'">&uarr;</span>
                            <span v-if="sort_direction == 'asc' && sort_field == 'email'">&darr;</span>
                        </th>
                        <th>
                            <a href="#" @click.prevent="change_sort('address')">Address</a>
                            <span v-if="sort_direction == 'desc' && sort_field == 'address'">&uarr;</span>
                            <span v-if="sort_direction == 'asc' && sort_field == 'address'">&darr;</span>
                        </th>
                        <th>
                            <a href="#" @click.prevent="change_sort('phone_number')">Phone Number</a>
                            <span v-if="sort_direction == 'desc' && sort_field == 'phone_number'">&uarr;</span>
                            <span v-if="sort_direction == 'asc' && sort_field == 'phone_number'">&darr;</span>
                        </th>
                        <th>
                            <a href="#" @click.prevent="change_sort('created_at')">Created At</a>
                            <span v-if="sort_direction == 'desc' && sort_field == 'created_at'">&uarr;</span>
                            <span v-if="sort_direction == 'asc' && sort_field == 'created_at'">&darr;</span>
                        </th>
                        <th>Class</th>
                        <th>Section</th>
                        <th>Action</th>
                    </tr>

                    <tr v-for="student in students.data" :key="student.id" :class="isChecked(student.id) ? 'table-primary' : ''">
                        <td>
                            <input type="checkbox" :value="student.id" v-model="checked"/>
                        </td>
                        <td>{{ student.name }}</td>
                        <td>{{ student.email }}</td>
                        <td>{{ student.address }}</td>
                        <td>{{ student.phone_number }}</td>
                        <td>{{ student.created_at }}</td>
                        <td>{{ student.class }}</td>
                        <td>{{ student.section }}</td>
                        <td>
                            <button onclick="confirm('Are you sure you wanna delete this Record?') || event.stopImmediatePropagation()" class="btn btn-danger btn-sm" @click="deleteSingleRecord(student.id)">
                                <i class="fa fa-trash" aria-hidden="true"></i>
                            </button>
                        </td>
                    </tr>
                </tbody>
            </table>
        </div>

    </div>
</template>

<script>
export default {
    data() {
        return {
            students: {},
            paginate: 10,
            search: "",
            classes: {},
            selectedClass: "",
            selectedSection: "",
            sections: {},
            checked: [],
            selectPage : false,
            selectAll : false,
            sort_direction : 'desc',
            sort_field: 'created_at',
            url : '',
        };
    },

    watch: {

        checked: function(value){
            this.url = "/api/students/export/" + this.checked;
        }

    },

    methods: {

        change_sort(field){
            if(this.sort_field == field){
                this.sort_direction = this.sort_direction == "asc" ? "desc" : "asc";
            }else{
                this.sort_field = field;
            }
            this.getStudents();
        },
        isChecked(student_id){
            return this.checked.includes(student_id);
        },
        getStudents(page = 1) {
            axios
                .get(
                    "/api/students?page=" +
                        page +
                        "&paginate=" +
                        this.paginate +
                        "&q=" +
                        this.search +
                        "&selectedClass=" +
                        this.selectedClass +
                        "&selectedSection=" +
                        this.selectedSection +
                        "&sort_direction=" +
                        this.sort_direction +
                        "&sort_field=" +
                        this.sort_field
                )
                .then(response => {
                    this.students = response.data;
                });
        }
    },

    mounted() {
        axios.get("/api/classes").then(response => {
            console.log(response);
            this.classes = response.data.data;
        });
        this.getStudents();
    }
};
</script>
0 likes
1 reply
UsmanBasharmal's avatar

my bad I was missing the ->orderBy($sort_field, $sort_direction) in the controller

Please or to participate in this conversation.