John Tasci
John Tasci

Reputation: 33

How to get the average of all the dynamic inputs

I can't find the average of all the inputs. My code only reads the input that i stated in html, but doesn't read the other dynamic ones.

Heres my code:

        $(document).ready(function(){
        // adds a new row
    	$(".addCF").click(function(){
    		$("#customFields").append('<tr valign="top"><th scope="row"><label for="customFieldName">Custom Field</label></th><td><input type="text" class="code" id="customFieldName" name="customFieldName[]" value="" placeholder="Input Name" /> &nbsp; <a href="javascript:void(0);" class="add">Add </a><a href="javascript:void(0);" class="remCF">Remove</a></td></tr>');
        });
        // deletes the row
        $("#customFields").on('click','.remCF',function(){
            $(this).parent().parent().remove();
        });
        $("#customFields").on('click','.add',function(){
          $("#customFields").append('<tr valign="top"><th scope="row"><label for="customFieldName">Custom Field</label></th><td><input type="text" class="code" id="customFieldName" name="customFieldName[]" value="" placeholder="Input Name" /> &nbsp; <a href="javascript:void(0);" class="add">Add </a><a href="javascript:void(0);" class="remCF">Remove</a></td></tr>');
        });
        $("#click").click(function(){
            var isbn = document.getElementById('customFieldName').value;
            alert(isbn / $("input").length)
            $("#averageGrade").text("Average Grade: " + isbn)
        })
    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="form-table" id="customFields">
    	<tr valign="top">
    		<th scope="row"><label for="customFieldName">Custom Field</label></th>
    		<td>
    			<input type="text" class="code" id="customFieldName" name="customFieldName[]" placeholder="Input Name" /> &nbsp;
    			<a href="javascript:void(0);" class="addCF">Add</a>
            </td>
        </tr>
    </table>
    <button id = "click" class = "btn btn-primary" >Hi</button>
    <p id = "averageGrade">Average Grade:</p>

Please help! Thanks!

Upvotes: 0

Views: 121

Answers (3)

Lewis
Lewis

Reputation: 4595

Each element.id must be unique - please change customFieldName to a class, and then iterate over the inputs and calculate the average. Also, you can reuse the same class for all "add" buttons and save that string in a variable so you don't have to paste it multiple times.

let inputTemplate = '<tr valign="top"><th scope="row"><label>Custom Field</label></th><td><input type="text" class="customFieldName code" name="customFieldName[]" value="" placeholder="Input Name" /> &nbsp; <a href="javascript:void(0);" class="addCF">Add </a><a href="javascript:void(0);" class="remCF">Remove</a></td></tr>';

$(document).ready(function() {
  
  // adds a new row
  $("#customFields").on('click', '.addCF', function() {
    $("#customFields").append(inputTemplate);
  });

  // deletes the row
  $("#customFields").on('click', '.remCF', function() {
    $(this).parent().parent().remove();
  });

  $("#click").click(function() {

    let fields = $('.customFieldName'),
        total = 0;
        
    for (let field of fields)
      total += Number(field.value);
      
    let average = total / fields.length;
    $("#averageGrade").text("Average Grade: " + average);
    
  })
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="form-table" id="customFields">
  <tr valign="top">
    <th scope="row"><label>Custom Field</label></th>
    <td>
      <input type="text" class="customFieldName code" name="customFieldName[]" placeholder="Input Name" /> &nbsp;
      <a href="javascript:void(0);" class="addCF">Add</a>
    </td>
  </tr>
</table>
<button id="click" class="btn btn-primary">Hi</button>
<p id="averageGrade">Average Grade:</p>

Upvotes: 1

Martin
Martin

Reputation: 2424

As many has pointed out (including myself in the comment section), you are going about using the wrong selector. id is a unique selector, meaning that the script will look at the first instance of the id and then stop immediately after.

What you need to do is use a selector that goes through every occurance of its instance. This is why class selectors exist. That will be the first fix in your code.

How I would go about calculating the average, personally, would be to make an array and push(); the values of the grades into the array. We will also need to do a parseInt() to make sure that our values are in fact handled as numbers. Otherwise, they'll be interpreted as strings.

You will then need to loop through the array, sum the values and divide by the length of the array.

HTML Example:

<div class="row">
    <div class="col-12">
        <table class="table form-table" id="customFields">
            <tr valign="top">
                <th scope="row"><label>Custom Field</label></th>
                <td>
                    <input type="number" class="customFieldName" placeholder="Input Number" /> &nbsp;
                    <a href="javascript:void(0);" class="addCF">Add</a>
                </td>
            </tr>
        </table>
    </div>
</div>
<div class="row">
    <div class="col-md-4">
        <button id="calcAvrgBtn" class="btn-primary">Calculate average grade</button>
    </div>
    <div class="col-md-4">
        <p id="averageCalc"></p>
    </div>
</div>

jQuery Example:

$('.addCF').on("click", function() {
    $("#customFields").append('<tr valign="top"><th scope="row"><label>Custom Field</label></th><td><input type="number" class="customFieldName" placeholder="Input Number" /> &nbsp; <a href="javascript:void(0);" class="remCF">Remove</a></td></tr>');
});

$(document).on("click", "a.remCF" , function() {
    $(this).parent().parent().remove();
});

$('#calcAvrgBtn').on("click", function() {
    let gradeArr = [];

    $('.customFieldName').each(function() {
        gradeArr.push(parseInt($(this).val()));
    });

    let total = 0;

    for(var i = 0; i < gradeArr.length; i++) {
        total += gradeArr[i];
    }

    let avg = total / gradeArr.length;

    $('#averageCalc').text("The average grade is: "+avg);
});

Codepen example can be found here.

Snippet Example:

$('.addCF').on("click", function() {
	$("#customFields").append('<tr valign="top"><th scope="row"><label>Custom Field</label></th><td><input type="number" class="customFieldName" placeholder="Input Number" /> &nbsp; <a href="javascript:void(0);" class="remCF">Remove</a></td></tr>');
});

$(document).on("click", "a.remCF" , function() {
	$(this).parent().parent().remove();
});

$('#calcAvrgBtn').on("click", function() {
	let gradeArr = [];
	
	$('.customFieldName').each(function() {
		gradeArr.push(parseInt($(this).val()));
	});

	let total = 0;
	
	for(var i = 0; i < gradeArr.length; i++) {
		total += gradeArr[i];
	}
	
	let avg = total / gradeArr.length;
	
	$('#averageCalc').text("The average grade is: "+avg);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet"/>
<div class="row">
	<div class="col-12">
		<table class="table form-table" id="customFields">
			<tr valign="top">
				<th scope="row"><label>Custom Field</label></th>
				<td>
					<input type="number" class="customFieldName" placeholder="Input Number" /> &nbsp;
					<a href="javascript:void(0);" class="addCF">Add</a>
				</td>
			</tr>
		</table>
	</div>
</div>
<div class="row">
	<div class="col-md-4">
		<button id="calcAvrgBtn" class="btn-primary">Calculate average grade</button>
	</div>
	<div class="col-md-4">
		<p id="averageCalc"></p>
	</div>
</div>

Upvotes: 0

Gabriel
Gabriel

Reputation: 2190

First of all, you need a way to select all the fields. Since id must (should) be unique, you could use the name or the class .code and remove id="customFieldName".

Then, getElementById, as its name suggests, returns one element. You need to select them all! If you're using class names, you can use getElementsByClassName, or querySelectorAll, or, since you're already using jQuery, just $(".code"), along with a loop to read each input's value (it you use jQuery, you can also use each()).

var sum=0,count=0,average;
$(".code").each(function() {
    var value=parseInt($(this).val());
    //You may want to validate the field
    if(!isNaN(value)) sum+=value;
    count++;
});
average=sum/count;
...

Upvotes: 0

Related Questions