1

The user can click on a + and - button to increment and decrement the value. How do I add a min and max value e.g. min = 1 and max = 10 for the <span>[[ count ]]</span>?

My Vue.js app:

<div id="app">
    <a class="btn" v-on:click="increment">Add 1</a>
    <a class="btn" v-on:click="decrement">Remove 1</a>

    <span>[[ count ]]</span>
  </div>

  <script>

    const App = new Vue({
      el: '#app',
      delimiters: ['[[',']]'],
      data() {
        return {
          min: 1,
          max: 10,
          count: 1
        }
      },
      methods: {
        increment() {
          this.count = this.count === this.max ? this.max : this.count + 1;
        },
        decrement() {
          this.count = this.count === this.min ? this.min : this.count + 1;
        }
      }
    })

  </script>

Update: Above code is working now.

1) How do I change my <span>[[ count ]]</span> into an <input type="number" min="0" max="10" />, controlled by this buttons?

2) How do I add a class e.g disabled when [[ count ]] === 1?

Update 2:

I changed it to an input field:

  <input type="number" name="lineItems[{{ product.id }}][quantity]" value="{{ quantity }}" v-model.number="quantity" min="{{ product.minPurchase }}" max="{{ product.calculatedMaxPurchase }}" class="custom-qty__qty-field">

And make the input value adjustable by the min and plus buttons:

<script>
    const app = new Vue({
      el: '#app',
      delimiters: ['[[',']]'],
      data() {
        return {
          quantity: 1,
          max: {{ product.calculatedMaxPurchase }},
          min: {{ product.minPurchase }}
        }
      },
      methods: {
        increment() {
          //this.count++
          this.quantity = this.quantity === this.max ? this.max : this.quantity + 1;
        },
        decrement() {
          //this.count--
          this.quantity = this.quantity === this.min ? this.min : this.quantity - 1;
        }
      }
    })
  </script>

E.g {{ product.minPurchase }} are twig variables which contains settings from the ShopWare backend.

Is this a clean way? And how do I add a CSS class when the count reaches 1, so I can disable the button?

meez
  • 3,783
  • 5
  • 37
  • 91

1 Answers1

2

Check if the count is already at the limits during increment and decrement and act accordingly.

increment() {
  this.count = this.count === 10 ? 10 : this.count + 1;
}
decrement() {
  this.count = this.count === 1 ? 1 : this.count - 1;
}

You could also make min and max data properties instead of hardcoding 1 and 10 if you wanted.

After your Edit:

If you use a number input instead, you could solve this without methods. All that's needed is to bind your data to the input like this:

<input type="number" v-model="count" :min="min" :max="max" />

See the demo below:

new Vue({
  el: "#app",
  data() {
    return {
      min: 1,
      max: 10,
      count: 1
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <input type="number" v-model="count" :min="min" :max="max" />
  
  <span class="instructions">&lt;&lt; Mouseover the input to change</span>
  <div class="count">Count: {{ count }}</div>
</div>
Community
  • 1
  • 1
Dan
  • 59,490
  • 13
  • 101
  • 110
  • thanks. I updated my question. If I want to change my `[[ count ]]` to an `` controlled by this buttons? – meez Mar 12 '20 at 08:25
  • No problem. I edited to reply to your new question – Dan Mar 12 '20 at 14:15
  • I needed the buttons (in combination with the input field). See my updated 2 question. Thanks – meez Mar 12 '20 at 16:50
  • Now you know how to bind data properties to the template, use the buttons, and use the number input. You can combine this knowledge to do what you need. Never use `{{ }}` in the component JavaScript or inside of attributes: only between tags. It's now a completely different question from your original, and it uses my answer from your 1st (and 2nd updated) question. It would be best now to ask a new question rather than to significantly change this one a 3rd time, introducing several new elements. – Dan Mar 12 '20 at 19:49
  • regarding the `{{ }}`. Those are Twig variables. In the backend there are settings assigned and in the Twig template they are rendered with e.g. `{{ product.minPurchase }}`. That's why I use in my Vue instance delimiters: `['[[',']]']` – meez Mar 13 '20 at 12:43
  • Aha, that explains those. Sometimes people try to use interpolation in the wrong spot. I [read up on Twig](https://stackoverflow.com/questions/31480612/conflict-on-template-of-twig-and-vue-js) a bit – Dan Mar 13 '20 at 13:30