Dynamically arranging data rows in a table using dates with Vue

In my Vue application, I am currently processing data for employees, including their hours and swipes, and multiplying this data for each employee every day.

This process is generating new rows of data so that I have a complete set of information for each day.

However, I am facing an issue in my template where I want to display the multiplied data in the column corresponding to the date and have only one row for each employee. I expect the results to look like this:

Employee  |  2021-08-31  |  2021-09-01  |  2021-09-02
-----------------------------------------------------
Evan        60                60
Stan        100               200
Kelly       60                             164

I am looking for guidance on how I can adjust my current approach to ensure that I end up with only one row per employee and place the data in the correct column based on the date in the object for that record and the column-header date.

<div id="app">
  <table>
    <thead>
      <tr>
        <th>Employee</th>
        <th>2021-08-31</th>
        <th>2021-09-01</th>
        <th>2021-09-02</th>
        <th>Grand Total</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(row, index) in compRows">
        <td v-html="row.employee"></td>
        <td v-if="row.workDate == {{$date->addDay()->format($format)}}"></td>
        <td v-html="row.hours"></td>
      </tr>
    </tbody>
  </table>
</div>


@endsection

@section('loadjs')

<script>

new Vue({
  el: "#app",
  data: {
    rows: [
        {  
            employee: "Evan",
            hours: "15",
            workDate: "2021-08-31",
            swipes: "4",
            
        },
        {  
            employee: "Kelly",
            hours: "15",
            workDate: "2021-08-31",
            swipes: "4",
            
        },
        {  
            employee: "Evan",
            hours: "15",
            workDate: "2021-09-01",
            swipes: "4",
           
        },
        {  
            employee: "Stan",
            hours: "25",
            workDate: "2021-08-31",
            swipes: "4",
            
        },
        {  
            employee: "Kelly",
            hours: "82",
            workDate: "2021-09-02",
            swipes: "2",
            
        },
        {  
            employee: "Stan",
            hours: "40",
            workDate: "2021-09-01",
            swipes: "5",
           
        }
    ]
  },
  methods: {

  },
  computed: {
    compRows() {
      const grouped = this.rows.reduce((r, o) => {
        r[o.employee] ??= {};
        r[o.employee][o.workDate] ??= {employee: o.employee, workDate: o.workDate, swipes: 0, hours: 0};
        r[o.employee][o.workDate].swipes += +o.swipes;
        r[o.employee][o.workDate].hours += +o.hours;
        return r;
      }, {});
      return Object.values(grouped).map(o => Object.values(o)).flat();
    }
  }
});


</script>

Answer №1

  1. Instead of merging the grouped data in the compRows prop (now known as hoursByEmployee), maintain it as an object for later retrieval of employee hours by date. Additionally, keep a total property to store the overall total (swipes by hours).

    export default {
      computed: {
        hoursByEmployee() {
          return this.rows.reduce((r, o) => {
            r[o.employee] ??= {}
            r[o.employee][o.workDate] ??= {swipes: 0, hours: 0}
            r[o.employee][o.workDate].swipes += +o.swipes
            r[o.employee][o.workDate].hours += +o.hours
            r[o.employee].total ??= 0 👈
            r[o.employee].total += (+o.swipes * +o.hours) 👈
            return r
          }, {})
        },
      }
    }
    
  2. Create another computed property to extract the available dates from the rows' workDate and sort them in chronological order:

    export default {
      computed: {
        dates() {
          const dates = [...new Set(this.rows.map(r => r.workDate))]
          return dates.sort((a,b) => new Date(a) - new Date(b))
        },
      }
    }
    
  3. Within the template's table header, display the calculated dates:

    <thead>
      <tr>
        <th>Employee</th>
        <th v-for="date in dates" :key="date">{{ date }}</th> 👈
        <th>Grand Total</th>
      </tr>
    </thead>
    
  4. In the template's table body, visualize the employee hours by date using the hoursByEmployee lookup and the previously generated dates. If the hours are present for the date, show the daily total. Lastly, display the final total property in the last column.

    <tbody>
      <tr v-for="(hours, employee) in hoursByEmployee" :key="employee">
        <td>{{ employee }}</td>
        <td v-for="date in dates" :key="date">{{ hours[date] && hours[date].swipes * hours[date].hours }}</td> 👈
        <td>{{ hours.total }}</td> 👈
      </tr>
    </tbody>
    

demo

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

Unable to access component data while inside a v-for loop scope

I recently started using Vue and I'm having trouble accessing my component data within a v-for loop. After implementing the code below, I encountered this error message. TypeError: Cannot read property 'whatever' of undefined at eva ...

Learn how to stream videos using the YouTube Player API's loadPlaylist feature

Is there a way to make the next video play automatically using the loadPlaylist option? I've tried implementing this code but unfortunately, it doesn't work and the video won't play: <div id="player"></div> <script> var ...

