How can I avoid having all expand-transitions occur simultaneously in Vuetify?

I am currently working on a page that includes several cards, each with its own v-expand-transition. These cards are being generated through a v-for loop. The issue I'm facing is that when I click on one v-expand-transition, all of the transitions open simultaneously. I understand that this is because they are all connected to the same "show" event, but I am unsure how to separate them so each card has its own event. Below is the code snippet I am using:

<template>
<v-container>
    <h1 class="font-weight-medium pa-6">All Labs</h1>
    <v-row dense>
      <v-col v-for="card in cards" :key="card.title" :cols="card.flex">
        <v-card class="mx-auto" max-width="350">
          <v-img class="white--text align-end" height="200px" :src="card.src" gradient="to bottom, rgba(0,0,0,.1), rgba(0,0,0,.5)">
            <v-card-title v-text="card.title"></v-card-title>
          </v-img>
        <v-card-subtitle class="pb=0" v-text="card.location"></v-card-subtitle>
        <v-card-text class="text--primary">
          <div v-text="card.hours"></div>
          <div v-text="card.keycardInfo"></div>
        </v-card-text>
        <v-card-actions>
            <v-btn color="blue" :href="card.directions" text target="_blank"gt;Directions</v-btn>
          <v-btn color="blue" :to="card.page" text>Learn More</v-btn>
          <v-spacer></v-spacer>
          <v-btn icon @click="toggelShow(card.id)">
            <v-icon>{{ getIconStatus(card.id) }}</v-icon>
          </v-btn>
        </v-card-actions>
        <v-expand-transition>
          <div v-show="isShown(card.id)">
            <v-divider></v-divider>
            <v-card-text v-text="card.bottomInfo"></v-card-text>
          </div>
        </v-expand-transition>
        </v-card>
      </v-col>
    </v-row>
  </v-container>
</template>

and my script is as follows:

<script>
import App from '../App.vue'

  export default {
  components: { App },
    name: 'Home',
    data: () => ({
      cardStatus: {},
      cards: [],
        
    }),
    methods: {
      toggleShow(id) {
        this.$set(this.cardStatus, id, !this.cardStatus[id]);
      },
      isShown(id) {
        return this.cardStatus[id];
      },
      getIconStatus(id) {
        return this.isShown(id) ? 'mdi-chevron-up' : 'mdi-chevron-down';
      }
    }
  }
</script>

I have kept the cards empty for now to prevent clutter on the page.

Answer №1

If you find that using a single variable to control the state of your component causes the action to affect everyone, consider adding a "show" property inside each object in your list. This approach allows each object to have its own unique state. Here is an example:

new Vue({
  el: '#app',
  data() {
    return {
       cards: [{
         title: "My title",
         flex: 6,
         src: '#',
         location: '#',
         hours: '13',
         keycardInfo: 'Info',
         directions: '#',
         page: '#',
         to: '#',
         bottomInfo: 'Bottom info',
         show: false,
       },
       {
         title: "My title 2",
         flex: 6,
         src: '#',
         location: '#',
         hours: '13',
         keycardInfo: 'Info 2',
         directions: '#',
         page: '#',
         to: '#',
         bottomInfo: 'Bottom info 2',
         show: false,
       }],
    }
  }
})
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
  <link href="https://cdn.jsdelivr.net/npm/@mdi/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="92f4fded97d3e75ffe">[email protected]</a>/css/materialdesignicons.min.css" rel="stylesheet">
  <link href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="56202333223f302f1664782e">[email protected]</a>/dist/vuetify.min.css" rel="stylesheet">
  
<div id="app">
  <v-container>
    <h1 class="font-weight-medium pa-6">All Labs</h1>
    <v-row dense>
      <v-col v-for="card in cards" :key="card.title" :cols="card.flex">
        <v-card class="mx-auto" max-width="350">
          <v-img class="white--text align-end" height="200px" :src="card.src" gradient="to bottom, rgba(0,0,0,.1), rgba(0,0,0,.5)">
            <v-card-title v-text="card.title"></v-card-title>
          </v-img>
        <v-card-subtitle class="pb=0" v-text="card.location"></v-card-subtitle>
        <v-card-text class="text--primary">
          <div v-text="card.hours"></div>
          <div v-text="card.keycardInfo"></div>
        </v-card-text>
        <v-card-actions>
            <v-btn color="blue" :href="card.directions" text target="_blank">Directions</v-btn>
          <v-btn color="blue" :to="card.page" text>Learn More</v-btn>
          <v-spacer></v-spacer>
          <v-btn  @click="card.show = !card.show">
            {{ card.show ? 'Hide' : 'Show' }}
          </v-btn>
        </v-card-actions>
        <v-expand-transition>
          <div v-show="card.show">
            <v-divider></v-divider>
            <v-card-text v-text="card.bottomInfo"></v-card-text>
          </div>
        </v-expand-transition>
        </v-card>
      </v-col>
    </v-row>
  </v-container>
</div>
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="0375766643312d7b">[email protected]</a>/dist/vue.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="89fffcecfde0eff0c9bba7f1">[email protected]</a>/dist/vuetify.js"></script>

Instead of using Vuetify's expansion panels, consider exploring another option by referring to the documentation link provided below.

