0

I am looking to add a number of inputs together so far I have reached two results.

Firstly using on input the computed result would add together every digit inputted.

Secondly using v-model as you would with a checkbox to put into an array but all the boxes end up matching each other.

The short piece of code there is is the following:

<template>
                <div class="panel panel-default">
                    <div class="panel-heading">{{credits}}</div>
                      <div v-for="meal in title">
                        <input v-bind:id="meal" v-model.number="used_credits" type="number">{{used_credits}}
                    <div class="panel-body">

                    </div>
                </div>

</template>

Thank you

3
  • I am not exactly sure what you're trying to achieve. Maybe you could give us a bit more code? Anyway: You're binding all your inputs to the exact same model - that's why they are always having the same value. Commented Jan 11, 2017 at 21:22
  • I shall explain better, say for example there were three. Number inputs developed by v-for. The user then input 2 in the first and then 2 and 5 in the others. I would like to add the numbers together and output 2, then 4 and then 9 as the user inputs. Commented Jan 11, 2017 at 21:26
  • Sorry there isn't more code the next step is the step it struggling with. Commented Jan 11, 2017 at 21:26

1 Answer 1

2

Alright, this is a (little) bit tricky. When working with v-model in a template loop we have to make sure the assigned model is different for each iteration. Otherwise all inputs will be bound to the exact same model instance. We can achieve this by using an object that stores all models and access those by a key available in the loop. Here's some code (based on your snippet):

<template>
  <div>
    <div>{{ credits }}</div>
    <div v-for="meal in meals">
      <input :id="meal" v-model.number="creditsPerMeal[meal]" type="number">
    </div>
    <div>
      Credits used: {{creditsSum}}
    </div>
  </div>
</template>

<script>
  export default {
    name: 'test-component',
    data: function () {
      let meals = [
        'pizza', 'pasta', 'salad'
      ]

      let creditsPerMeal = {}
      for (let meal of meals) {
        creditsPerMeal[meal] = 0
      }

      return {
        credits: 10,
        meals,
        creditsPerMeal
      }
    },
    computed: {
      creditsSum () {
        return Object.values(this.creditsPerMeal).reduce((a, b) => a + b, 0)
      }
    }
  }
</script>

The tricky part is that the object which should store our models has to be pre-initialized with all keys. If this is not the case, the computed property creditsSum would not get updated. Keep in mind that this might not work if you get the meals dynamically via a prop or some other means. If you have to do that, consider using a watch function instead of the computed property I used in the snippet.

See this part of the documentation for more information about the change detection of Vue and this part about computed properties vs watchers.

Edit: In case you are not using a transpiler like Babel you might have to replace all let with var and the loop as follows in the snippet above:

  var meals = [
    'pizza', 'pasta', 'salad'
  ]

  var creditsPerMeal = {}
  for (var i = 0; i < meals.length; i++) {
    creditsPerMeal[meals[i]] = 0
  }
Sign up to request clarification or add additional context in comments.

8 Comments

Thanks Bengt, sorry for the delayed reply. I having problems with the code failing. The module build fails. It seems to be when the v-model.number is used with []. Do you have any ideas?
Hi there! What does the console say?
I am getting "Uncaught Error: Module build failed: Error at Node.initialise". Thanks!
That error is related to your build system. I used some ES2015 features in the snippet above, because I assumed you're using Babel. How did you scaffold your project - have you used the vue-webpack-boilerplate?
Im using it as part of Laravel installation so webpack should be installed
|

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.