Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue.js: Calculate average and update field

I am trying to calculate the average of sub grades that aren't equal to zero and setting a binded input to that new average value.

The sub grades have a v-on directive that calls a calcAverage() function. In this is where I would think you should update the respective avgGrade value.

HTML:

<div id="container">
    <div class="row" v-repeat="testData">
        <p>Grade avg:
            <!--this should be average of sub grades that aren't 0-->
            <input type="text" v-model="avgGrade" disabled />
            <div v-repeat="vals">Sub grade {{item}}:
                <input type="text" v-model="grade" v-on="change:calcAverage" />
            </div>
        </p>
    </div>
</div>

JS:

var data = [
    {item: 1,avgGrade: 2,vals: [{grade: 2}, {grade: 2}, {grade: 2}]},
    {item: 2,avgGrade: 3,vals: [{grade: 3}, {grade: 3}, {grade: 3}]},
    {item: 3,avgGrade: 4,vals: [{grade: 4}, {grade: 4}, {grade: 4}]}
];
var testVue = new Vue({
    el: '#container',
    data: {
        testData: data
    },
    methods: {
        calcAverage: function (e) {
            //calculate the average of sub grades
            //change Grade avg to show this
        }
    }
});

Fiddle: https://jsfiddle.net/ksumarine/bwrvsmpk/

Thanks!

like image 463
ksumarine Avatar asked Jan 25 '26 00:01

ksumarine


1 Answers

You can pass the repeat item into your the change event callback function, just like this:

HTML

<div id="container">
    <div class="row" v-repeat="testData">
        <p>Grade avg:
            <!--this should be average of sub grades that aren't 0-->
            <input type="text" v-model="avgGrade" disabled />
            <div v-repeat="vals" v-with="subItem: $data">Sub grade {{item}}:
                <input type="text" v-model="grade" v-on="change:calcAverage(subItem)" />
            </div>
        </p>
    </div>
</div>

JS

var data = [
    {item: 1,avgGrade: 2,vals: [{grade: 2}, {grade: 2}, {grade: 2}]},
    {item: 2,avgGrade: 3,vals: [{grade: 3}, {grade: 3}, {grade: 3}]},
    {item: 3,avgGrade: 4,vals: [{grade: 4}, {grade: 4}, {grade: 4}]}
];

var testVue = new Vue({
    el: '#container',
    data: {
        testData: data
    },
    methods: {
        calcAverage: function (subItem) {
            var total = 0,
                length = subItem.vals.length;

            for (var i = 0; i < length; i++) {
                total += parseFloat(subItem.vals[i].grade);
            }

            subItem.avgGrade = total / length;
        }
    }
});

Assuming your avgGrade is float, I use parseFloat here, you can change it to parseInt as you like.

And here is a JSFiddle.

like image 94
Miaonster Avatar answered Jan 26 '26 14:01

Miaonster