Why does removeChild remove every element instead of just one? - javascript

I'm having a very hard time adding HTML to a webpage the way I want to. I'm currently working on a resume creator webpage, but when I click the remove school button while more than 2 schools are listed, the associated javascript removes every school except for the first one. The removeChild function is not working as it is supposed to. My code is listed below. Specifically, if you run the code, then click add school twice, and then click remove school, it will remove Schools 2 and 3, while it should only remove school 3. So something is wrong with my removeSchool function I would think. But nothing is wrong as far as I can tell.
Also, if anyone has any idea of a better way of doing what I'm trying to do, please let me know.
const schools = document.getElementById("schools");
var num_schools = 1;
var add_school_button = `<button id="addschool" onclick="addSchool();">Add School</button>`;
var remove_school_button = `<button id="removeschool" onclick="removeSchool();">Remove School</button>`;
var new_school_html = `<table id="school[]">
<tr>
<td colspan="2" align="center">School []</td>
</tr>
<tr>
<td><label for="schoolname[]">School Name: </label></td><td><input type="text" id="schoolname[]" size="50" /></td>
</tr>
<tr>
<td><label for="schoollocation[]">Location: </label></td><td><input type="text" id="schoollocation[]" size="50" /></td>
</tr>
<tr>
<td><label for="schoolyear[]">Year Graduated: </label></td><td><input type="text" id="schoolyear[]" size="50" /></td>
</tr>
<tr>
<td><label for="schooldegree[]">Degree Earned: </label></td><td><input type="text" id="schooldegree[]" size="50" /></td>
</tr>
</table>`;
function addSchool() {
schools.removeChild(document.getElementById("addschool"));
if (num_schools > 1) {
schools.removeChild(document.getElementById("removeschool"));
}
num_schools++;
schools.innerHTML += new_school_html.replace(/\[\]/g, num_schools.toString());
schools.innerHTML += add_school_button;
schools.innerHTML += remove_school_button;
}
function removeSchool() {
schools.removeChild(document.getElementById("school" + num_schools.toString()));
num_schools--;
if (num_schools == 1) {
schools.removeChild(document.getElementById("removeschool"));
}
}
div {
border: 1px solid black;
}
.maincol {
width: 50%;
}
.maincol>* {
margin-left: 20px;
}
.maincol>h2 {
margin-left: 0px;
}
#schools>table {
margin-bottom: 20px;
}
<h1>Resume Creator</h1>
<form>
<div class="maincol">
<h2>Identifying Information</h2>
<table>
<tr>
<td><label for="name">Full Name: </label></td>
<td><input type="text" id="name" name="name" size="50" /></td>
</tr>
<tr>
<td><label for="address">Address: </label></td>
<td><input type="text" id="address" name="address" size="50" /></td>
</tr>
<tr>
<td><label for="email">Email Address: </label></td>
<td><input type="text" id="email" name="email" size="50" /></td>
</tr>
<tr>
<td><label for="phone">Phone Number: </label></td>
<td><input type="text" id="phone" name="phone" size="50" /></td>
</tr>
</table>
</div>
<div class="maincol">
<h2>Skills</h2>
<p>Enter a comma-separated list of skills. E.g. Guest Services, Loss Prevention, Product Promotion, Etc.</p>
<textarea id="skill_list" rows=4 cols=90></textarea>
</div>
<div class="maincol">
<h2>Education</h2>
<div id="schools">
<table id="school1">
<tr>
<td colspan="2" align="center">School 1</td>
</tr>
<tr>
<td><label for="schoolname1">School Name: </label></td>
<td><input type="text" id="schoolname1" size="50" /></td>
</tr>
<tr>
<td><label for="schoollocation1">Location: </label></td>
<td><input type="text" id="schoollocation1" size="50" /></td>
</tr>
<tr>
<td><label for="schoolyear1">Year Graduated: </label></td>
<td><input type="text" id="schoolyear1" size="50" /></td>
</tr>
<tr>
<td><label for="schooldegree1">Degree Earned: </label></td>
<td><input type="text" id="schooldegree1" size="50" /></td>
</tr>
</table>
<button id="addschool" onclick="addSchool();">Add School</button>
</div>
</div>
</form>

I's thinking of using DOM remove method instead of removeChild method. Since you are already using getElementById so remove will do just fine.
function removeSchool() {
document.getElementById("school" + num_schools.toString()).remove(); // here changed removeChild method to remove
num_schools--;
if (num_schools == 1) {
document.getElementById("removeschool").remove(); // here changed removeChild method to remove
}
}
Remove DOM Element

