0

I can't seem to figure out how to sum the values of various field types in a form. I have some select fields like this:

<select name="age">
    <option value="">- Select -</option>
    <option value="1" class="">30-34</option>
    <option value="2">35-39</option>
</select>

And some radio buttons:

    <p>Do you smoke?</p>
    <label for="riskSmoke"><input type="radio" name="riskSmoke" value="2"> Yes</label><br>
    <label for="riskSmoke"><input type="radio" name="riskSmoke" value="0"> No</label>

But how would I add the selections all up? I can find solutions for adding values of just inputs, or just radios, or just selects. But not all together.

I'd use jQuery if I have to.

[EDIT] I should have said, I'd like to output the total value to the user, perhaps inside a element.

3
  • please according to the example you show share the expected result. I imagine it will be adding the values of the selected elements. Is that so? Commented Jul 5, 2020 at 13:36
  • Yes, sorry. It should sum up the values of all the selected options. If the user selects the option "30-40" and then the "No" radio button, the form should display the sum "1" (1 + 0). Commented Jul 5, 2020 at 13:58
  • ok, please try the example i suggest Commented Jul 5, 2020 at 14:01

8 Answers 8

1

Could clean this up a bit, but an example of using the FormData interface to add up all values in a form: https://developer.mozilla.org/en-US/docs/Web/API/FormData

function getValues() {
  let myForm = document.getElementById('myForm');
  let formData = new FormData(myForm);
  
  let total = 0;

  for (var value of formData.values()) {
     total += parseInt(value);
  }
  
  document.getElementById("total").innerHTML = total;
  
  console.log(total);
}
<form id="myForm" name="myForm">
  <div>
    <label for="age">What is your age?</label>
    <select name="age">
        <option value="">- Select -</option>
        <option value="1" class="">30-34</option>
        <option value="2">35-39</option>
    </select>
  </div>
  <div>
    <label for="riskSmoke">Do you smoke?</label>
    <label for="riskSmoke"><input type="radio" name="riskSmoke" value="2"> Yes</label>
    <label for="riskSmoke"><input type="radio" name="riskSmoke" value="0"> No</label>
  </div>
</form>

<button onclick="getValues()">Get Values</button>

<p>Total:</p>
<div id="total"></div>

Sign up to request clarification or add additional context in comments.

Comments

1

You can use constructor FormData.

An HTML <form> element — when specified, the FormData object will be populated with the form's current keys/values using the name property of each element for the keys and their submitted value for the values. It will also encode file input content.

You could add a key/value pair to this using FormData.append:

formData.append('username', 'Chris'); 

Comments

1

I assume that you mean adding the values of the selected elements and that you use some trigger in this case I use a button. To make it work select options that have values

Please try this option

const button = document.querySelector("button");

button.addEventListener("click", () => {
  const age = document.querySelector("select");
  const riskSmoke = document.querySelector('input[name="riskSmoke"]:checked');

  if (age && age.value && riskSmoke) {
    const ageValue = +age.value;
    const riskSmokeValue = +riskSmoke.value;

    console.log(ageValue + riskSmokeValue);
  }
});
<select name="age">
  <option value="">- Select -</option>
  <option value="1" class="">30-34</option>
  <option value="2">35-39</option>
</select>

<p>Do you smoke?</p>
<label><input type="radio" name="riskSmoke" value="2" /> Yes</label><br />
<label><input type="radio" name="riskSmoke" value="0" /> No</label>

<button>Click</button>

3 Comments

Not very generic, is it?
sorry, what do you mean?
With your code, OP will have to separately add every field to his sum. See my answer to see what I mean
1

Without jQuery and for selecting specific values:

function getValues() {
  var ageValue = Number(document.querySelector("select[name=age]").value);
  console.log('age value: ' + ageValue);
  var smokeValue = Number(document.querySelector('input[name="riskSmoke"]:checked').value);
  console.log('smoke value: ' + smokeValue);
  console.log('age + smoke: ' + (ageValue + smokeValue));
}
<select name="age">
    <option value="">- Select -</option>
    <option value="1" class="">30-34</option>
    <option value="2">35-39</option>
</select>

<p>Do you smoke?</p>
<label for="riskSmoke"><input type="radio" name="riskSmoke" value="2"> Yes</label><br>
<label for="riskSmoke"><input type="radio" name="riskSmoke" value="0"> No</label>
<p>    
<button onclick="getValues()">Get Values</button>

9 Comments

Not very generic, is it?
@mplungjan no not at all but I assumed OP is looking to add up specific values not just everything on his page. The other answers here would cause problems if you had multiple inputs on your page that you wanted to add up separately, so just wanted to give an example of how to select things specifically if you wanted.
I expect OP wants to add up ALL values in the form/container
@mplungjan true but in that case I'd probably recommend using a form.
But as you can see in my answer we can sum all input fields on a page (or in my latest version a form) without knowing their names
|
1