Exploring a new method for AJAX loading when handling large amounts of data into multiple div elements

As I continue my learning journey with html and jquery, I have been exploring ways to replicate monitoring systems (SCADA) into web-based systems. During this process, I discovered openseadragon as a MAP system similar to google maps that allows for overla ...

Oops! Looks like the connection has been abruptly cut off from the ASYNC node

Is there a way to properly close an async connection once all data has been successfully entered? Despite attempting to end the connection outside of the loop, it seems that the structure is being finalized after the first INSERT operation CODE require( ...

Running a server using Docker with Node and Vue proves to be a challenging task

Here is the structure of my Dockerfile: FROM node:current-buster # Utilities: System RUN apt update && apt install -y nano apt-utils #RUN npm install -g @vue/cli-service-global # Utilities: Node & Vue RUN npm install -g @vue/cli RUN mkdir /a ...

Is there a method to display a loading animation while the micro apps are being loaded in a single spa project?

Currently, I am working on a project using single spa and I need to implement a loader while my micro app is being loaded. Additionally, I also need the loader to be displayed when switching between these micro apps. Are there any methods to accomplish t ...

Utilizing Vue.js 2 to dynamically update data through directives

Is it possible to change a data property from a directive using single file components? For instance, consider the following code... export default { name: 'app', data: function() { return { is_loading: true ...

Can you explain how to break down secured routes, users, and posts all within a single .create() function in Mongoose/JavaScript

I am seeking guidance on utilizing the .create() method within a protected route while implementing deconstructed JavaScript. In the absence of the protected route, I can deconstruct my schema and utilize req.body in .create(...) as shown below. const { ti ...

Exploring Javascript parameters with the power of jquery

Is it possible to pass a parameter from PHP into a JavaScript function within HTML? I am currently facing an issue where my code crashes when it reaches a certain condition. This is the code snippet causing the problem: $str="<input type='submit&a ...

Are the functionalities of my code implemented with Node.js and callback functions comparable to Java Threads?

I am unfamiliar with the Node.js concurrency model. Below is an example of creating Java threads and starting them concurrently. package com.main; class MyThread implements Runnable{ private int num = 0; MyThread(int num){ this.num = num; } ...

Guide on Validating and Updating an embedded item within a mongoDB Collection Document

How do I go about updating the values of an embedded object within a mongoDB document? The values displayed for {{service.id}} and {{service.username}} in the table template are correct. However, I am unsure of the correct way to access them within the sa ...

Disabling the Autocomplete Drop-Down Arrow

Can the drop-down arrow icon be removed from the material-ui Autocomplete react component? My current view includes a blue arrow that I'd like to remove, opting instead for text to automatically drop down as I type. https://i.stack.imgur.com/ZTLYu.p ...

Minimize the number of clicks needed to navigate using the HTML/JavaScript navigation

On my website, I have a navigation bar that changes the contents of a div when a user clicks on an item. However, if the user clicks multiple times in quick succession, the content changes too many times. I want to ensure that the content only changes once ...

Vue - Additional loading may be required to manage the output of these loaders

Currently working with Vue and babel. I have a function that's been exported // Inside file a.js export async function get() { ... } I am trying to link this exported function to a static method of MyClass // Inside file b.js import myInterface fr ...

Embed JavaScript code within the Material-UI components

I am working with the material-ui ListItemText: <ListItemText primary={<div> <Table className={classes.table}> <TableRow> <TableCell width="40">{item.issue_state}</TableCell> <TableCell width="40">{ ...

Having trouble accessing the property 'prototype' of null in Bing Maps when using Angular4

I'm currently working on creating a Bing component in Angular 4, but I'm facing issues with rendering the map. Below is my index.html file: <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title> ...

How can you pass an authorization token in a Next.js post request when using Django REST framework?

Is there a way to successfully pass a Django authorization token in Next.js using Axios? I attempted this method, but encountered a 404 error. let token = "Token 8736be9dba6ccb11208a536f3531bccc686cf88d" await axios.post(url,{ headers ...

Steps to remove information from a database using PHP, AJAX, and vanilla JavaScript (without jQuery)

I am facing an issue with deleting data from my database. Whenever I click on the delete button, it deletes the first row instead of the intended row. Below is my PHP code: <?php $connect = mysqli_connect("localhost","root","","abu"); if($conne ...

Unlock the innerHTML of a DIV by clicking a button with ng-click in Angular JS

I am curious about something. There is a <div> and a <button> in my code. I am looking to access the inner markup of the <div> within the ng-click function without relying on jQuery. Can you give me some guidance? <div id = text-entry ...

Is it possible to insert a second hyperlink into a JavaScript-occupied anchor?

Check out my reference page at: To change the content in a 'containerarea' div, I am utilizing Dynamic Drive's "Dynamic Ajax" script. Below is an example of the anchor code used: <a href="javascript:ajaxpage('videos-maintenance/app ...