IDs must be unique
Use type="button" or use preventDefault (you are submitting your form now on each click)
Delegate
Using
<button type="button" class="addschool">
<button type="button" class="removeschool">
and
document.getElementById("schools").addEventListener("click",function(e) {
const tgt = e.target;
if (tgt.classList.contains("removeschool")) {
tgt.closest("table").remove();
}
else if (tgt.classList.contains("addschool")) addSchool();
})
Also look into
clone templates
Here is a clone example. I renumber the schools whenever I add or remove one
I moved the add outside schools and remove to the header
const schools = document.getElementById("schools");
const firstSchool = document.getElementById("school1");
const renum = () => schools.querySelectorAll(".num").forEach((school,i) => school.innerText = (i+1))
function addSchool() {
const newSchool = firstSchool.cloneNode(true);
newSchool.querySelector(".removeschool").removeAttribute("hidden")
schools.appendChild(newSchool)
renum()
}
schools.addEventListener("click", function(e) {
const tgt = e.target;
if (tgt.classList.contains("removeschool")) {
tgt.closest("table").remove();
renum()
}
})
document.getElementById("addschool").addEventListener("click",addSchool);
div {
border: 1px solid black;
}
.maincol {
width: 50%;
}
.maincol>* {
margin-left: 20px;
}
.maincol>h2 {
margin-left: 0px;
}
#schools>table {
margin-bottom: 20px;
}
<h1>Resume Creator</h1>
<form>
<div class="maincol">
<h2>Identifying Information</h2>
<table>
<tr>
<td><label for="name">Full Name: </label></td>
<td><input type="text" id="name" name="name" size="50" /></td>
</tr>
<tr>
<td><label for="address">Address: </label></td>
<td><input type="text" id="address" name="address" size="50" /></td>
</tr>
<tr>
<td><label for="email">Email Address: </label></td>
<td><input type="text" id="email" name="email" size="50" /></td>
</tr>
<tr>
<td><label for="phone">Phone Number: </label></td>
<td><input type="text" id="phone" name="phone" size="50" /></td>
</tr>
</table>
</div>
<div class="maincol">
<h2>Skills</h2>
<p>Enter a comma-separated list of skills. E.g. Guest Services, Loss Prevention, Product Promotion, Etc.</p>
<textarea id="skill_list" rows=4 cols=90></textarea>
</div>
<div class="maincol">
<h2>Education</h2>
<div id="schools">
<table id="school1">
<tr>
<td colspan="2">School <span class="num">1</span><span style="float:right"><button type="button" hidden class="removeschool" >Remove</button></span></td>
</tr>
<tr>
<td><label for="schoolname1">School Name: </label></td>
<td><input type="text" id="schoolname1" size="50" /></td>
</tr>
<tr>
<td><label for="schoollocation1">Location: </label></td>
<td><input type="text" id="schoollocation1" size="50" /></td>
</tr>
<tr>
<td><label for="schoolyear1">Year Graduated: </label></td>
<td><input type="text" id="schoolyear1" size="50" /></td>
</tr>
<tr>
<td><label for="schooldegree1">Degree Earned: </label></td>
<td><input type="text" id="schooldegree1" size="50" /></td>
</tr>
</table>
</div>
<button type="button" id="addschool">Add School</button>
</div>
</form>

You need to specify for each button type = "button" so that it doesn't reload the page every time you press it. Like so :
<button id="removeschool" type = "button" onclick="removeSchool();">Remove School</button>.
Although I would suggest you put your buttons outside the table so that you don't have to add them with javascript every time you add/delete a school. (for the delete button just hide it when you have only one school and display it when you have multiple schools).
Also I think its better in the future to use classes instead of just adding plain strings to the HTML body. Your code would be cleaner and easier to edit.

Related

javascript equivalent to jquery closest().find()

<tr>
<td><input type="text" class="rate" oninput="priceChanged(this)"> </td>
<td><input type="text" class="quantity"></td>
<td><input type="text" class="total"> </td>
</tr>
I can find the quantity textbox with jquery-
var quantityTextbox = $('.rate').closest('tr').find('.quantity');
I would like to do it now with pure javascript.
I am newcomer in the pure javascript world.
Any idea?
You can use querySelector & .closest() for this like:
var quantityTextbox = document.querySelector('.rate').closest('tr').querySelector('.quantity')
console.log(quantityTextbox.value)
<table>
<tr>
<td><input type="text" class="rate" oninput="priceChanged(this)"> </td>
<td><input type="text" class="quantity" value="10"></td>
<td><input type="text" class="total"> </td>
</tr>
</table>
If you are calling this inside priceChanged() function, then you can use:
function priceChanged(rate){
var quantityTextbox = rate.closest('tr').querySelector('.quantity')
}
as you are already passing this inside priceChanged() function.
function priceChanged(rate) {
var quantityTextbox = rate.closest('tr').querySelector('.quantity')
console.log(quantityTextbox.value)
}
<table>
<tr>
<td><input type="text" class="rate" oninput="priceChanged(this)"> </td>
<td><input type="text" class="quantity" value="10"></td>
<td><input type="text" class="total"> </td>
</tr>
</table>

