1

I use v-for to create buttons. I add the .active class if isActiveButton() returns true:

<button 
  v-for="(text, index) in this.buttonOptions" 
  class="btn" 
  :class="{active: isActiveButton(text)}" 
  :value='text' 
  @mousedown.prevent @click="some_method">
    {{text}}
</button>

What is the best way to add the .active class to the first button if isActive() returns false for all buttonOptions? Note that the buttonOptions is a prop.

2
  • Is that , supposed to be there before the :value? Commented Jun 8, 2018 at 18:50
  • edit code block Commented Jun 8, 2018 at 18:51

2 Answers 2

3

A Computed Property would be the way to go!

var app = new Vue({
  el: '#app',
  data: {
    buttonOptions: ['button1', 'button2', 'button3', 'button4']
  },
  methods: {
    isActiveButton: function (text) {
      return (text === text.toUpperCase());
    },
    some_method: function() {
      console.log('Button clicked')
    }
  },
  computed: {
    shouldFirstBeActive: function () {
      return (this.buttonOptions.filter(el => this.isActiveButton(el))).length === 0
    }
  }
});
.active {
  background: #f00;
}
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
  <section>
    <button 
      v-for="(text, index) in buttonOptions" 
      class="btn" 
      :class="{active: isActiveButton(text) || (shouldFirstBeActive && index === 0)}" 
      :value='text' 
      @mousedown.prevent @click="some_method">
        {{text}}
    </button>
  </section>
</div>

I don't know what the methods isActiveButton do, so I had to improvise: It checks if the string is uppercase.

What does the trick is the computed property shouldFirstBeActive which returns true if all the items in the buttonOptions array fails the isActiveButton method:

return (this.buttonOptions.filter(el => this.isActiveButton(el))).length === 0  

If you change the button2 to BUTTON2 for example, then the isActiveButton returns true for that item, which renders the shouldFirstBeActive computed property to false

var app = new Vue({
  el: '#app',
  data: {
    buttonOptions: ['button1', 'BUTTON2', 'button3', 'button4']
  },
  methods: {
    isActiveButton: function (text) {
      return (text === text.toUpperCase());
    },
    some_method: function() {
      console.log('Button clicked')
    }
  },
  computed: {
    shouldFirstBeActive: function () {
      return (this.buttonOptions.filter(el => this.isActiveButton(el))).length === 0
    }
  }
});
.active {
  background: #f00;
}
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
  <section>
    <button 
      v-for="(text, index) in buttonOptions" 
      class="btn" 
      :class="{active: isActiveButton(text) || (shouldFirstBeActive && index === 0)}" 
      :value='text' 
      @mousedown.prevent @click="some_method">
        {{text}}
    </button>
  </section>
</div>

Sign up to request clarification or add additional context in comments.

Comments

1

Use a computed that filters this.buttonOptions where isActiveButton is true and that takes index as a parameter

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.