narrei
narrei

Reputation: 596

Vue js - show/hide a single element in list generated with v-for

I am trying to show/hide a single element, as v-for is used for many objects. Before, i had showAeInfo as a boolean, which resulted in all of the cards opening/closing when a single button was pressed. I figured out i would need an array of booleans, for each card to have its own data for open/collapse.

I came up with this code, however now, when I press button, I can see the value in array changed, but card didn't open.

Any idea why? Or is there a better way to do this instead of showAeInfo array?

Thank you!

<template>
    <div class="container">
        <button class="btn btn-primary" @click="show">Pridaj prídavné zariadenia na túto stavbu</button>

        <modal name="addAesToConsite" height="auto" :scrollable="true">
            <div class="addAesToCSModalFlex mt-4">
                <div class="card mb-2" style="width: 18rem;" v-for="ae in aes" :key="ae.id">
                    <img :src="ae.imgPath" class="card-img-top">
                    <div class="card-body">
                        <h5 class="card-title"><a :href="ae.path">{{ ae.pseudo_id + " - " + ae.name }}</a></h5>
                        <button class="btn btn-outline-secondary"
                                @click="showAeInfo[ae.id] = true"
                                v-show="!showAeInfo[ae.id]">
                            Zobraz informácie
                        </button>
                        <button class="btn btn-outline-secondary" @click="showAeInfo[ae.id] = false" v-show="showAeInfo[ae.id]">
                            Skry informácie
                        </button>
                        <div v-show="showAeInfo[ae.id]">
                            <p class="card-text"><b>Poloha:</b> {{ aeLocationName(ae.construction_site_id) }}</p>
                        </div>
                        <a href="#" class="btn btn-primary">Pridaj toto zariadenie na stavbu</a>
                    </div>
                </div>
            </div>
        </modal>
    </div>
</template>

<script>
  export default {
    props: {
      cs: {
        required: true,
        type: Object
      },
      aes: {
        required: true,
        type: Array
      },
      machines: {
        required: true,
        type: Array
      },
      css: {
        required: true,
        type: Array
      }
    },

    mounted: function() {
      this.setShowAeInfo()
    },

    created() {
      //
    },

    data: function() {
      return {
        showAeInfo: []
      }
    },
    methods: {
      show() {
        this.$modal.show('addAesToConsite');
      },
      aeLocationName(ae) {
        var cs;
        if (ae) {
          cs = this.css.filter(tcs => tcs.id === ae)[0].name;
          return cs;
        } else {
          return 'Neznáma stavba';
        }
      },
      setShowAeInfo() {
        this.aes.forEach(ae => this.showAeInfo.push(false))
        this.showAeInfo.push(false);
      },
    }
  }
</script>

Upvotes: 1

Views: 1984

Answers (1)

Ilia Brykin
Ilia Brykin

Reputation: 271

new Vue({
  el: '#app',
  template: `
    <div>
      <ul>
        <li v-for="item in list" :key="item.id">
          <strong>Item:</strong> {{item.name}}
          <button @click="showItem(item.id, true)" v-show="!statusShowItem[item.id]">Zobraz informácie</button>
          <button @click="showItem(item.id, false)" v-show="statusShowItem[item.id]">Skry informácie</button>
        </li>
      </ul>
    </div>
  `,
  data() {
    return {
      statusShowItem: {},
      list: [{
          id: "1",
          name: "item1",
        },
        {
          id: "2",
          name: "item2",
        },
        {
          id: "3",
          name: "item3",
        },
      ],
    };
  },
  methods: {
    showItem(id, status) {
      if (status) {
        this.$set(this.statusShowItem, id, true);
      } else {
        this.statusShowItem[id] = false;
      }
    },
  },
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app"></div>

Upvotes: 1

Related Questions