Utilizing dynamic class and color binding features in VueJs?

I need help with implementing a Custom Sort method on my divs to arrange them in ascending or descending order. My query is how can I pre-set the icon color to grey by default, and only change it to black when clicked, while keeping the others greyed out as demonstrated in Vuetify data tables here.

For reference, here is a link to my pen.

new Vue({
  el: '#app',
  data() {
    return {
      headers: [{
          text: "Name",
          value: "name"
        },
        {
          text: "Grades",
          value: "grades"
        }
      ],
      labels: ["Andy", "Max", "John", "Travis", "Rick"],
      Grades: [99, 72, 66, 84, 91],
      sortKey: "",
      direction: 1
    }
  },
  computed: {
    tableItems() {
      let retVal = this.labels.map((label, i) => {
        return {
          name: label,
          grades: this.Grades[i]
        };
      });
      
      if (this.sortKey) {
        retVal.sort((a, b) =>
          this.direction *
          (a[this.sortKey] < b[this.sortKey] ? -1 : 1)
        );
      }
      return retVal;
    }
  },
  methods: {
    sortBy(prop) {
      if (this.sortKey === prop) {
        this.direction *= -1
      }
      this.sortKey = prop;
      console.log(prop);
    }
  }
})
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="44323121302d223d04756a716a7570">[email protected]</a>/dist/vuetify.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/babel-polyfill/dist/polyfill.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="9fe9eafaebf6f9e6dfaeb1aab1aeab">[email protected]</a>/dist/vuetify.min.css" rel="stylesheet" />
<div id="app">
  <v-app id="inspire">
    <v-container>
      <v-layout>
        <v-flex v-for="header in headers" :key="header.text" xs4 py-1>
          <span>
                {{ header.text }}
                <v-icon small @click="sortBy(header.value)">arrow_upward</v-icon>
            </span>
      </v-layout>
      <v-layout v-for="item in tableItems" :key="item.name">
        <v-flex xs4 py-1>
          <span>{{ item.name }}</span>
        </v-flex>
        <v-flex xs4 py-1>
          <span>{{item.grades}}</span>
        </v-flex>
      </v-layout>
    </v-container>
  </v-app>
</div>

I am trying to replicate the functionality of Vuetify data tables but struggling with binding the color of the icon based on the header value when clicked.

Answer №1

A simple solution would be to use a dynamic class name that changes based on a method to check your sortKey value, either directly on the icon or on a parent element.

Customized Pen

:class="{ current: sortKey == header.value }"

Answer №2

If you want to enhance your code...

customizeIconStyle(value) {
  return (this.direction===1 && value===this.sortKey)?'black--text':'grey--text'
}

You can apply it in this way...

<v-icon small @click="updateSortBy(header.value)" :class="customizeIconStyle(header.value)">arrow_upward</v-icon>

Check out the custom demo here

Another way to handle the icon styling is...

<v-icon small @click="updateSortBy(header.value)" :class="customizeIconStyle(header.value)">{{setCustomIcon(header.value)}}</v-icon>

setCustomIcon(value) {
    return (this.direction===1 && value===this.sortKey)?'arrow_upward':'arrow_downward'
}

View the updated customized Codeply

Answer №3

Incorporate the icon as its own stateful component by creating a single file component called Icon.vue. Then, simply import it into your Vue instance where necessary.

<template>
  <i @click="setActive" v-bind:class="{ active: isActive }"></i>
</template>

<script>
  data() {
    return {
      active: false
    }
  },
  methods: {
    setActive() {
      active = true
    }
  },
  computed: {
    isActive() {
    return active
  }
}
</script>

<style scoped>
  .active {
    /* Define styles for 'active' state here */
  }
</style>

Import the Icon component:

import Icon from 'wherever/icon/is.vue'
/* ... */
components: {
  'icon': Icon,
}

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

Transform a jQuery element into an HTML element

I'm facing a dilemma where I have a jQuery element that needs to be passed into a function that only works with HTML elements. How can I efficiently convert the jQuery element into an HTML element? ...

What is the best way to format a date as "2020-01-16 07:29:43.657519000 Z" using JavaScript?

Upon discovering a format 2020-01-16 07:29:43.657519000 Z in a project, I am curious about the significance of the numbers 657519000 and how to replicate this precise format using JavaScript. When attempting new Date().toISOString(), I receive 2020-05-27T2 ...

JavaScript WYSIWYG Algorithm