Automatic calculation from input fields

I want to construct some input forms that can calculate automatically. Provide below is my input forms.
var form = document.forms.myform,
pv1 = form.pv1,
pv2 = form.pv2,
output = form.pvtotal;
window.calculate = function () {
var p1 = parseInt(pv1.value, 10) || 0,
p2 = parseFloat(pv2.value) || 0;
output.value = (p1 + p2).toFixed(2);
};
<style>
table, th, td {
border: 1px solid black;
text-align: center;
border-collapse: collapse;
}
th {
color: black;
background: #f9f9f9;
font-size: 16px;
}
input[type=number]{
width: 50px;
}
</style>
<form action="" name="myform" onkeyup="calculate()">
<table>
<thead>
<tr>
<th colspan="3">PREV DAY STOCK</th>
<th colspan="3">CULL</th>
<th colspan="3">MORTALITY</th>
<th colspan="3">CURRENT STOCK</th>
</tr>
<tr>
<th>M</th>
<th>F</th>
<th>Total</th>
<th>M</th>
<th>F</th>
<th>Total</th>
<th>M</th>
<th>F</th>
<th>Total</th>
<th>M</th>
<th>F</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="number" name="pv1"></td>
<td><input type="number" name="pv2"></td>
<td><input type="number" name="pvtotal"></td>
<td><input type="number" name=""></td>
<td><input type="number" name=""></td>
<td><input type="number" name=""></td>
<td><input type="number" name=""></td>
<td><input type="number" name=""></td>
<td><input type="number" name=""></td>
<td><input type="number" name="" readonly></td>
<td><input type="number" name="" readonly></td>
<td><input type="number" name="" readonly></td>
</tr>
</tbody>
</table>
</form>
As you can see and try, i just provide the sum for previous stock. The main problem is I want all the column be automatic calculated except for the CURRENT STOCK column which i want this column calculated by:
(PREVIOUS STOCK - CULL - MORTALITY = CURRENT STOCK
Then, the other problem whenever i add one row below, all the script did not function anymore. I don't know why. I hope you guys can help me through this.
Below is my expected output:
table, th, td {
border: 1px solid black;
text-align: center;
border-collapse: collapse;
}
th {
color: black;
background: #f9f9f9;
font-size: 16px;
}
input[type=number]{
width: 50px;
}
div.scrollmenu {
overflow: auto;
}
h4 {
text-decoration: underline;
text-align: center;
line-height: 1.6;
}
<form action="dailyprod_action.php" method="post" name="myform" onkeyup="calculate()">
<table>
<thead>
<tr>
<th colspan="3">PREV DAY STOCK</th>
<th colspan="3">CULL</th>
<th colspan="3">MORTALITY</th>
<th colspan="3">CURRENT STOCK</th>
</tr>
<tr>
<th>M</th>
<th>F</th>
<th>Total</th>
<th>M</th>
<th>F</th>
<th>Total</th>
<th>M</th>
<th>F</th>
<th>Total</th>
<th>M</th>
<th>F</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="number" name="" value="1000"></td>
<td><input type="number" name="" value="1000"></td>
<td><input type="number" name="" value="2000"></td>
<td><input type="number" name="" value="200"></td>
<td><input type="number" name="" value="200" ></td>
<td><input type="number" name="" value="400"></td>
<td><input type="number" name="" value="200"></td>
<td><input type="number" name="" value="200"></td>
<td><input type="number" name="" value="400"></td>
<td><input type="number" name="" value="600" readonly></td>
<td><input type="number" name="" value="600" readonly></td>
<td><input type="number" name="" value="1200" readonly></td>
</tr>
<tr>
<td><input type="number" name="" value="2000"></td>
<td><input type="number" name="" value="2000"></td>
<td><input type="number" name="" value="4000"></td>
<td><input type="number" name="" value="400"></td>
<td><input type="number" name="" value="400" ></td>
<td><input type="number" name="" value="800"></td>
<td><input type="number" name="" value="400"></td>
<td><input type="number" name="" value="400"></td>
<td><input type="number" name="" value="800"></td>
<td><input type="number" name="" value="1700" readonly></td>
<td><input type="number" name="" value="1700" readonly></td>
<td><input type="number" name="" value="3400" readonly></td>
</tr>
</tbody>
</table>
</form>
You can develop my sample script and try
$("#pds_v1").keyup(function(){
var pds_v1 = $("#pds_v1").val();
var pds_v2 = $("#pds_v2").val();
var total= parseInt(pds_v2) + parseInt(pds_v1);
$("#pds_sum").val(total);
});
$("#pds_v2").keyup(function(){
var pds_v1 = $("#pds_v1").val();
var pds_v2 = $("#pds_v2").val();
var total= parseInt(pds_v2) + parseInt(pds_v1);
$("#pds_sum").val(total);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>
<table>
<tr>
<td><input type="number" name="" id="pds_v1"></td>
<td><input type="number" name="" id="pds_v2"></td>
<td><input type="number" name="" id="pds_sum"></td>
</tr>
</table>
I suggest you use JQuery as that will make your life easier, also there's not much difference between Javascript and JQuery syntax, so it'll be easy for you to learn if you know Javascript.
I moved your onkeyup event listener to the tr tag so you'll be able to do calculate() on every row. I also added this parameter on the calculate() function to get the element that fired that function and get all child from that element to change the output field of that row (the one that fired calculate() function).
Try this code below (this is only inputs for Previous Stock):
function calculate(elem) {
pv1 = $(elem).children()[0].children;
pv2 = $(elem).children()[1].children;
out = $(elem).children()[2].children;
var p1 = parseInt($(pv1).val(), 10) || 0;
var p2 = parseFloat($(pv2).val()) || 0;
$(out).val((p1 * p2).toFixed(2));
}
$('#add_field').click(function() {
$('#table_body').append(`
<tr onkeyup="calculate(this)" onchange="calculate(this)">
<td><input type="number" name="pv1" id="pv1"></td>
<td><input type="number" name="pv2" id="pv2"></td>
<td><input type="number" name="pvtotal" id="output"></td>
<td><input type="number" name=""></td>
<td><input type="number" name=""></td>
<td><input type="number" name=""></td>
<td><input type="number" name=""></td>
<td><input type="number" name=""></td>
<td><input type="number" name=""></td>
<td><input type="number" name="" readonly></td>
<td><input type="number" name="" readonly></td>
<td><input type="number" name="" readonly></td>
</tr>
`)
})
$('#remove_field').click(function() {
var len = ($('#table_body').children()).length - 1;
$('#table_body').children()[len].remove();
})
table,
th,
td {
border: 1px solid black;
text-align: center;
border-collapse: collapse;
}
th {
color: black;
background: #f9f9f9;
font-size: 16px;
}
input[type=number] {
width: 50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form action="" name="myform">
<table>
<thead>
<tr>
<th colspan="3">PREV DAY STOCK</th>
<th colspan="3">CULL</th>
<th colspan="3">MORTALITY</th>
<th colspan="3">CURRENT STOCK</th>
</tr>
<tr>
<th>M</th>
<th>F</th>
<th>Total</th>
<th>M</th>
<th>F</th>
<th>Total</th>
<th>M</th>
<th>F</th>
<th>Total</th>
<th>M</th>
<th>F</th>
<th>Total</th>
</tr>
</thead>
<tbody id="table_body">
<!-- I'm moving your event listener to the <tr> tag -->
<tr onkeyup="calculate(this)" onchange="calculate(this)">
<td><input type="number" name="pv1" id="pv1"></td>
<td><input type="number" name="pv2" id="pv2"></td>
<td><input type="number" name="pvtotal" id="output"></td>
<td><input type="number" name=""></td>
<td><input type="number" name=""></td>
<td><input type="number" name=""></td>
<td><input type="number" name=""></td>
<td><input type="number" name=""></td>
<td><input type="number" name=""></td>
<td><input type="number" name="" readonly></td>
<td><input type="number" name="" readonly></td>
<td><input type="number" name="" readonly></td>
</tr>
</tbody>
</table>
</form>
<button type="button" id="add_field">Add Field</button>
<button type="button" id="remove_field">Remove Field</button>

How to add multiple text boxes of currency using JavaScript when one could be empty?

I am attempting to build a form that only adds boxes together when the input is not empty. Thus far, I can get the form to work when at least two boxes are not empty. However, I can not seem to get the form to work when only one box has a value present.
I have tried adding an additional line to the code as follows:
else if (debit1 != "") {
totalDebit = parseFloat(debit1);
document.getElementById("debitTotal").value = totalDebit.toFixed(2);
}
However, this does not appear to work.
For some detail, I would still consider myself inexperienced with JavaScript, having only used it for form validation in the past. These validations mostly dealt with just required text boxes or drop down boxes so relatively simple things. I realize that a loop may be a better way to go about achieving these results but I am not yet familiar enough with those to attempt on my own.
CSS:
<style>
.Header
{
border: solid black 1px;
background-color: #a9e6fc;
padding: 5px;
text-align: center;
}
table
{
border-collapse: separate;
width: 100%;
border: 1px solid black;
}
table.ex1
{
table-layout: auto;
}
.actionButtons
{
border: solid black 1px;
padding: 5px;
overflow: auto;
background-color: #ff5b5b;
}
.submitButton
{
font-size: 16px;
float: left;
}
.cancelButton
{
font-size: 16px;
float: right;
}
</style>
HTML:
<!DOCTYPE HTML>
<html>
<head>
<title>GL Ticket</title>
</head>
<body>
<form name="myForm" method="post">
<table>
<tr>
<td>Account:</td><td>DEBIT</td><td>CREDIT</td><td>T/C</td><td>DATE</td><td>CHECK #</td><td>SPECIFIC G/L DESCRIPTION</td>
</tr>
<td><input type="text" id="OBKey__51_1" name="OBKey__51_1" size="15" maxlength="10"></td>
<td><input type="text" id="debit1" name="debit1" size="15" maxlength="10"></td>
<td></td>
<td><input type="text" size="5" maxlength="3"></td>
<td><input type="text" size="15" maxlength="10"></td>
<td><input type="text" size="10" maxlength="8"></td>
<td><input type="text" size="60" maxlength="40"></td>
<tr>
<td><input type="text" id="OBKey__51_2" name="OBKey__51_2" size="15" maxlength="10"></td>
<td></td>
<td><input type="text" id="credit1" name="credit1" size="15" maxlength="10"></td>
<td><input type="text" size="5" maxlength="3"></td>
<td><input type="text" size="15" maxlength="10"></td>
<td><input type="text" size="10" maxlength="8"></td>
<td><input type="text" size="60" maxlength="40"></td>
</tr>
<tr>
<td><input type="text" id="OBKey__51_3" name="OBKey__51_3" size="15" maxlength="10"></td>
<td><input type="text" id="debit2" name="debit2" size="15" maxlength="10" onblur="calculateDebits()"></td>
<td></td>
<td><input type="text" size="5" maxlength="3"></td>
<td><input type="text" size="15" maxlength="10"></td>
<td><input type="text" size="10" maxlength="8"></td>
<td><input type="text" size="60" maxlength="40"></td>
</tr>
<tr>
<td><input type="text" id="OBKey__51_4" name="OBKey__51_4" size="15" maxlength="10"></td>
<td></td>
<td><input type="text" id="credit2" name="credit2" size="15" maxlength="10" onblur="calculateCredits()"></td>
<td><input type="text" size="5" maxlength="3"></td>
<td><input type="text" size="15" maxlength="10"></td>
<td><input type="text" size="10" maxlength="8"></td>
<td><input type="text" size="60" maxlength="40"></td>
</tr>
<tr>
<td><input type="text" id="OBKey__51_5" name="OBKey__51_5" size="15" maxlength="10"></td>
<td><input type="text" id="debit3" name="debit3" size="15" maxlength="10" onblur="calculateDebits()"></td>
<td></td>
<td><input type="text" size="5" maxlength="3"></td>
<td><input type="text" size="15" maxlength="10"></td>
<td><input type="text" size="10" maxlength="8"></td>
<td><input type="text" size="60" maxlength="40"></td>
</tr>
<tr>
<td><input type="text" id="OBKey__51_6" name="OBKey__51_6" size="15" maxlength="10"></td>
<td></td>
<td><input type="text" id="credit3" name="credit3" size="15" maxlength="10" onblur="calculateCredits()"></td>
<td><input type="text" size="5" maxlength="3"></td>
<td><input type="text" size="15" maxlength="10"></td>
<td><input type="text" size="10" maxlength="8"></td>
<td><input type="text" size="60" maxlength="40"></td>
<td></td>
</tr>
<tr>
<td><input type="text" id="OBKey__51_7" name="OBKey__51_7" size="15" maxlength="10"></td>
<td><input type="text" id="debit4" name="debit4" size="15" maxlength="10" onblur="calculateDebits()"></td>
<td></td>
<td><input type="text" size="5" maxlength="3"></td>
<td><input type="text" size="15" maxlength="10"></td>
<td><input type="text" size="10" maxlength="8"></td>
<td><input type="text" size="60" maxlength="40"></td>
</tr>
<tr>
<td><input type="text" id="OBKey__51_8" name="OBKey__51_8" size="15" maxlength="10"></td>
<td></td>
<td><input type="text" id="credit4" name="credit4" size="15" maxlength="10" onblur="calculateCredits()"></td>
<td><input type="text" size="5" maxlength="3"></td>
<td><input type="text" size="15" maxlength="10"></td>
<td><input type="text" size="10" maxlength="8"></td>
<td><input type="text" size="60" maxlength="40"></td>
</tr>
<tr>
<td></td>
<td><input type="text" id="debitTotal" name="debitTotal"></td>
<td><input type="text" id="creditTotal" name="creditTotal"></td>
</tr>
</table>
<div class="actionButtons">
<input type="submit" class="submitButton" value="Save" name="OBBtn_Yes" onclick="return validateForm()">
<input type="reset" class="cancelButton" value="Reset" name="OBBtn_Reset">
</div>
</form>
</body>
</html>
JavaScript:
<script>
function validateForm()
{
var a = document.forms["myForm"]["debitTotal"].value;
var b = document.forms["myForm"]["creditTotal"].value;
if (a != b) {alert("NO MATCH.");
return false;
}
}
calculateDebits = function()
{
var debit1 = document.getElementById("debit1").value;
var debit2 = document.getElementById("debit2").value;
var debit3 = document.getElementById("debit3").value;
var debit4 = document.getElementById("debit4").value;
var totalDebit;
if (debit4 != "" && debit3 != "" && debit2 != "" && debit1 != "") {
totalDebit = parseFloat(debit4) + parseFloat(debit3) + parseFloat(debit2) + parseFloat(debit1);
document.getElementById("debitTotal").value = totalDebit.toFixed(2);
}
else if (debit3 != "" && debit2 != "" && debit1 != "") {
totalDebit = parseFloat(debit3) + parseFloat(debit2) + parseFloat(debit1);
document.getElementById("debitTotal").value = totalDebit.toFixed(2);
}
else if (debit2 != "" && debit1 != "") {
totalDebit = parseFloat(debit2) + parseFloat(debit1);
document.getElementById("debitTotal").value = totalDebit.toFixed(2);
}
}
calculateCredits = function()
{
var credit1 = document.getElementById("credit1").value;
var credit2 = document.getElementById("credit2").value;
var credit3 = document.getElementById("credit3").value;
var credit4 = document.getElementById("credit4").value;
var totalCredit;
if (credit4 != "" && credit3 != "" && credit2 != "" && credit1 != "") {
totalCredit = parseFloat(credit4) + parseFloat(credit3) + parseFloat(credit2) + parseFloat(credit1);
document.getElementById("creditTotal").value = totalCredit.toFixed(2);
}
else if (credit3 != "" && credit2 != "" && credit1 != "") {
totalCredit = parseFloat(credit3) + parseFloat(credit2) + parseFloat(credit1);
document.getElementById("creditTotal").value = totalCredit.toFixed(2);
}
else if (credit2 != "" && credit1 != "") {
totalCredit = parseFloat(credit2) + parseFloat(credit1);
document.getElementById("creditTotal").value = totalCredit.toFixed(2);
}
}
</script>
The result I would like to achieve is having these boxes always add and place a value in the debitTotal and creditTotal spots. These values will always be United States currency as well if that is helpful to know. I know it would likely be beneficial to have a way to check that a decimal exists from the third to last position of the debit and credit elements.
Thank you in advance for any assistance or conceptual understanding I get out of asking this question.
This sounds like you're looking for something like "sum" in excel.
First, give every element you want to sum a property that signals that.
For e.g. give your debits the class debit.
<td><input type="text" id="debit1" class="debit" name="debit1" size="15" maxlength="10"></td>
Now you can select them all using querySelectorAll:
let debits = document.querySelectorAll(".debit")
and loop through it (read about it, you will need it over and over again).
let debitValue = 0;
for (var debit in debits) {
if (debits.hasOwnProperty(debit) && debits[debit].value > 0) {
debitValue += debits[debit].value;
}
}
document.getElementById("debitTotal").value = debitValue;
Not tested but that should help you.

How to calculate sum of one field in table and put it in an input

I have a table in razor and I sent the data by ViewBag from controller
<table>
<thead>
<tr>
<th>Name</th>
<th>Category</th>
<th>Price</th>
<th>Count</th>
</tr>
</thead>
<tbody>
#foreach(var item in ViewBag.Products)
{
<tr>
<td>#item.Name</td>
<td>#item.Category</td>
<td>
<input type="text" class="form-control" value="#item.Price" />
</td>
<td>
<input type="text" class="form-controll" value="#item.Count" />
</td>
</tr>
}
</tbody>
</table>
<input type="text" class="form-control" value="#Model.TotalPrice" />
I want to multiple count and price of each row and put it in another input using javascript. and when the user change the value of input, that input that holds the value could change automatically.
if anyone can help me i would be appreciated.
If you are using jquery then it can be achieve as below.
You can update your total on every key press in price or count input.
Add some class to your input. In my example I've took class as price, and class total for display sum.
Add keyup event as below. Also trigger it on $(document).ready to initially set the total value.
$('.price').on('keyup', function() {
var val = +$(this).val();
var valSibling = +$(this).parent().siblings('td').find('.price').val();
if (isNaN(val) || isNaN(valSibling))
return;
$(this).parent().siblings('td').find('.total').val(val * valSibling);
var finaltotal = 0;
$('.total').each(function() {
if(!isNaN($(this).val()))
finaltotal += Number($(this).val());
});
$('.finaltotal').val(finaltotal);
});
$(document).ready(function(){
$('.price').trigger('keyup');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.3/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>Name</th>
<th>Category</th>
<th>Price</th>
<th>Count</th>
</tr>
</thead>
<tbody>
<tr>
<td>Name1</td>
<td>Category1</td>
<td><input type="text" class="price form-control" value="40" /></td>
<td><input type="text" class="price form-control" value="4" /></td>
<td><input type="text" class="total form-control" /></td>
</tr>
<tr>
<td>Name2</td>
<td>Category2</td>
<td><input type="text" class="price form-control" value="20" /></td>
<td><input type="text" class="price form-control" value="2" /></td>
<td><input type="text" class="total form-control" /></td>
</tr>
</tbody>
</table>
<input type="text" class="finaltotal form-control" />
var inputs = $('#container input');
inputs.keyup(function() {
var arr = inputs.toArray();
var sum = 0;
for (var i = 0; i < arr.length / 2; i++)
sum += arr[i * 2].value * arr[i * 2 + 1].value;
$('#result').val(sum);
})
table,
th,
td {
border: 1px solid black;
border-collapse: collapse;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>Count</th>
<th>Price</th>
<tr>
</thead>
<tbody id='container'>
<tr>
<td><input type='number' value='1' /></td>
<td><input type='number' value='2' /></td>
</tr>
<tr>
<td><input type='number' value='10' /></td>
<td><input type='number' value='20' /></td>
</tr>
</tbody>
</table>
Total: <input type='number' readonly id='result' readonly value='202' />
I want to multiple count and price of each row and put it in another input using javascript.
You can add another td in each tr. Then loop through all the tbody tr to calculate the value:
var tr = document.querySelectorAll('tbody tr');
function calculate(){
tr.forEach(function(el){
var td = el.querySelectorAll('td');
// If there is invalid number in input then no change in total.
if (isNaN(td[2].querySelector('input').value) || isNaN(td[3].querySelector('input').value))
return;
td[4].querySelector('input').value = td[2].querySelector('input').value * td[3].querySelector('input').value;
});
}
calculate();
.form-control{
width: 50px;
}
<table>
<thead>
<tr>
<th>Name</th>
<th>Category</th>
<th>Price</th>
<th>Count</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr>
<td>Name1</td>
<td>Category1</td>
<td><input type="text" oninput="calculate()" class="form-control" value="40" /></td>
<td><input type="text" oninput="calculate()" class="form-control" value="4" /></td>
<td><input type="text" class="form-control" /></td>
</tr>
<tr>
<td>Name2</td>
<td>Category2</td>
<td><input type="text" oninput="calculate()" class="form-control" value="20" /></td>
<td><input type="text" oninput="calculate()" class="form-control" value="2" /></td>
<td><input type="text" class="form-control" /></td>
</tr>
<tr>
<td>Name3</td>
<td>Category3</td>
<td><input type="text" oninput="calculate()" class="form-control" value="30" /></td>
<td><input type="text" oninput="calculate()" class="form-control" value="3" /></td>
<td><input type="text" class="form-control" /></td>
</tr>
</tbody>
</table>

How to load HTML table in div container? JQuery/JavaScript

I have navigation bar with two items so far. This can have more item potentially but for now I just need two. When user opens the page I want to load the content of the first item in my navigation bar. Each item has separate table. So on load first table should be loaded on the page. If user click on the different link I want that to show on the screen. I'm not sure what is the best approach/solution for this problem. Here is my HTML code:
<div class="container">
<section class="mainBox">
<h3>Home Page</h3>
<nav class="xNavigation">
Info 1 |
Info 2 |
</nav>
<div id="dataContainer">
//Here I want to load the tables
</div>
</section>
</div>
I already have built the tables on the page:
<table class="tab1Class" id="tab1Tbl">
<caption>Info 1</caption>
<tr>
<th>Last Name</th>
<th>First Name</th>
<th>DOB</th>
</tr>
<tr>
<td><input type="text" name="lname" id="lname" value="" size="20" maxlength="30" readonly /></td>
<td><input type="text" name="fname" id="fname" value="" size="20" maxlength="30" readonly /></td>
<td><input type="text" name="dob" id="dob" value="" size="10" maxlength="10" readonly /></td>
</tr>
</table>
<table class="tab2Class" id="tab2Tbl">
<caption>Info 2</caption>
<tr>
<th>Last Name</th>
<th>First Name</th>
<th>DOB</th>
</tr>
<tr>
<td><input type="text" name="lname2" id="lname2" value="" size="20" maxlength="30" readonly /></td>
<td><input type="text" name="fname2" id="fname2" value="" size="20" maxlength="30" readonly /></td>
<td><input type="text" name="dob2" id="dob2" value="" size="10" maxlength="10" readonly /></td>
</tr>
</table>
On page load I want to load first table. After that based on the users choice I want to load second table. In that case I'm not sure if table should be removed from the container or set to hide?
Here is my idea but that did not work:
function openTab(tblID){
$('.xNavigation a').each(function(i){
if(this.id == tblID){
$('#'+tblID).show();
}else{
$(this.id).hide();
}
});
}
If anyone can help with this problem please let me know.
Instead of adding unique ids for the tables, you could give them a data-id that matches the nav item's id and toggle based on that:
JS Fiddle
Simplify the JS
$('.xNavigation a').on('click', function() {
var id = $(this).prop('id');
$('#dataContainer > table[data-id=' + id + ']').show();
$('#dataContainer > table:not([data-id=' + id + '])').hide();
});
Start off by putting both tables where they belong, but hide the tables you don't want shown like:
CSS
#dataContainer > table:not([data-id="tab1"]) {
display: none;
}
HTML
<div class="container">
<section class="mainBox">
<h3>Home Page</h3>
<nav class="xNavigation">
Info 1 |
Info 2 |
</nav>
<div id="dataContainer">
<table class="tab1Class" data-id="tab1">
<caption>Info 1</caption>
<tr>
<th>Last Name</th>
<th>First Name</th>
<th>DOB</th>
</tr>
<tr>
<td>
<input type="text" name="lname" id="lname" value="" size="20" maxlength="30" readonly />
</td>
<td>
<input type="text" name="fname" id="fname" value="" size="20" maxlength="30" readonly />
</td>
<td>
<input type="text" name="dob" id="dob" value="" size="10" maxlength="10" readonly />
</td>
</tr>
</table>
<table class="tab2Class" data-id="tab2">
<caption>Info 2</caption>
<tr>
<th>Last Name</th>
<th>First Name</th>
<th>DOB</th>
</tr>
<tr>
<td>
<input type="text" name="lname2" id="lname2" value="" size="20" maxlength="30" readonly />
</td>
<td>
<input type="text" name="fname2" id="fname2" value="" size="20" maxlength="30" readonly />
</td>
<td>
<input type="text" name="dob2" id="dob2" value="" size="10" maxlength="10" readonly />
</td>
</tr>
</table>
</div>
</section>
</div>
Put your tables inside the div #dataContainer. No need to load them there, just show/hide the ones you want.
Give all tables the css class 'tabTable', and give the first one an extra class called 'active'
Each table already has a unique id, so nothing to do here, but it is important that they have one.
Use css to hide all elements with the tabTable class
Give all links that will cause tabs to change the class of tabLink and the attribute of data-opens="[id-of-table]" where [id-of-table] is the unique id of the table it opens.
Use the below JS
Here's a JSfiddle
JS
$(document).ready(function () {
$(document).on('click', '.xNavigation a.tabLink', function (evt) {
evt.preventDefault();
var opens = $(evt.target).data('opens');
$('.tabTable').removeClass('active');
var el = $('#' + opens).addClass('active');
});
});
CSS
.tabTable { display: none }
.tabTable.active {display: table} /* Cause we're using tables not divs */
HTML
<div class="container">
<section class="mainBox">
<h3>Home Page</h3>
<nav class="xNavigation">
Info 1 |
Info 2 |
</nav>
<div id="dataContainer">
<table class="tabTable active" id="tab1Tbl">
<caption>Info 1</caption>
<tr>
<th>Last Name</th>
<th>First Name</th>
<th>DOB</th>
</tr>
<tr>
<td><input type="text" name="lname" id="lname" value="" size="20" maxlength="30" readonly /></td>
<td><input type="text" name="fname" id="fname" value="" size="20" maxlength="30" readonly /></td>
<td><input type="text" name="dob" id="dob" value="" size="10" maxlength="10" readonly /></td>
</tr>
</table>
<table class="tabTable" id="tab2Tbl">
<caption>Info 2</caption>
<tr>
<th>Last Name</th>
<th>First Name</th>
<th>DOB</th>
</tr>
<tr>
<td><input type="text" name="lname2" id="lname2" value="" size="20" maxlength="30" readonly /></td>
<td><input type="text" name="fname2" id="fname2" value="" size="20" maxlength="30" readonly /></td>
<td><input type="text" name="dob2" id="dob2" value="" size="10" maxlength="10" readonly /></td>
</tr>
</table>
</div>
</section>
</div>
1.) Place both tables inside a hidden div.
2.) Call openTab with the table-id (tab1Tbl or tab2Tbl).
openTab(tabId):
1.) If there is a table in #dataContainer move him to the hidden div.
2.) Get the table with #tabId from the hidden div and move it to #dataContainer.

Categories