jQuery seems to be a bit of a overkill. In order to get the sum of the options and inputs, you may first get the value of the option in the select tag, and then add to the value of the selected radio input as such:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Your Title Here</title>
</head>
<body>
    <select name="age" id="someId">
        <option value="">- Select -</option>
        <option value="1" class="">30-34</option>
        <option value="2">35-39</option>
    </select>
    <p>Do you smoke?</p>
    <label for="riskSmoke"><input type="radio" name="riskSmoke" value="2"> Yes</label><br>
    <label for="riskSmoke"><input type="radio" name="riskSmoke" value="0"> No</label><br>
    <button onclick="CalculateValue()">Calculate</button>
    <script>
        let ageRangePicker = null, riskSmokeOptions = null;

        function CalculateValue(){
            ageRangePicker = document.getElementById("someId");
            if(ageRangePicker.value !== ""){
                let sum = Number(ageRangePicker.value);
                riskSmokeOptions = document.getElementsByName("riskSmoke")
                for(i = 0; i < riskSmokeOptions.length; i++) { 
                    if(riskSmokeOptions[i].checked) 
                        sum += Number(riskSmokeOptions[i].value); 
                }
                alert("Your risk is: " + sum);
            }
            else{
                alert("Select an age range");
            }
        }
    </script>
</body>
</html>

2 Comments

Does not seem very generic, does it? I would say code overkill here
In real world applications I would totally agree, but my thoughts on the answer was to show the 'old fashioned way' of doing this since it looks like more of a beginners question.
1

I wrap in a form with an ID and sum on all input, making sure only to count checked radios and checkboxes

const sumValues = () => {
  let val = 0;
  $("#myForm :input").each(function() {
    if (this.type === "radio" || this.type === "checkbox")
      val += this.checked ? +this.value : 0;
    else val += +this.value; // cast to number
  })
  $("#total").text(val)
};
$(function() {
  $("#myForm").on("change", sumValues).change(); //when page loads
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<form id="myForm">
  <select name="age">
    <option value="">- Select -</option>
    <option value="1" class="" selected>30-34</option>
    <option value="2">35-39</option>
  </select>


  <p>Do you smoke?</p>
  <label for="riskSmoke"><input type="radio" checked name="riskSmoke" value="2"> Yes</label><br>
  <label for="riskSmoke"><input type="radio" name="riskSmoke" value="0"> No</label>
  <br/>Total: <span id="total" />
</form>

Plain JS

const sumValues = () => {
  let val = 0;
  [...document.getElementById("myForm").querySelectorAll("input, select, textarea")].forEach(function(elem) {
    if (elem.type === "radio" || elem.type === "checkbox")
      val += elem.checked ? +elem.value : 0;
    else val += +elem.value; // cast to number
  })
  document.getElementById("total").textContent = val;
};
window.addEventListener("load", function() {
  document.querySelector("#myForm").addEventListener("change", sumValues)
  sumValues()
})
<form id="myForm">
  <select name="age">
    <option value="">- Select -</option>
    <option value="1" class="" selected>30-34</option>
    <option value="2">35-39</option>
  </select>


  <p>Do you smoke?</p>
  <label for="riskSmoke"><input type="radio" checked name="riskSmoke" value="2"> Yes</label><br>
  <label for="riskSmoke"><input type="radio" name="riskSmoke" value="0"> No</label>
  <br/>Total: <span id="total" />
</form>

2 Comments

It's important that if the user changes a value, the total changes accordingly.
I added a plain JS version
1

With jQuery, you can listen for the change event and use both the jQuery .serializeArray() and the array .reduce() method to get the total:

$('form').on('change', function() {
    let totalScore = $(this).serializeArray().reduce((a, f) => a += +f.value, 0);
    //output to a predefined element
    $('#output').text( totalScore );
})
.change();

Here is how you may define an output element:

<div class="output">
    <label>Total Score: </label>
    <span id="output"></span>
</div>

Note that this will give a running total and there's no need to click any button or to trigger any event other then the actions needed to make choices on the various form elements.

$('form').on('change', function() {
    let totalScore = $(this).serializeArray().reduce((a, f) => a += +f.value, 0);
    //console.log( totalScore );
    $('#output').text( totalScore );
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form method="post">
<select name="age">
    <option value="">- Select -</option>
    <option value="1" class="">30-34</option>
    <option value="2">35-39</option>
</select>
<p>Do you smoke?</p>
<label for="riskSmoke"><input type="radio" name="riskSmoke" value="2"> Yes</label><br>
<label for="riskSmoke"><input type="radio" name="riskSmoke" value="0"> No</label>
</form>
<div class="output">
    <label>Total Score: </label>
    <span id="output"></span>
</div>

Comments

0

Put a button below at the bottom of your HTML and make a function something like this:

const radioControls = document.querySelectorAll('.radio-btn');
const selectControl = document.querySelectorAll('.select');
let dataTransferObject = {
  radioValue: 0,
  selectValue: 0
};
let sum = 0;

function collectValues() {
  for(let control of radioControls) {
    if (control.checked) {
      dto.radioValue = control.value
    }    
  }
  dto.selectValue = selectControl[0].value;
  for(let attr of Object.values(dto)) {
    sum += parseInt(attr);
  }  
}

Then your button simply calls this function, I would imagine this would all be contained in a form of some sort:

<button onclick="collectValues()">Submit</button>

Now the variable sum holds the accumulated value.

1 Comment

DRY: Don't repeat yourself.

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.