Despite my searches on SO, it appears that most questions revolve around simply making a div editable using contenteditable="true". I am interested in finding the most effective method for tracking all formatting tags applied to a document. Merely togglin ...

The versions of my npm and node are not compatible, despite using nvm

I have recently started working with node and npm. I need to run a program repository for my job, which requires compatibility with node version 10.13.0 or even 8.11. I attempted to install nvm, but now every time I try to execute any npm command (includ ...

Easily changing the state of a specific array item using React

I'm having trouble updating the state of a specific item in an array called reviews. Can someone guide me on how to achieve this? The following code snippet is not working as expected: this.setState({ reviews[2].current: true }); Below is the comp ...

Using PHP to pass variables to an external JavaScript file

I have come across the following code snippet: PHP <?php include("db.php"); ?> <html> <head> <title>Title</title> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.0/j ...

The function res.render is not displaying the new page

I have a task that seems straightforward. On my header, I am loading a few a links. <a class="nav-link" href="menu">Menu 1</a> I am attempting to access the URL /menu from this link. In my app.js file: app.use('/', index); app.us ...

Detecting When an Input has an :invalid Selector in Jquery

Here is the code snippet I am currently working with: HTML <input type="text" data-value="1" data-type="input-records" placeholder="Value" pattern="\d{1,4}$" /> CSS input[type=text]:invalid { background-color: red; } Javascript $("[data-ty ...

Validation of New Relic License Key

Is there a way to verify the validity of a provided New Relic license key in a JavaScript application? I have searched through the documentation but did not come across any API endpoint for this purpose. UPDATE: Just to clarify, we do not have access to ...

I am struggling to create a modal component for a settings button

I am currently working with Quasar VueJS and I have a requirement to add a button on my navbar that will trigger a pop-up dialog settings panel. This settings panel will be used for various functionalities such as dynamic theming, although that is somewhat ...

What causes the DOM's appendChild() to trigger on('load', ...) while jQuery's append() does not fire?

I have two snippets of code that I am working with: $(document).ready(function() { document.head.appendChild( $('<script />').attr('src', 'source.js').on('load', function() { ... ...

Overtaking a property in a node_module interface: a guide

I am facing a situation where I need to modify an existing interface property in my custom type declaration file, rather than creating a new one. Despite trying various approaches, such as attempting to omit the property, I have not been successful in ach ...

What is the best way to ensure only one item is being selected at a time?

In the initial state, I want 'ALL' to be automatically selected. Clicking on another item should change the classes so that only 'this' has the class and the others do not. However, I am facing an issue where 'ALL' cannot be r ...

Identifying a particular pattern in a JavaScript string

What is the best way to check if a JavaScript String includes the pattern: "@aRandomString.temp" I need to verify if the String includes an @ character followed by any string and finally ".temp". Thank you ...

Incorporating a delay into looped HTTP requests while effectively utilizing Promise.all to track their completion

Greetings! In my current project, I am trying to introduce a 50ms delay before each subsequent HTTP request is sent to the server. Additionally, I aim to incorporate a functionality that triggers after all requests have been successfully made. To better e ...

Troubleshooting jQuery masonry problem related to initial display and height settings

Within a div, there is a masonry container with the inline style property display:none. With several divs on the page, clicking their respective buttons during load causes them to switch like a slideshow. This disrupts masonry's ability to calculate t ...

Is it necessary to encode special characters in a JSON object?

I am currently working on a code where I am taking a class and converting it to JSON format. Throughout my testing, all the content is surrounded by double quotes, for example: { "a" : "hello world ! '' this is john's desk" } I am wonderi ...

A step-by-step guide on incorporating vue-select into a basic HTML webpage

My initial experience with Vue + vue-select is a learning curve. I followed the guidelines in the vue-select documentation to import Vue and vue-select. The HTML page for my first attempt is as follows: <!DOCTYPE html> <html lang="en&qu ...

What is the most effective way to utilize zoom with an Orthographic projection?

I'm attempting to utilize THREE.OrbitControls for zooming in an orthographic projection, but I'm not achieving the desired outcome. I believe it may be possible to adjust the viewSize that is multiplied by left, right, top, and bottom to achieve ...

Exploring the limitations of middlewares in supporting independent routers

When I examine the code provided, it consists of three distinct routers: const Express = require("express") const app = Express() // Three independent routers defined below const usersRouter = Express.Router() const productsRouter = Express.Router() cons ...