Changing class on radio button change

Viewed 270

My first column (Test1) is active, so the background turns orange. Why does the active class not change to the second column (Test2) when I click the radio button? I'd like it to change the active class when the radio button is clicked.

I have the following template:

<template v-if="columns" v-for="(item, index) in columns" v-bind="item">
    <div class="card-container"
         :style="{'height': item.height+'%'}"
         :class="{ active: item.active}">
        <div class="card-inner">
            <input type="radio" v-if="item.selectedDefault" checked v-model="currentInput" name="cardRadioGroup"
                   :value="item.id" v-on:change="updateDetails(item, index)"/>
            <input type="radio" v-else v-model="currentInput" name="cardRadioGroup" :value="item.id"
                   v-on:change="updateDetails(item, index)"/>
            <template v-if="item.gbAmount === null">
                Onbeperkt
            </template>
            <template v-else>
                {{ item.gbAmount }} GB
            </template>
            {{ currentInput }}
        </div>
    </div>
</template>

With the following Vue code:

import {onMounted} from "vue";

export default {
name: 'Card',
components: {Details},

data() {
    const columns =
        {
            "Test1": {
                "id": 1,
                "gbAmount": 0,
                "price": 5,
                "selectedDefault": false,
                "informationGet": ["bla", "bla"],
                "informationUsing": "Boop.",
                "recommended": false,
                "height": 16.66,
                "active": true,
            },
            "Test2": {
                "id": 2,
                "gbAmount": 1,
                "price": 10,
                "selectedDefault": false,
                "informationGet": ["beh", "beh"],
                "informationUsing": "Beep",
                "recommended": false,
                "height": 33.33,
                "active": false,
            },
        }

    return {
        columns,
        currentColumn: {},
        checkedCard: [],
        currentInput: null,
    };
},

methods: {
    updateDetails(item, index) {
        this.currentColumn = {
            ...item,
            name: index,
            active: true,
        }
        console.log($(this.currentColumn));
    },
},

setup() {
    return {};
},

};

And CSS:

.active {
  background: orange;
}
2 Answers

You update this.currentColumn but in template use this.columns. Correct will be:

updateDetails(item, index) {
    Object.keys(this.columns).forEach(key => this.columns[key].active = false);
    this.columns[index].active = true;
    console.log(this.columns);
 }
<template>
  <div v-for="column in columns" :key="column.id">
    <div
      class="card-container"
      :style="{ height: column.height + '%' }"
      :class="{ active: column.id === currentInput }"
    >
      <div class="card-inner">
        <input
          type="radio"
          name="cardRadioGroup"
          :value="column.id"
          v-model="currentInput"
        />
        <template v-if="column.gbAmount === null"> Onbeperkt </template>
        <template v-else> {{ column.gbAmount }} GB </template>
        {{ currentInput }}
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { ref } from 'vue'

const columns = [
  {
    id: 1,
    gbAmount: 0,
    price: 5,
    selectedDefault: false,
    informationGet: ['bla', 'bla'],
    informationUsing: 'Boop.',
    recommended: false,
    height: 16.66,
  },
  {
    id: 2,
    gbAmount: 1,
    price: 10,
    selectedDefault: false,
    informationGet: ['beh', 'beh'],
    informationUsing: 'Beep',
    recommended: false,
    height: 33.33,
  },
]

export default {
  name: 'Card',
  setup() {

    const currentInput = ref(columns[0].id)

    return {
      columns,
      currentInput,
    }
  },
}
</script>
Related