Displaying subtotal in a list using Vue.js and conditional rendering with v-if statement

Seeking guidance on calculating a total for a vue.js list that contains invoice items. To illustrate, let's consider a scenario where a table of invoice items is being rendered. Here is the code snippet:

<table>
<template v-for="(invoice_item, index) in invoice_items" v-if="invoice_item.category === 'widgets'">
    <tr>
        <td>@{{ invoice_item.name }}</td>
        <td><input type="number" class="inline-edit" v-model="invoice_item.rate"></td>
        <td><input type="number" class="inline-edit" v-model="invoice_item.quantity"></td>
        <td><input type="number" class="inline-edit" v-model="invoice_item.activation_fee"></td>
        <td class="subtotal">@{{ computeSubTotal(invoice_item) }}</td>
    </tr>
</template>
</table>

An individual subtotal is calculated for each row and displayed in the final column using the Vue.js JavaScript function below:

computeSubTotal: function(invoice_item) {
    return(this.formatPrice((parseFloat(invoice_item.rate) * parseFloat(invoice_item.quantity) + parseFloat(invoice_item.activation_fee))));
},

The current setup works effectively. However, the objective now is to show the total sum of all subtotals from the listed invoice items:

https://i.sstatic.net/9Qjwc.png

How can this be achieved?

Appreciate any input!

Answer №1

Utilize computed properties for your calculations.

console.clear()

