yariv bar
yariv bar

Reputation: 976

Vuejs multiple active buttons

I'm trying to create a list where every list item contains a button and i want a user to be able to click multiple button. I'm generating my list like so:

    <ul>
      <li v-for="item in items" :key="item.id">
        <button type="button">{{item.title}}</button>
      </li>
    </ul>

but the problem with my code is whenever a user click a button, it turns the rest of the buttons to "unclicked". been trying to play with the focus and active stats but even with just css i cant get to enable multiple select . i did manage to change the look of the current selected button:

button:focus {
  outline: none;
  background-color: #6acddf;
  color: #fff;
}

any idea how can i allow multiple buttons to be clicked?

to make things a bit clearer, i am going to create an AJAX call later and pass the item.id of each item where it's button is clicked

Upvotes: 1

Views: 4947

Answers (2)

Vucko
Vucko

Reputation: 20844

I would much rather avoid changing the data structure if possible

Well you have to store somewhere that you clicked on the clicked item.

If you can't edit the items array then you can always create a new one, like isClicked where you store those values.

new Vue({
  el: '#app',
  data: {
    items: [{
        id: 1,
        title: 'foo'
      },
      {
        id: 2,
        title: 'bar'
      },
      {
        id: 3,
        title: 'baz'
      }
    ],
    isClicked: []
  },
  beforeMount() {
    // set all values to false
    this.items.forEach((item, index) => this.$set(this.isClicked, index, false))
  },
  methods: {
    clicked(index) {
      // toggle the active class
      this.$set(this.isClicked, index, !this.isClicked[index])
    }
  }
})
.active {
  background: red
}
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <div v-for="(item, index) in items" :key="index">
    <button @click="clicked(index)" :class="{'active': isClicked[index]}">{{item.title}}</button>
  </div>
</div>

Or you can use vuex for storing those values.


However you can just use Vues event to manipulate the classList property, like:

new Vue({
  el: '#app',
  data: {
    items: [1, 2, 3, 4, 5, 6, 7]
  }
})
.active {
  color: red
}
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <button v-for="i in items" @click="e => e.target.classList.toggle('active')">{{ i }}</button>
</div>

But it doesn't feel right, IMHO.

Also you can use cookies or localStorage to store those states. So it's really up to you.

Upvotes: 3

Muthu
Muthu

Reputation: 19

Use id attribute for list items to make it unique.

<ul>
    <li v-for="item in items" :key="item.id" :id="item.id">
        <button type="button" @click="doThis">{{item.title}}</button>
    </li>
</ul>


new Vue({
  el: '#app',
  data: {},
  methods: {
      doThis() { 
          // Use this to access current object
      }
  }
});

Upvotes: 0

Related Questions