0

I am trying to calculate the average of 3 values (each numbered from 1-10) that are selected by the user and then pass the results to an text input (for display as a graph).

It should be updating the new average every time one of the values is changed, but the averaging is not working correctly at all. I think that the loop is not resetting the values every time it runs- it's adding up the sum each time it runs, but not sure how to fix it.

Here is my code:

var sliders = $("#health1,#health2,#health3");

var elmt = [];

$(sliders).each(function () {
    elmt.push($(this).attr('value'));

    $("#health1,#health2,#health3").change(function () {
        var sum = 0;
        averageRisk();
    });
});

function averageRisk() {
    var sum = 0;
    for (var i = 0; i < elmt.length; i++) {
        sum += parseInt(elmt[i], 10);
    }

    var avg = sum / elmt.length;
    document.getElementById('healthLevel').value = +avg;

    elmt.push($(sliders).attr('value'));
    $('#healthLevel').val(avg).trigger('change');

    console.log("Sum: " + sum);
    console.log("Average: " + avg);
}

Here is an example:

http://jsfiddle.net/pixelmix/783cfmnv/

Jordan Running
  • 102,619
  • 17
  • 182
  • 182
dchadney
  • 283
  • 2
  • 7
  • 18

3 Answers3

3

Not sure but seems like a lot of extra work going. Main issue was you were building array of initial values and not getting the values each time they changed. That first .each got all the slider values and added them to elmt and continued to push new values on to after every change instead of just getting the current values every time. Did you want to accumulate all values over time?

Fiddle: http://jsfiddle.net/AtheistP3ace/783cfmnv/6/

$("#health1,#health2,#health3").on('change', function () {
    averageRisk();
});

function averageRisk() {
    var sum = 0;
    var elmt = $("#health1,#health2,#health3");
    for (var i = 0; i < elmt.length; i++) {
        sum += parseInt(elmt[i].value, 10); //don't forget to add the base
    }

    var avg = sum / elmt.length;
    document.getElementById('healthLevel').value = +avg;

    $('#healthLevel').val(avg).trigger('change');
    console.log("Sum: " + sum);
    console.log("Average: " + avg);
}

And as pointed out if you want to ignore updating things when the sum is NaN you can do this:

function averageRisk() {
    var sum = 0;
    var elmt = $("#health1,#health2,#health3");
    for (var i = 0; i < elmt.length; i++) {
        sum += parseInt(elmt[i].value, 10); //don't forget to add the base
    }

    if (isNaN(sum)) {
        return false;
    }

    var avg = sum / elmt.length;
    document.getElementById('healthLevel').value = +avg;

    $('#healthLevel').val(avg).trigger('change');
    console.log("Sum: " + sum);
    console.log("Average: " + avg);
}
AtheistP3ace
  • 9,611
  • 12
  • 43
  • 43
  • 1
    This is a great solution. It may be desirable for it to ignore empty elements (or act as though they are 0 ?) because right now an empty element will fill "NaN" – jdussault Nov 20 '15 at 16:42
  • Very true! Updated answer. – AtheistP3ace Nov 20 '15 at 16:44
  • Yes I agree this is a great solution. it works just as I wanted it to. In my case it's not possible to have a value of 0, but I can see the usefulness of having something in place for this. – dchadney Nov 20 '15 at 16:44
  • Well the update doesn't take into account 0 but it will not update the average if its not a number. This solution can easily be extended to handle many situations I imagine. – AtheistP3ace Nov 20 '15 at 16:45
1

The problem is that you fill the elmt array at page loading.

When user changes the values, you do not refresh the elmt array. So the array used to compute the average is always the same, empty.

You have to recover the input values each time they are modified.

function averageRisk() {
    var sum = 0;

    // Re make the loop for getting all inputs values
    $(sliders).each(function() {
        var value = parseInt($(this).val(), 10);
        sum += value;
    });

    var avg = sum/$(sliders).length;

    $('#healthLevel').val(avg);
}

Working example : http://jsfiddle.net/783cfmnv/7/

PS : You can use the css class healthInput to select your inputs. If you add later other fields, you will not have to add the new input id to your jQuery selector.

Paul DS
  • 859
  • 7
  • 13
1

I did this work, check it .

http://jsfiddle.net/783cfmnv/10/

$("#health1,#health2,#health3").change(function() {
             var val1 = +slider1.val();
                var val2 = +slider2.val();
                var val3 = +slider3.val();
             var avg = (val1 + val2 + val3) /3;  
             $("#healthLevel").val(avg);                  
            });
Zohaib Ijaz
  • 21,926
  • 7
  • 38
  • 60