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/

2
  • 1
    Shouldn't there be a elmt.pop() or elmt=[]; somewhere? Otherwise, you're just adding to the array all the time. Commented Nov 20, 2015 at 16:37
  • try this: jsfiddle.net/783cfmnv/11 Commented Nov 20, 2015 at 16:45

3 Answers 3

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);
}
Sign up to request clarification or add additional context in comments.

4 Comments

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"
Very true! Updated answer.
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.
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.
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.

Comments

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);                  
            });

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.