Having trouble reverting the table to its original order by clicking the column in Vue.js

Transitioning from Laravel Livewire to Laravel Vue has presented a challenge in recreating the necessary sorting logic in Vue. I've managed to implement basic table sorting by clicking on the table headers. However, I now need help with achieving a feature where clicking on a column header after it has been sorted in descending order ('desc') will revert it back to its original unsorted state, similar to the behavior in the Livewire Component example below. Any assistance in implementing this functionality in Vue would be greatly appreciated.

User Index Vue Component - Current Behavior

https://i.sstatic.net/o5gD7.gif

User Index Livewire Component - Required Behavior

https://i.sstatic.net/mMKUv.gif

User Index Vue Component - Script

<script>
    export default {
        props : ['users'],
        data() {
            return {
                sortField: '',
                sortDirection: 'asc'
            }
        },
        methods: {
            sortBy: function(column) {
                if (column === this.sortField) {
                    this.sortDirection = this.sortDirection === 'asc' ? 'desc' : 'asc';
                } else this.sortDirection = 'asc';
                this.sortField = column;
            }
        },
        computed:{
            sortedUsers: function() {
                return this.users.sort((a, b) => {
                    let modifier = 1;
                    if (this.sortDirection === 'desc') modifier = -1;
                    if (a[this.sortField] < b[this.sortField]) return -1 * modifier; 
                    if (a[this.sortField] > b[this.sortField]) return 1 * modifier;
                    return 0;
                });
            }
        }
    }
</script>

User Index Vue Component - Template

<template #head>
    <data-table-heading sortable :direction="sortField === 'id' ? sortDirection : null" @click="sortBy('id')" class="pr-0">ID</data-table-heading>
    <data-table-heading sortable :direction="sortField === 'name' ? sortDirection : null" @click="sortBy('name')">Name</data-table-heading>
    <data-table-heading sortable :direction="sortField === 'email' ? sortDirection : null" @click="sortBy('email')" class="w-screen">Email</data-table-heading>
    <data-table-heading sortable :direction="sortField === 'role' ? sortDirection : null" @click="sortBy('role')">Role</data-table-heading>
    <data-table-heading sortable :direction="sortField === 'created_at' ? sortDirection : null" @click="sortBy('created_at')">Date</data-table-heading>
</template>

Data Table Heading Vue Component - Template

<span class="relative flex items-center">
    <div v-if="direction === 'asc'">
        <svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
        </svg>
    </div>
    <div v-else-if="direction === 'desc'">
        <svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 15l7-7 7 7"></path>
        </svg>
    </div>
    <div v-else>
        <svg class="w-3 h-3 opacity-0 group-hover:opacity-100 transition-opacity duration-300" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 15l7-7 7 7"></path>
        </svg>
    </div>
</span>

Edit

Livewire Component Sorting

public $sorts = [];

public function sortBy($field)
{
    if (! isset($this->sorts[$field])) return $this->sorts[$field] = 'asc';

    if ($this->sorts[$field] === 'asc') return $this->sorts[$field] = 'desc';

    unset($this->sorts[$field]);
}

Answer №1

After reviewing the logic presented, it became apparent that there were issues with updating the state of sortDirection due to not resetting it properly.

In order to reset the sortDirection back to its original state, you can utilize the following code snippet:

sortBy: function(column) {
                if (column === this.sortField) {
                    this.sortDirection = this.sortDirection === 'asc' ? 'desc' : this.sortDirection == '' ? 'asc' : '';
                } else this.sortDirection = 'asc';
                this.sortField = column;
            }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is there a way to generate and transmit a text file using XmlHttpRequest or $.ajax?

The server is anticipating an html or txt file to be sent from a form named "websitetopdf". The file is dynamically created on client javascript and should only function properly on Chrome. Below is the form that needs to be used for sending: <form ac ...

Node.js Sparse Array Memory Usage Explained

I created a program that generates arrays and noticed an interesting behavior: var results = []; var i = 1; while (true) { console.log(i++); results.push([]); } However, when I modify the program to create sparse arrays instead of empty ones, it cra ...

Is there a way to transform a JavaScript array into JSON format in order to use it as the returned data from a RESTful API

