sorry for asking simple question. I am really a beginner in Javascript. I need to access my HTML array form object in my javascript, but I don't know how to do it.
The goal is to trigger the alert in javascript so the browser will display message according to the condition in javascript. Here is my code :
checkScore = function()
{
//I don't know how to access array in HTML Form, so I just pretend it like this :
var student = document.getElementByName('row[i][student]').value;
var math = document.getElementByName('row[i][math]').value;
var physics = document.getElementByName('row[i][physics]').value;
if (parseInt(math) >= 80 ) {
alert(student + " ,You are good at mathematic");
}
if (parseInt(physics) >= 80 ){
alert(student + " ,You are good at physics");
}
student_score.row[i][otherinfo].focus();
student_score.row[i][otherinfo].select();
}
<h2>HTML Forms</h2>
<form name="student_score" action="/action_page.php">
<table border=1>
<thead>
<td>Student</td>
<td>Math Score</td>
<td>Physics Score</td>
<td>Other info</td>
</thead>
<tbody>
<tr>
<td><input type="text" name="row[1][student]"></td>
<td><input type="number" name="row[1][math]" onblur="checkScore()" min="0" max="100"></td>
<td><input type="number" name="row[1][physics]" onblur="checkScore()" min="0" max="100"></td>
<td><input type="text" name="row[1][otherinfo]"></td>
</tr>
<tr>
<td><input type="text" name="row[2][student]"></td>
<td><input type="number" name="row[2][math]" onblur="checkScore()" min="0" max="100"></td>
<td><input type="number" name="row[2][physics]" onblur="checkScore()" min="0" max="100"></td>
<td><input type="text" name="row[2][otherinfo]"></td>
</tr>
<tr>
<td>
<input type="submit" value="Submit">
</td>
</tr>
</tbody>
</table>
</form>
<p>If you click the "Submit" button, it will save the data.</p>
We are going to leverage few things here to streamline this.
The first is Event Listeners, this removes all javascript from your HTML. It also keeps it more dynamic and easier to refactor if the table ends up having rows added to it via javascript.
Next is parentNode, which we use to find the tr that enclosed the element that was clicked;
Then we use querySelectorAll with an attribute selector to get our target fields from the tr above.
/*This does the work*/
function checkScore(event) {
//Get the element that triggered the blur
var element = event.target;
//Get our ancestor row (the parent of the parent);
var row = element.parentNode.parentNode;
//Use an attribute selector to get our infor from the row
var student = row.querySelector("[name*='[student]']").value;
var math = row.querySelector("[name*='[math]']").value;
var physics = row.querySelector("[name*='[physics]']").value;
var otherField = row.querySelector("[name*='[otherinfo]']");
if (parseInt(math, 10) >= 80) {
alert(student + " ,You are good at mathematic");
}
if (parseInt(physics, 10) >= 80) {
alert(student + " ,You are good at physics");
}
otherField.focus();
otherField.select();
}
/*Wire Up the event listener*/
var targetElements = document.querySelectorAll("input[name*='math'], input[name*='physics']");
for (var i = 0; i < targetElements.length; i++) {
targetElements[i].addEventListener("blur", checkScore);
}
<h2>HTML Forms</h2>
<form name="student_score" action="/action_page.php">
<table border=1>
<thead>
<tr>
<td>Student</td>
<td>Math Score</td>
<td>Physics Score</td>
<td>Other info</td>
</tr>
</thead>
<tbody>
<tr>
<td><input type="text" name="row[1][student]" class='student'></td>
<td><input type="number" name="row[1][math]" min="0" max="100"></td>
<td><input type="number" name="row[1][physics]" min="0" max="100"></td>
<td><input type="text" name="row[1][otherinfo]"></td>
</tr>
<tr>
<td><input type="text" name="row1[2][student]"></td>
<td><input type="number" name="row[2][math]" min="0" max="100"></td>
<td><input type="number" name="row[2][physics]" min="0" max="100"></td>
<td><input type="text" name="row[2][otherinfo]"></td>
</tr>
<tr>
<td>
<input type="submit" value="Submit">
</td>
</tr>
</tbody>
</table>
</form>
Well, it follows your line of code exactly as it is (because you said you do not want to change the code too much).
<h2>HTML Forms</h2>
<form name="student_score" action="/action_page.php">
<table border=1>
<thead>
<td>Student</td>
<td>Math Score</td>
<td>Physics Score</td>
<td>Other info</td>
</thead>
<tbody>
<tr>
<td><input type="text" name="row[1][student]"></td>
<td><input type="number" name="row[1][math]" onblur="checkScore(this)" min="0" max="100"></td>
<td><input type="number" name="row[1][physics]" onblur="checkScore(this)" min="0" max="100"></td>
<td><input type="text" name="row[1][otherinfo]"></td>
</tr>
<tr>
<td><input type="text" name="row1[2][student]"></td>
<td><input type="number" name="row[2][math]" onblur="checkScore(this)" min="0" max="100"></td>
<td><input type="number" name="row[2][physics]" onblur="checkScore(this)" min="0" max="100"></td>
<td><input type="text" name="row[2][otherinfo]"></td>
</tr>
<tr>
<td>
<input type="submit" value="Submit">
</td>
</tr>
</tbody>
</table>
</form>
JavaScript [Edited again using part of the #Jon P code, the query selector is realy more dynamic, and the value of the "other" field you requested is commented out]
//pass element to function, in html, only add [this] in parenteses
checkScore = function (element) {
//Get our ancestor row (the parent of the parent);
var row = element.parentNode.parentNode;
//Use an attribute selector to get our infor from the row
var student = row.querySelector("[name*='[student]']").value;
var math = row.querySelector("[name*='[math]']").value;
var physics = row.querySelector("[name*='[physics]']").value;
var other = row.querySelector("[name*='[otherinfo]']");
if (parseInt(math) >= 80) {
//other.value = student + " ,You are good at mathematic";
alert(student + " ,You are good at mathematic");
}
if (parseInt(physics) >= 80) {
//other.value = student + " ,You are good at physics";
alert(student + " ,You are good at physics");
}
otherField.focus();
otherField.select();
}
Tested :), and sorry about my english!
Try that, haven't tested it
var form = document.getElementsByName("student_score")[0];
var students = form.getElementsByTagName("tr");
for(var i = 0; i < students.length; i++){
var student = students[i].childnodes[0].value;
var math = students[i].childnodes[1].value;
var physics = students[i].childnodes[2].value;
if (parseInt(math) >= 80 ) {
alert(student + " ,You are good at mathematic");
}
if (parseInt(physics) >= 80 ){
alert(student + " ,You are good at physics");
}
}
Related
I have a table which lets users to add number of participants for an event. in it I used input type number field to get number of participants. then I calculate how much fee they have to pay for each passenger type. I have 3 passenger types.
My table looks like this,
I use keyup mouseup bind to get the input value by user and multiplied it with fee for one participant.
var totalAdults;
jQuery("#number_adults").bind('keyup mouseup', function () {
var numOfAdults = jQuery("#number_adults").val();
totalAdults = numOfAdults * adultFee;
});
I have 3 of above functions to calculate and real time display how much fee that they have to pay in each passenger type.
Now I need to get the total sum of all three passenger type fees and display/update it in real time to the user, at the end of my table.
I tried making each passenger type total value global and calculating it's sum, but I get an error saying missing semicolon error linked to this MDN article
I'm stuck here. how can I get total value on all three passenger types outside their respective functions and display that value correctly in real time? (when they update number of passengers, total for passenger type is changing, I need to change final total accordingly). please help
Update:
this is the html table that I used. this get repeated another two times for other two passenger types.
var adultFee = 150;
var finalTotal = 0;
jQuery("#number_adults").bind('keyup mouseup', function() {
var numOfAdults = jQuery("#number_adults").val();
totalAdults = numOfAdults * adultFee;
jQuery("#adult_amount").html(totalAdults);
// console.log(totalAdults);
finalTotal = finalTotal + totalAdults;
console.log(finalTotal);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<tr>
<td style="font-weight: 600;">Adult</td>
<td id="adult_price" name="adult_price">150.00</td>
<td>
<input id="number_adults" max="3" min="1" name="number_adults" type="number" value="0" class="form-control">
</td>
<td name="amount">
<p id="adult_amount"></p>
</td>
</tr>
This is how I tried to get the final total, it doesn't display any result
jQuery(document).on('change', '#adult_amount', function() {
finalTotal = finalTotal+totalAdults;
alert(finalTotal);
});
I made a working example for you.
$('.inputs').each(function(){
$(this).on('change keyup', function(){
let sumTotal = 0;
$('.inputs').each(function(){
sumTotal += $(this).val() * +$(this).parent().next().data('price');
});
$('.total').text(`${sumTotal} $`);
});
});
td:nth-child(3),
th:nth-child(3){
text-align:center;
}
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>
<body>
<div class="container">
<div class="row justify-content-center">
<div class="col-12">
<table class="table table-hover">
<thead>
<tr>
<th></th>
<th>QTY</th>
<th>Amount</th>
</tr>
</thead>
<tbody>
<tr>
<td>Child</td>
<td><input type="number" class="inputs form-control" value="0" min="0" max="999"></td>
<td class="price" data-price="150">150 $</td>
</tr>
<tr>
<td>Adult</td>
<td><input type="number" class="inputs form-control" value="0" min="0" max="999"></td>
<td class="price" data-price="200">200 $</td>
</tr>
<tr>
<td>Adult Plus</td>
<td><input type="number" class="inputs form-control" value="0" min="0" max="999"></td>
<td class="price" data-price="250">250 $</td>
</tr>
<tr>
<td>Total - </td>
<td></td>
<td class="total">0.00 $</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
(https://codepen.io/bichiko/pen/JQWomy)
Here is a solution which should do what you need.
Compared to your code, the key changes are:
Use classes instead of IDs to identify the elements within each row. This means you can handle changes to all your fields using the same event handling code. I've given all your quantity fields the .qty class, and then bound the event to that class, so all elements with that class will run the same function.
Within the function, I've stripped out all direct references to fields - instead, to get the price field, and the total field for the relevant type, the code uses the positions of the fields relative to each other in the page, it uses the .parent(), .next(), and .prev() functions to find the total and amount fields which are within the same table row as the altered quantity field (which will always be this inside the event handler), so that it does the calculations on the right fields.
To calculate the final overall total, I've defined a separate function. Again this uses a class selector to identify all the "amount" fields, and add each of those values together to get the total. Since this function is triggered at the end of the event handler, it will always update the grand total whenever one of the quantities is updated.
Other minor changes:
use .on() instead of the deprecated .bind()
jQuery(".qty").on('keyup mouseup', function() {
var tdElement = jQuery(this).parent();
var qty = parseInt(this.value);
var fee = parseFloat(tdElement.prev(".price").text());
var typeTotal = qty * fee;
tdElement.next(".amount").html(typeTotal);
calcFinalTotal();
});
function calcFinalTotal()
{
var finalTotal = 0;
$(".amount").each(function() {
finalTotal += parseFloat($(this).text());
});
$("#total").text(finalTotal);
}
td, th
{
border: solid 1px #cccccc;
padding: 5px;
text-align:left;
}
table {
border-collapse: collapse;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<th>Passenger Type</th>
<th>Price</th>
<th>Quantity</th>
<th>Total</th>
<tr>
<th>Adult</th>
<td class="price">150.00</td>
<td>
<input max="3" min="1" name="number_adults" type="number" value="0" class="form-control qty">
</td>
<td class="amount">0
</td>
</tr>
<tr>
<th>Type 2</th>
<td class="price" id="type3_price">200.00</td>
<td>
<input max="3" min="1" name="number_type" type="number" value="0" class="form-control qty">
</td>
<td class="amount">0
</td>
</tr>
<tr>
<th>Type 3</th>
<td class="price" id="type3_price">200.00</td>
<td>
<input max="3" min="1" name="number_type" type="number" value="0" class="form-control qty">
</td>
<td class="amount">0
</td>
</tr>
<tr>
<th colspan="3">Grand Total</th>
<td id="total"></td>
</tr>
</table>
You can simply loop on every rows on the table and calculate the total sum and also the individual. Here i done by the dynamic method. if the total of each passenger is inserted in a unique input, then you can access from that input. Otherwise please follow the method
$(document).on('keyup mouseup','.qty', function() {
calculate();
});
function calculate(){
var finalTotal = 0;
var old = 0;
var mature = 0;
var adult = 0;
$('.qty').each(function(key,value){
$qty = $(this).val();
$type = $(this).attr('data-type');
$amount = $(this).parent().siblings('.adult_price').html();
$total = Number($qty) * parseFloat($amount);
$(this).parent().siblings('.amount').html($total);
finalTotal += $total;
if($type == 'adult')
adult += parseFloat($total);
else if($type == 'mature')
mature += parseFloat($total);
else if($type == 'old')
old += parseFloat($total);
});
$('.grandTotal').html(finalTotal);
// console.log('Adult',adult);
// console.log('Mature',mature);
// console.log('Old',old);
}
table {
border-collapse: collapse;
width: 80%;
}
th, td {
text-align: left;
padding: 8px;
}
tr:nth-child(even){background-color: #f2f2f2}
th {
background-color: #4CAF50;
color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>Passenger Types</th>
<th>Amount</th>
<th>Qty</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr>
<td><b>Adult</b></td>
<td class="adult_price" name="adult_price">150.00</td>
<td>
<input max="3" min="1" name="number_adults" type="number" value="0" class="form-control qty" data-type="adult">
</td>
<td name="amount" class='amount'></td>
</tr>
<tr>
<td><b>Mature</b></td>
<td class="adult_price" name="adult_price">200.50</td>
<td>
<input max="3" min="1" name="number_adults" type="number" value="0" class="form-control qty" data-type="mature">
</td>
<td name="amount" class='amount'></td>
</tr>
<tr>
<td><b>Old</b></td>
<td class="adult_price" name="adult_price">150.00</td>
<td>
<input max="3" min="1" name="number_adults" type="number" value="0" class="form-control qty" data-type="old">
</td>
<td name="amount" class='amount'></td>
</tr>
<tr>
<td colspan="3"><b>Grand Total</b></td>
<td class='grandTotal'>100</td>
</tr>
</tbody>
</table>
jQuery is very flexible use class instead of id. If you use inputs, selects, etc you should delegate the input or change event to them.
$('input').on('input', function() {...
input event will trigger as soon as user types or selects on or to an input tag. change event will trigger when a user types or selects on or to an input and then clicks (unfocus or blur event) elsewhere.
The HTML is slightly modified for consistency. Note that there are 2 extra inputs per <tr>.
When using input inside tables you can traverse the DOM by first referencing the imputed/changed/clicked tag as $(this) then climb up to the parent <td> and from there either go to the next <td> using .next() or go to the previous <td> using .prev(). Once you get to a neighboring <td> use .find() to get the input within. When extracting a number from an input it is normally a string but with jQuery method .val() it should extract input value as a number automatically. Details commented in demo.
/*
//A - Any tag with the class of .qty that the user inputs data into triggers a function
//B - Get the value of the imputed .qty (ie $(this))
//C - reference $(this) parent <td> go to the next <td> then find a tag with the class .price and get its value
//D - reference $(this) parent <td> go to the previous <td> then find a tag with the class of .total then set its value to the product of qty and price and fix it with hundredths (.00 suffix)
//E - Declare an empty array
//F - Get the value of each .total, convert it into a number then push the number into the empty array
//G - Use .reduce() to get the sum of all values within the array then fix it with hundredths (.00 suffix) and set it as the value of .grand
*/
$('.qty').on('input', function() { //A
var qty = $(this).val(); //B
var price = $(this).parent().prev('td').find('.price').val(); //C
$(this).parent().next('td').find('.total').val((qty * price).toFixed(2)); //D
var totals = []; //E
$('.total').each(function() {
totals.push(Number($(this).val()));
}); //F
$('.grand').val(totals.reduce((sum, cur) => sum + cur).toFixed(2)); //G
});
table {
table-layout: fixed;
}
td {
width: 6ch
}
[readonly] {
border: 0;
width: 6ch;
text-align: right
}
[type=number] {
text-align: right
}
<table>
<tr>
<td style="font-weight: 600;">Adult</td>
<td><input class="price" name='price' value='150.00' readonly></td>
<td>
<input class="qty" name="qty" min="0" max="3" type="number" value="0" class="form-control">
</td>
<td>
<input class="total" name='total' readonly>
</td>
</tr>
<tr>
<td style="font-weight: 600;">Senior</td>
<td><input class="price" name='price' value='100.00' readonly></td>
<td>
<input class="qty" name="qty" min="0" max="3" type="number" value="0" class="form-control">
</td>
<td>
<input class="total" name='total' readonly>
</td>
</tr>
<tr>
<td style="font-weight: 600;">Child</td>
<td><input class="price" name='price' value='75.00' readonly></td>
<td>
<input class="qty" name="qty" min="0" max="3" type="number" value="0">
</td>
<td>
<input class="total" name='total' readonly>
</td>
</tr>
<tr>
<td colspan='3' style='text-align:right;'>Total</td>
<td><input class='grand' name='grand' value='0' readonly></td>
</table>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
This is axample of yours problem, try using object
var data = {a:0, b:0, c: 0}
function one (){
data.a = data.a + 10
console.log(data.a)
total()
}
function two (){
data.b = data.b + 10
total()
console.log(data.b)
}
function three () {
data.c = data.c + 30
total()
console.log(data.c)
}
function total () {
var totaly = data.a + data.b + data.c
console.log('Total input :', totaly)
}
<button onclick="one()"> get A </button>
<button onclick="two()"> get B</button>
<button onclick="three()"> get C </button>
I have a input element to accept number type. I know javascript takes input as a string. so I am using parseInt() to convert into integer. but it is not working.
My code is:
<tr>
<td rowspan="6"><br><br><br><br><br>B1<br> Salary/Pension:</td>
<td>(1) Salary (excluding all allowances, perquisites and profit in lieu of salary</td>
<td><input type="text" id="sal" value="0" name="sal" placeholder="" class="form-control "></td>
</tr>
<tr>
<td>(2) Allowances not exempt</td>
<td><input type="text" id="allowance" value="0" name="allowance" placeholder="" class="form-control "></td>
</tr>
<tr>
<td>(3)Value of perquisites</td>
<td><input type="text" id="perquisites" value="0" name="perquisites" placeholder="" class="form-control "></td>
</tr>
<tr>
<td>(4) Profits in lieu of salary</td>
<td><input type="text" id="profit" name="profit" value="0" placeholder="" class="form-control"></td>
</tr>
<tr>
<td>(5)Deduction u/s 16</td>
<td><input type="text" id="ded16" name="ded16" value="0" placeholder="" class="form-control"></td>
</tr>
<tr>
<td>(6)Income chargable under the head 'Salaries':</td>
<td><input type="text" id="inchargesal" value="0" name="inchargesal" placeholder="" class="form-control" readonly></td>
</tr>
//js part is:
$(document).ready(function() {
function change() {
f = a + b + c + d - e;
alert(f);
$('#inchargesal').removeAttr('readonly').val(f);
}
$('#sal').on('change', function() {
var a = parseInt(document.getElementsById("sal").value);
alert("hi");
change();
});
$('#allowance').on('change', function() {
b = parseInt(document.getElementById("allowance").value)
change();
});
$('#perquisites').on('change', function() {
c = parseInt(document.getElementsById("perquisites").value);
change();
});
$('#profit').on('change', function() {
d = parseInt(document.getElementsById("profit").value);
change();
});
$('#ded16').on('change', function() {
e = parseInt(document.getElementsById("ded16").value);
change();
});
});
here to notice is, when I use alert("hi") above the parseInt statement then alert works fine, however when I use it after that, alert("hi") doesn't work.
what's going wrong? please help.
You are using incorrect method of document. There is no such method saying getElementsById(). In HTML DOM the id field is unique so it can never be getElements but getElement. Use getElementById('id') to make it work.
Also its always better to check console first where most of your problems can be resolved on your own.
Console -
I have a form that uses the onsubmit event.
Tested in MS Blade, Chrome Version 67, Firefox Version 60 and the event works as expected.
This means a dialogue box appears and asks "do you wish to proceed with the order and lists the item and value". With options to select "ok" or "cancel".
Tested in IE11 and the event fires but goes directly to the cancel option and reloads the page.
<form onsubmit="confirmBox()" action="#" name="order_form" id="order_form">
<table>
<tr>
<td>Price</td>
<td><div id="divPriceObj"></div></td>
<td><input type="hidden" name="price" id="price" value=""></td>
</tr>
<tr>
<td><label>Quantity</label></td>
<td><input type="number" name="quantity" id="quantity" min="1" value="1"></td>
<td>REQUIRED FIELD</td>
<td><input type="hidden" name="description" id="description" value=""></td>
</tr>
<tr>
<td><label>Total Price</label></td>
<td><div id="totalPrice"></div></td>
</tr>
<tr>
<td><button type="button" onclick="resetQuantity()">Clear</button></td>
<td><button type="button" onclick="calculateTotal()">Calculate Total</button></td>
<td><input type="submit" name="submit" id="submit" value="Submit" /></td>
</tr>
</table>
</form>
The Javascript involved is
function confirmBox() {
var itemDesc = setDesc(getUrlVars()["description"]);
var itemPrice = document.forms["order_form"]["price"].value;
var itemQuantity = document.forms["order_form"]["quantity"].value;
var itemTotal = itemPrice * itemQuantity;
//check if form data is valid still
if (validateForm(price, quantity)) {
var x = document.forms["order_form"]["price"].value;
var y = document.forms["order_form"]["quantity"].value;
var z = getUrlVars()["desc"];
if (confirm('Do you wish to Proceed with the order of '
+ itemQuantity
+ ' ' + itemDesc
+ ' valued at $'
+ itemTotal + '?')) {
close();
} else {
resetQuantity();
}
} else {
//do nothing
//close();
}
}
I have not been able to fix this bug, does anyone have a solution?
I have a a table with inputs inside each table cell like so:
<table width="300" border="1" align="center" id="mainTable">
<tr>
<td><input onkeyup="insertToArray(value)" size="1" maxlength="1" /></td>
<td><input onkeyup="insertToArray(value)" size="1" maxlength="1" /></td>
<td><input onkeyup="insertToArray(value)" size="1" maxlength="1" /></td>
<td><input onkeyup="insertToArray(value)" size="1" maxlength="1" /></td>
</tr>
</table>
I would like to know how to obtain the location (row and column) of an input within the table (using javascript). I know how to do it for a regular cell with nothing inside, but for an input within the cell I can't seem to find a way. The function inside the input is for another purpose.
Modify the call to the function insertToArray(value) to insertToArray(this) and then inside the function do
function insertToArray(elem){
...
var tdElem = elem.parentNode;
var trElem = tdElem.parentNode;
console.log("Row: " + trElem.rowIndex);
console.log("Column: " + tdElem.cellIndex);
...
}
If you are able to get a reference to the table cell, then you just have to get access to the children inside of that node.
You can use `childNodes' which returns a NodeList object and then you use the index to access the children so in your case, the input box.
example:
document.getElementById("firstTableCell").childNodes[0].value;
I adopted the following approach, though it uses the keyup listener from jquery:
HTML:
<table width="300" border="1" align="center" id="mainTable">
<tr>
<td><input size="1" maxlength="1" /></td>
<td><input size="1" maxlength="1" /></td>
<td><input size="1" maxlength="1" /></td>
<td><input size="1" maxlength="1" /></td>
</tr>
<tr>
<td><input size="1" maxlength="1" /></td>
<td><input size="1" maxlength="1" /></td>
<td><input size="1" maxlength="1" /></td>
<td><input size="1" maxlength="1" /></td>
</tr>
</table>
JS:
$("#mainTable input").keyup(function() {
var colIndex = $(this).parent()[0].cellIndex;
var rowIndex = $(this).parent()[0].parentElement.rowIndex;
})
Hope this helps!
It can be done in different ways, the code I included here is just to help you understand it better and depending on what you want to do, this is a nice easy approach to your issue. You can get the indexes instead, again, it depends on what you want to do.
HTML:
<table width="300" border="1" align="center" id="mainTable">
<tr class="row1">
<td><input class="tableCell" id="cell1" size="1" maxlength="1" /></td>
<td><input class="tableCell" id="cell2" size="1" maxlength="1" /></td>
<td><input class="tableCell" id="cell3" size="1" maxlength="1" /></td>
<td><input class="tableCell" id="cell4" size="1" maxlength="1" /></td>
</tr>
</table>
JS
window.onload = function() {
var cells = document.getElementsByClassName("tableCell");
for (var x = 0; x < cells.length; x++) {
cells[x].addEventListener("keyup", function(e) {
// get row class name:
var rowClass = (e.target).parentElement.parentElement.className;
alert("Row classname: " + rowClass);
// get the value insede the cell:
var cellValue = (e.target).value;
alert("Value entered: " + cellValue);
var cellId = e.target.id;
alert("Cell ID: " + cellId);
});
}
You could use a utility method that to looks for the closest parent
using a tag name:
Here's an example
function getClosestParent( needle, haystack ) {
var parent = null;
var target = needle.toUpperCase();
var element = haystack.parentElement;
while ( parent == null ) {
if ( element !== null ) {
if ( element.tagName === target ) {
parent = element;
}
}
else {
break;
}
element = element.parentElement;
}
return parent;
}
document.querySelector("input").addEventListener("click", function() {
var row = getClosestParent("tr", this)
var column = getClosestParent("td", this)
alert(row);
alert(column);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table width="300" border="1" align="center" id="mainTable">
<tr>
<td><input onkeyup="insertToArray(value)" size="1" maxlength="1" /></td>
</tr>
</table>
I've figured out a great way to do it.
I have 2 global variables representing the column and the row objects (tr, td)
function returnParent(x)
{
parentOfInput = x.parentNode; //td level
parentOfTd = parentOfInput.parentNode; //tr level
}
And I call this function alongside the other as well like so (note that I call returnParent() first since I want the position first thing when I enter something in input):
<table width="300" border="1" align="center" id="mainTable">
<tr>
<td><input onkeyup="returnParent(this); insertToArray(value);" size="1" maxlength="1" /></td>
<td><input onkeyup="returnParent(this); insertToArray(value);" size="1" maxlength="1" /></td>
<td><input onkeyup="returnParent(this); insertToArray(value);" size="1" maxlength="1" /></td>
<td><input onkeyup="returnParent(this); insertToArray(value);" size="1" maxlength="1" /></td>
Finally in my insertToArray(value) function, I get the column and row like so:
function insertToArray(value)
{
var a = value;
//get the cell position using parentNode
tableCol = parentOfInput.cellIndex;
tableRow = parentOfTd.rowIndex;
}
Again with this one I have no idea what to call it but I will attempt to explain it the best I can.
I created a question similar to this before that did get answered but only because I wasn't 100% sure what I was looking for. Now I have worked out what I need etc..
So I have created this example, you will see that there are multiple inputs but they only work in the first column (due to no knowing how to make the others work). So now I need to get that working in ALL other columns using the same functions.
EXAMPLE
HTML:
<table>
<tr>
<th></th>
<th>Option1</th>
<th>Option2</th>
<th>Option3</th>
<th>Option4</th>
</tr>
<tr>
<td>Money</td>
<td><input type="number" id="money" /></td>
<td><input type="number" /></td>
<td><input type="number" /></td>
<td><input type="number" /></td>
</tr>
<tr>
<td>Upfront</td>
<td><input type="number" id="upfront" /></td>
<td><input type="number" /></td>
<td><input type="number" /></td>
<td><input type="number" /></td>
</tr>
<tr>
<td>Overall Price</td>
<td id="overallPrice"></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Discount</td>
<td><input type="number" id="discount" /></td>
<td><input type="number" /></td>
<td><input type="number" /></td>
<td><input type="number" /></td>
</tr>
<tr>
<td>Dicount Price</td>
<td id="discountPrice"></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>
Javascript/jQuery:
$(document).ready(function () {
$('input').keyup(function () {
overallPrice();
discountPrice();
});
});
function overallPrice() {
var cal1, cal2, result;
cal1 = parseFloat(document.getElementById("money").value);
cal2 = parseFloat(document.getElementById("upfront").value);
result = cal1 - cal2;
document.getElementById("overallPrice").innerHTML = "£" + result;
return result;
}
function discountPrice() {
var cal1, cal2, result;
cal1 = parseFloat(document.getElementById("discount").value);
cal2 = overallPrice();
result = cal2 - cal1;
document.getElementById("discountPrice").innerHTML = "£" + result;
}
So we have 2 inputs that will create the "Overall Price" and then the 3rd input will take that number and give the "Discount Price". If this was just 1 single column I could do it no problem but as I need this to work for all of the columns I'm not sure how I can do this using the same functions.
Hope this made some sort of sense if not let me know and I will try explain some more.
Here is a link to my other question, I added this part onto the end of it just encase you want to see where I started etc.
Other Question
*Note: There will be more then 2 sets of inputs, this is just an example. In my real version some of the inputs will not be used for certain columns and I will have to change some function to calculate certain columns differently. *
Here's another solution: FIDDLE
The idea is to find out which column the input is in (using .index()) and hand that index on to the overallPrice() and discountPrice() functions.
HTML
<table>
<tr>
<th></th>
<th>Option1</th>
<th>Option2</th>
<th>Option3</th>
<th>Option4</th>
</tr>
<tr id="money">
<td>Money</td>
<td><input type="number"/></td>
<td><input type="number" /></td>
<td><input type="number" /></td>
<td><input type="number" /></td>
</tr>
<tr id="upfront">
<td>Upfront</td>
<td><input type="number"/></td>
<td><input type="number" /></td>
<td><input type="number" /></td>
<td><input type="number" /></td>
</tr>
<tr id="overallPrice">
<td>Overall Price</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr id="discount">
<td>Discount</td>
<td><input type="number"/></td>
<td><input type="number" /></td>
<td><input type="number" /></td>
<td><input type="number" /></td>
</tr>
<tr id="discountPrice">
<td>Dicount Price</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>
JavaScript
$(document).ready(function () {
$('input').change(function () {
var $this = $(this),
$row = $this.closest('tr'),
$column = $this.closest('td'),
columnIndex = $row.find('td').index($column[0]);
//overallPrice(columnIndex);
discountPrice(columnIndex);
});
});
function overallPrice(column) {
var cal1, cal2, result;
cal1 = parseFloat($('#money td').eq(column).find('input').val() || '0');
cal2 = parseFloat($('#upfront td').eq(column).find('input').val() || '0');
result = cal1 - cal2;
$('#overallPrice td').eq(column).text("£" + result);
return result;
}
function discountPrice(column) {
var cal1, cal2, result;
cal1 = parseFloat($('#discount td').eq(column).find('input').val() || '0');
cal2 = overallPrice(column);
result = cal2 - cal1;
$('#discountPrice td').eq(column).text("£" + result);
}
Try giving a custom attribute to the individual cells(I've used count) and then accessing all the cells in the same column using that attribute(using the parentElement.childNodes thing wouldn't work because the parent in this instance would be the row, and not the column). I've passed the count value to your overallPrice and discountPrice functions, and modified the HTML a bit.
SCRIPT
$(document).ready(function () {
$('input').keyup(function () {
discountPrice(this.attributes.count.value);
});
});
function discountPrice(n) {
var cal1, cal2, result;
cal1 = parseFloat(document.getElementsByClassName("discount")[n-1].value);
cal2 = overallPrice(n);
result = cal2 - cal1;
document.getElementsByClassName("discountPrice")[n-1].innerHTML = "£" + result;
}
function overallPrice(n) {
var cal1, cal2, result;
cal1 = parseFloat(document.getElementsByClassName("money")[n-1].value);
cal2 = parseFloat(document.getElementsByClassName("upfront")[n-1].value);
result = cal1 - cal2;
document.getElementsByClassName("overallPrice")[n-1].innerHTML = "£" + result;
return result;
}
HTML Your rows should look like this:
<tr>
<td>Overall Price</td>
<td count="1" class="overallPrice"></td>
<td count="2" class="overallPrice"></td>
<td count="3" class="overallPrice"></td>
<td count="4" class="overallPrice"></td>
</tr>
FIDDLE
Edit: This can be done even without adding a new(count) attribute. Instead of passing the this.attributes.count.value to the two price functions, you can do:
$('input').change(function () {
discountPrice($(this).parent().prevAll().length);
});
FIDDLE2