https://vuetifyjs.com/en/components/expansion-panels/#usage

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

What is the ideal JavaScript framework for implementing drag-and-drop, resize, and rotation features?

I am planning to create a web application that involves images and text with user handle functionalities such as drag-and-drop, resizing, and rotating. Although I have tried using JQuery UI js to implement drag-and-drop, rotate, and resize, I have encount ...

Comparing two tables in jQuery/Javascript for matching data

I want to check for matches between the rows of two HTML tables, where the data in the first cell can be duplicated but the data in the second cell is always unique. The goal is to determine if the combination of values in the first and second cells of tab ...

What steps do I need to take to integrate Vuex into a Vue CLI project?

After setting up a project with VUE CLI, I wanted to integrate VUEX to add a store to my application. However, I encountered errors when trying to install VUEX using the command: npm install vuex --save-dev The error message stated: Could not resolve de ...

Is there a specific regular expression that can be used for validating Credit Card Expiry dates in Javascript/Ang

I am currently working on a textfield where users can enter their credit card expiry date in the format mm/yy. To ensure the validity of this input, I have implemented JavaScript validation using regular expressions. Here is an example of what I have tried ...

Collecting data from an HTML form filled out by users

I need a way to capture user input from an HTML form and display it later on my website. I want to show all the information users provide along with their pizza selections. I've been struggling for hours trying to make this work without success :( Spe ...

Injecting dynamic content using JavaScript

My goal is to develop a web page where clicking on any of the three images will cause the content to be inserted into the empty div located above the image links. Below is the JavaScript code I'm using: <script type="text/javascript" src="js/jque ...

What is the process of declaring state in React components?

I have recently started learning React and I am curious about how this code snippet should function: class App extends Component { > 4 | state = { | ^ 5 | bands: [], 6 | concerts: [] 7 | } Below is the error message being ...

What steps can I take to address this issue with my express node and ejs?

Hey there, I'm new to node.js and I've been encountering this error message. Can someone please provide some insight? Error: Could not find matching close tag for "<%=". at /Users//Desktop/Web Development/getting_started_express js/node_m ...

Maintain focus on the current tab when utilizing window.open() function

When I open a window in another tab with my code, the issue is that the focus immediately shifts to the new tab. However, I need the focus to stay on the current window. I have tried searching for a solution, but haven't found one yet. It seems like ...

Having difficulty launching the sapper app in production mode

Having trouble starting my sapper project in production mode. When running npm run start, the following output appears on the console: niklas@Niklass-iMac project-name % npm run start > [email protected] start /Users/niklas/path/to/project > node _ ...

Javascript : an operation which combines two separate functions

Trying to create a function named "sendAndMove" that involves two other functions working in a specific order: setting() followed by goHome(). However, the initial code executes them in the reverse order - goHome() first, then setting(). Asynchronous featu ...

React Discussion Forum Word Count Tracker

Hey there coding whizzes, I'm currently facing a thorny issue with React. I've managed to display 2000 as a numeric value overall, but strangely, whenever I try to input within the comment section, the number transforms into NaN. I attempted usi ...

The div keeps appearing multiple times while the button remains inactive

In order to create a password confirmation form with validation, you need to have two input fields - one for entering a new password and another to confirm the password. The goal is to display a message saying "please enter the password above" below the ...

How can Vue.js implement a satisfactory method for synchronizing computed values with asynchronous data?

Imagine retrieving a list of products from the state manager in your Vue.js component, where a computed property is then used to process this list for display on the DOM. <template> <span>{{ computedProducts }}</span> </template> ...

AngularJS ng-table with collapsible headers using jQuery accordion

Currently, I am utilizing AngularJS ng-table to showcase specific information. My goal is to have a fixed header with a scroll bar for the ng-table. Additionally, I aim to include an accordion just before the ng-table. However, when I collapse the accordi ...

Utilizing Laravel Blade traits within Javascript script: A step-by-step guide

I am utilizing Laravel traits that are able to convert numbers into a money-currency format. If I wish to use it within a Blade template, I simply call it like this: <td class="text-center"> @money($repayment->admnin) </td> However, I am f ...

Retrieve an array of items from the Firebase snapshot

Currently in the process of retrieving items from my Firebase database, I am utilizing a snapshot that is generated when the page loads. I have collected the values of each object in an array and I am now attempting to add an item from each object into a s ...

What is the best method to customize CSS in ExtJS 5.0 by overriding a function?

Is there a way to dynamically add a rule to existing CSS using code, particularly in overrides? For example: var sheets = document.styleSheets; // Some code omitted for simplicity var sheet = sheets[sheets.length - 1]; sheet.insertRule('.overlay {flo ...

Receiving an error when attempting to import a function and access props using the "this" keyword: "TypeError: Unable to retrieve property 'renderElapsedString' as it is undefined"

Just started using React and working on a time tracking app based on the teachings of FullStackReact. Instead of Create Class, I opted for the ES6 'extends' module. However, I've encountered an error that has got me stumped. Error: Unable ...

Choosing items in an MVC view using KnockoutJS

I am currently working on implementing a generic ASP.net MVC view that displays a list of available and selected items loaded from the server. Users have the ability to make changes to the list by selecting new items from the available list and removing it ...