Currently, I am exploring how to efficiently convert an array of arrays into a JSON string for retrieval through a RESTful API. On my server, data is fetched from a database in the format: {"user":"some name","age":number ...

Is there a way to invoke a JavaScript function specifically for a given link?

I am trying to make the JavaScript only apply to a specific A LINK (#tornado,_bar -> ul -> li -> a links) when clicked, but it is applying to all A links. How can I specify the particular link in the JS? The JavaScript code is not functioning cor ...

Is there a way to ensure that a "loop once" animated GIF background will replay on each page refresh or load?

I currently have an animated GIF file set as the background image for my div, which was specifically configured in Photoshop to loop only once. Therefore, it only plays on the initial page load. Is there a way to reset the background image upon page refre ...

What's the best way to showcase the time on the x-axis of a Flot line graph?

My goal is to display time intervals between the minimum and maximum values within a specific time range. For example: 2015-04-30 10:20:00 and 2015-04-30 10:30:00 on the x-axis. I need to fetch values from a database where the datetime is stored in the fo ...

Using JavaScript within PHP Functions

My JavaScript function works like this: $.msgBox({ title:"msgbox", content:"whatever" }); I am trying to use it inside a PHP Function. This is what I attempted: function MsgBox(){ echo'<script type="text/javascript ...

JavaScript: Implementing Array Declarations within Objects Using Loops

I'm currently in the process of developing a Pixel RPG game, and I'm facing a bit of confusion. Here's what I am trying to accomplish: var mainCharacter = { gender: "male", age: 18, action: "walking", direction: "left", ...

Using JQuery with special characters in attributes

Within my jQuery script, I am required to dynamically translate certain content. As a part of this function, I have the following code: $('#password').attr('placeholder', 'Contrase&ntilde;a'); In this code snippet, I att ...

How to Add Styling to Your Nuxt Project

I have been encountering an issue with adding styling to the body tag in Nuxt. The default.vue file seems to be overriding my CSS changes, even though I have specified styles for the body tag. This behavior was not present when I was working on a pure HTML ...

Adding Information to Flot

I'm struggling to showcase an array of data using a Flot graph. My method involves jQuery Ajax/PHP/MySQL. I created the array with this PHP/MySQL code: $result = mysql_query("SELECT * FROM happiness"); $array = array(); while($row = mysql_fetc ...

Is it possible to incorporate an editable text feature within react-moveable? (Allowing for both dragging and editing capabilities)

In React Movable box, the text can be dragged with a left click and edited with a right click using the "contentEditable" attribute. However, on smartphones, editing seems to be disabled and only dragging is possible. <div className="move ...

Assign position values to an element inside a DIV container using JavaScript, Cascading Style Sheets, and

I am currently creating some visual representations of journal issues. I am looking to showcase blocks of text using basic DIVs or other elements inside another DIV, mirroring the organization of the issue page. In order to achieve this, I need to positi ...

What could be the reason for operators like tap and map not being invoked on the inner observable when combineLatest is used?

Can you clarify why the operators tap and map of inner observable are not being called? Shouldn't combineLatest subscribe to the observables it receives in obsArr? Why are these operators not triggered by this subscription? const obsArr = []; [[1, 2 ...

Transform a REACT js Component into an HTML document

I'm working with a static React component that displays information from a database. My goal is to implement a function that enables users to download the React component as an HTML file when they click on a button. In essence, I want to give users ...

Load content in three.js using JavaScript

In my three.js project or JavaScript, I want to preload contents with a loading bar. While I am familiar with using action-script to achieve this, I am struggling to do the same in JavaScript: Here is the code snippet: var loader = new THREE ...

Creating a dropdown list for months in Vue.js

I have managed to get this working in my test project, but I'm struggling to understand the inner workings of it. The Vue.js implementation seems a bit complex to me, and I believe there might be a simpler way to achieve the same result. Any advice on ...

Could you please install an older version of Vue.js devtools, or consider downloading an earlier release

Just noticed the latest update for vue devtools, but it seems to have some issues with displaying my vuex store data. The data gets updated after mutations but doesn't show up in the tool anymore. Has anyone figured out how to revert back to the prev ...

Validation of textfields using React.js

Currently, I am working on implementing a validation feature in ReactJS. Specifically, I have a field named "name" and my requirement is that every time a name is entered, it must be equal to or greater than 2 characters. The validation works fine when t ...

What could be causing my API post request using Guzzle to fail?

I encountered an error while attempting to make a post request to an API in order to create a new client: Client error: `POST https://testname.app.invoicexpress.com/document-type.json?api_key=...` resulted in a `404 Not Found` response: <!doctype html ...