new Vue({
  el: "#app",
  data: {
    invoice_items: [
      {
        name: "Community / Support",
        rate: 5.20,
        quantity: 1,
        activation_fee: 3.00,
        category: "widgets"
      },
      {
        name: "Infrastructure",
        rate: 269.00,
        quantity: 3,
        activation_fee: 1.00,
        category: "widgets"
      },
      {
        name: "Infrastructure",
        rate: 269.00,
        quantity: 3,
        activation_fee: 1.00,
        category: "stuff"
      },
    ]
  },
  computed: {
    // potentially need a more descriptive name, but this is just an example
    itemsWithSubTotal() {
      return this.invoice_items.map(item => ({
          item,
          subtotal: this.computeSubTotal(item)
      }))
    },
    // calculate the total of all subtotalItems grouped by category
    totalByCategory() {
      // group the items by category
      let grouped = this.itemsWithSubTotal
        .reduce((acc, val) => {
          if (!acc[val.item.category]) 
            acc[val.item.category] = []
          acc[val.item.category].push(val)
          return acc
        }, {})
        
      // create an object with the total for each category
      return Object.keys(grouped).reduce((acc, val) => {
        acc[val] = grouped[val].reduce((total, item) => total += item.subtotal, 0)
        return acc
      }, {})
    }
  },
  methods: {
    computeSubTotal: function(invoice_item) {
      return ((parseFloat(invoice_item.rate) * parseFloat(invoice_item.quantity) + parseFloat(invoice_item.activation_fee)));
    },
  }
})
input {
  width: 5em
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
<div id="app">
  <table>
    <template v-for="(invoice_item, index) in itemsWithSubTotal" v-if="invoice_item.item.category === 'widgets'">
    <tr>
        <td>{{ invoice_item.name }}</td>
        <td><input type="number" class="inline-edit" v-model="invoice_item.item.rate"></td>
        <td><input type="number" class="inline-edit" v-model="invoice_item.item.quantity"></td>
        <td><input type="number" class="inline-edit" v-model="invoice_item.item.activation_fee"></td>
        <td class="subtotal">{{ invoice_item.subtotal }}</td>
    </tr>
</template>
  </table>
  Total: {{totalByCategory["widgets"]}}
</div>

The itemsWithSubTotal might appear unusual.

itemsWithSubTotal() {
  return this.invoice_items.map(item => ({
      item,
      subtotal: this.computeSubTotal(item)
  }))
},

This essentially returns a new object with an item property referring to the original item and a subtotal property. I structured it this way to allow for v-model functionality in the template and automatic updates to the computed properties.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Specialized selection option with disabled function

Looking for assistance with a script to create a custom select box. I have UL and LI elements overlapping a select element, but I want to prevent the UL LI from opening when the select has a "disabled" attribute. Can anyone provide guidance on how to achie ...

How to resolve the error "TypeError: 'listener' argument must be a function" in Gulpfile.js?

I am in the process of setting up my development environment and encountering some issues when running gulp in the terminal. I am not sure where this error is originating from. Here is the snippet of code from my Gulpfile.js : var gulp = require(&a ...

I encountered an issue stating, "The function `req.redirect` is not recognized."

Recently starting out with node development. Encountering the error below: TypeError: req.redirect is not a function at Post.create (/var/www/html/node_blog/index.js:40:7) at /var/www/html/node_blog/node_modules/mongoose/lib/utils.js:276:16 a ...

Using Django, CSS, and Javascript, create a dynamic HTML form that shows or hides a text field based on the selection

How can I hide a text field in my Django form until a user selects a checkbox? I am a beginner in Django and web applications, so I don't know what to search for or where to start. Any guidance would be appreciated. Here is the solution I came up wi ...

What is the best approach for developing an npm package containing multiple Vue directives? Should each directive have its own separate package, or should they

While I have successfully created an npm package by exporting a single vue directive in the src/index.js file, I am now faced with the challenge of creating a package that allows for the use of multiple vue directives. Unfortunately, I have been unable t ...

What could be the reason for not receiving any response from my Firestore query?

Hey there! I'm delving into the world of Firebase for the first time and just set up the Firestore emulator. I've added some data that I want to fetch in my Nextjs app. Once I initialized firebase, this is what my component code looks like: funct ...

Adding data to a multidimensional array in JavaScript

I am in need of creating a multidimensional JavaScript array dynamically, following this specific structure: array_answers[0][1]:"yes" array_answers[1][2]:"no" array_answers[2][2-subquestion]:"text input" array_answers[3][8]:"yes" array_answers[4] ...

How to position items at specific coordinates in a dropdown using JavaScript

I have five images in my code and I would like to arrange them in a circular pattern when they are dropped into the designated area. For example, instead of lining up the five images in a straight line, I want them to form a circle shape once dropped. Ho ...

When we find ourselves within a fat arrow function

I'm struggling with this code. I have a ternary operator within a fat arrow function, but for some reason it's not working. There are no errors in browserify or the console, but the headers are not being printed. If I remove the {} and ternary o ...

Tips for organizing and concealing images within a Div for seamless transitions (no need for floats)

Currently, I am working on a grid layout for my website. My goal is to have 9 images load quickly, and then once the page has loaded, I want to fetch additional images, insert them into the image containers, and animate between them. While I understand how ...

In a VueJS project, access an xlsx file stored in the public directory by reading its contents

My current challenge involves trying to extract a quiz template from an xlsx file in order to create the quiz within it. Unfortunately, storing the xlsx file as json in a database is not a feasible solution for me at this time. I experimented with using ...

Incorporating D3.js into Angular 6 for interactive click events

Currently working on building a visual representation of a tree/hierarchy data structure using d3.js v4 within an Angular environment. I've taken inspiration from this particular implementation https://bl.ocks.org/d3noob/43a860bc0024792f8803bba8ca0d5e ...

Having difficulties hosting static Vue.js files using Express

Take a look at my express code: const express = require('express'); const serveStatic = require('serve-static'); const path = require('path'); // Setting up the express app const app = express(); var cors = require('cors ...

How can a personalized greeting be added in Node.js to welcome a user by their first name retrieved from a MongoDB database upon logging in?

I am looking to create a login and signup form using React that will allow users to input their name, email, and password. After submission, I want the next page to be a personalized congratulations page with the user's name dynamically inserted. Can ...

Value in any array matches

I need help finding a match array within an input value: var values = new Array('stackoverflow', 'google', 'yahoo'); var userInput = $('#txtAddress').val(); if ($.inArray(userInput, values) != -1) { alert(&apos ...

Tips for retrieving the 'Created' value in vue.js

I am currently trying to fetch API JSON data for a weather widget, but unfortunately it is returning null. While I am able to retrieve the JSON data successfully, I am struggling to handle this value. Below is my HTML code snippet: <html> <head& ...

An in-depth guide on incorporating an Editor into a Reactjs project

Currently, I am working with Reactjs and using the Nextjs framework. My goal is to integrate the "Tinymce" editor into my project and retrieve the editor value inside a formsubmit function. How can I achieve this? Below is my current code: const editor = ...

Javascript malfunctions upon refreshing the div

After updating data with an ajax function and refreshing the div, I encountered an issue where the jQuery elements inside the div break. How can this be resolved? function getURLParameter(name) { return decodeURIComponent((new RegExp('[?|&]&apo ...

When I use `console.log` with `req.body` in Node, the password is

Currently, I am utilizing NodeJs on the backend to console.log(req.body) data from a form that gathers usernames and passwords from users. I have noticed that this method exposes the collected username and password information. Should I be concerned abou ...

React JS functionality does not support Bootstrap tooltips

I'm attempting to implement a tooltip in my React app, but I'm experiencing issues with it not displaying properly. I am utilizing vanilla Bootstrap for this purpose. I've included the following script tag in my index.html file to import the ...