2

How can I multiply values in a table using Vue.js? The macro values are given for 100g of the product. When I type 200g, I would like the values to be doubled, i.e. 318kcal, 12 fat, 48 carbs, 8 protein, 2% iron. When I type 50g: 79.6kcal, 3 fat, 12 carbs, 2 protein, 0.5 iron etc.

Demo code here

HTML:

<div id="app">
  <v-app id="inspire">
    <v-data-table :headers="headers" :items="desserts" :items-per-page="5" class="elevation-1" hide-default-footer>

      <template v-slot:item.quantity="{ item }">
        <v-text-field value="" :placeholder="item.quantity" type="number" suffix="g">
        </v-text-field>
      </template>

    </v-data-table>
  </v-app>
</div>

JS:

new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data () {
    return {
      headers: [
        {
          text: 'Dessert (100g serving)',
          align: 'start',
          sortable: false,
          value: 'name',
        },
        { text: 'Calories', value: 'calories' },
        { text: 'Fat (g)', value: 'fat' },
        { text: 'Carbs (g)', value: 'carbs' },
        { text: 'Protein (g)', value: 'protein' },
        { text: 'Iron (%)', value: 'iron' },
        { text: 'Quantity', value: 'quantity' },
      ],
      desserts: [
        {
          name: 'Frozen Yogurt',
          calories: 159,
          fat: 6.0,
          carbs: 24,
          protein: 4.0,
          iron: '1%',
          quantity: 0,
        },
      ],
    }
  },
  computed: {
    
  }
})
2
  • 1
    Can you show what you have tried so we can try and help you fix it? You should be using a computed to calculate these values for you when the user types something in. Commented Mar 19, 2021 at 20:48
  • 1
    I believe a filter would be a better approach in this case. Manipulating raw data for display is what filters are designed for. vuejs.org/v2/guide/filters.html ... this is assuming you write a template for each table column. Commented Mar 19, 2021 at 20:58

1 Answer 1

2

If dessert[].quantity represented the amount for a single serving size, you could bind the v-text-field's v-model to a data property (e.g., named "userQuantities") that will be used to calculate a multiplier:

<template v-slot:item.quantity="{ item, index }">
  <v-text-field v-model="userQuantities[index]"></v-text-field>
</template>
export default {
  data() {
    return {
      userQuantities: []
    }
  }
}

Then create a computed property (e.g., named "computedDesserts") that calculates the nutrition values based on a multiplier, which is the ratio of the user quantity to single serving size:

export default {
  computed: {
    computedDesserts() {
      return this.desserts.map((dessert,i) => {
        const qty = this.userQuantities[i] || dessert.quantity
        const multiplier = qty / (dessert.quantity || 1)
        return {
          ...dessert,
          calories: dessert.calories * multiplier,
          fat: dessert.fat * multiplier,
          carbs: dessert.carbs * multiplier,
          protein: dessert.protein * multiplier,
          iron: `${parseInt(dessert.iron) * multiplier}%`,
        }
      })
    }
  }
}

And update your template to use computedDesserts instead of desserts:

<v-data-table :items="computedDesserts">

updated codepen

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

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.