I have then following table:
<table style="width:100%" id="testTable">
<tr>
<th>length per</th>
<th>width per</th>
<th>length</th>
<th>width</th>
<th>total</th>
</tr>
<tr align='right'>
<td>
<input type="text" name="length-per-input">
</td>
<td>
<input type="text" name="width-per-input">
</td>
<td>
<input type="text" name="length-total-input">
</td>
<td>
<input type="text" name="width-total-input">
</td>
<td>
<input type="text" name="total-output" disabled="disabled">
</td>
</tr>
<tr align='right'>
<td>
<input type="text" name="length-per-input">
</td>
<td>
<input type="text" name="width-per-input">
</td>
<td>
<input type="text" name="length-total-input">
</td>
<td>
<input type="text" name="width-total-input">
</td>
<td>
<input type="text" name="total-output" disabled="disabled">
</td>
</tr>
</table>
<input type=button value='+' onclick="addRow()" />
<input type=button value='Calculate' onclick="Calculate()" />
I also have the javascript which adds the value and puts it in total:
<script>
function Calculate() {
var lengthPerInput = $("input[name='length-per-input']").val();
var widthPerInput = $("input[name='width-per-input']").val();
var lengthTotal = $("input[name='length-total-input']").val();
var widthTotal = $("input[name='width-total-input']").val();
var total = (lengthTotal/lengthPerInput) + (widthTotal/widthPerInput);
$("input[name='total-output']").val(total);
}
</script>
The aim here is to have it iterate over the two rows, then add each one separately.
I know how to get each row by using:
$('#testTable tr').each(function(){
console.log(this);
$(this).find('length-per-input').each(function(){
console.log(this);
})
})
But using the row (accessed via "this") I don't know how to get the correct cells, get their value, then perform the calculate on that row for the total.
Any advice on this please? Thank you!
function Calculate(tr_row) {
var lengthPerInput = tr_row.find("input[name='length-per-input']").val();
var widthPerInput = tr_row.find("input[name='width-per-input']").val();
var lengthTotal = tr_row.find("input[name='length-total-input']").val();
var widthTotal = tr_row.find("input[name='width-total-input']").val();
var total = (lengthTotal/lengthPerInput) + (widthTotal/widthPerInput);
tr_row.find("input[name='total-output']").val(total);
}
For every row you call function to summ the values
To the function you pass the row, then it can collect values on that row
$('#testTable tr').each(function(){
Calculate($(this))
})
You can use each() function to iterate through table and use find() function to find cell values.
function Calculate() {
$('#testTable tr').each(function() {
var lengthPerInput = $(this).find("input[name='length-per-input']").val();
var widthPerInput = $(this).find("input[name='width-per-input']").val();
var lengthTotal = $(this).find("input[name='length-total-input']").val();
var widthTotal = $(this).find("input[name='width-total-input']").val();
var total = (lengthTotal/lengthPerInput) + (widthTotal/widthPerInput);
$(this).find("input[name='total-output']").val(total);
});
}
Working Plunker
How to get a table cell value using jQuery?
Related
The script below creates a new line of text boxes and a button. However, when the button is clicked, the new field would like to have new button text and a new design.
$(function () {
var newRow = $(".addRows").clone();
$("#addButton").on("click", function () {
let row = newRow.clone().appendTo("#TextBoxesGroup tbody");
$("tr").find("#addButton").css( "border-color", "red" );
});
});
<table id="TextBoxesGroup">
<tr class="addRows">
<td>Start Date:</td>
<td>
<input type="text" name="StartDate[]" class="picker" value="" size="6">
</td>
<td>End Date:</td>
<td>
<input type="text" name="EndDate[]" class="picker" value="" size="6">
</td>
<td>
<input type="button" id="addButton" value="add row" />
</td>
</tr>
</table>
<script type = "text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
For example, the created new button should be with text delete and color red.
Thanks for the help or recommendation
I think using templates might make it easier and cleaner to modify the elements. Here is a quick guide for basic templating with vanillajs https://gomakethings.com/html-templates-with-vanilla-javascript/
This allows you to easily pass in IDs for your inputs.
I am not sure if you are just trying to toggle a second row or add multiple rows. If you simply want to toggle the second row and not add more than that then only use the second part of the js, and remove the first template. Likewise if you want to add multiple you can remove the second part (currently commented out) of the js and the second template.
(function (){
// Interpolate function from https://gomakethings.com/html-templates-with-vanilla-javascript/
//Lets us pass a unique id to the template
function interpolate (str, params) {
let names = Object.keys(params);
let vals = Object.values(params);
return new Function(...names, `return \`${str}\`;`)(...vals);
}
//Using document on click as we are adding new buttons to the DOM and want the event to trigger on them as well
$(document).on('click', '.add-button', function () {
let id = $('.addRows').length + 1; //Use this for our row ID
let newRow = interpolate(row_template.innerHTML, {id}); //Generate our row html from the template
$(this).closest('.addRows').after(newRow); //Add the html to the table
});
//Remove button
$(document).on('click', '.remove-button', function () {
$(this).closest('.addRows').remove();
});
})();
//Use the below INSTEAD of the above for just the single extra toggling row.
/*(function (){
//Add new row from simple template
$(document).on('click', '.add-button', function () {
$("#TextBoxesGroup tbody").append(row_template_single.innerHTML);
});
//Remove the row
$(document).on('click', '.remove-button', function () {
$(this).closest('.addRows').remove();
});
})();*/
/*Style for red remove button*/
.remove-button {
background-color: #f77;
color: white;
}
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<table id="TextBoxesGroup">
<tbody>
<tr class="addRows">
<td>Start Date:</td>
<td>
<input type="text" name="StartDate_1" class="picker" value="" size="6">
</td>
<td>End Date:</td>
<td>
<input type="text" name="EndDate_2" class="picker" value="" size="6">
</td>
<td>
<input type="button" id="addButton_1" class="add-button" value="Add row" />
</td>
</tr>
</tbody>
</table>
<!-- Template allowing to add multiple new rows with unique input names via id passed -->
<template id="row_template">
<tr class="addRows">
<td>Start Date:</td>
<td>
<input type="text" name="StartDate_${id}" class="picker" value="" size="6">
</td>
<td>End Date:</td>
<td>
<input type="text" name="EndDate_${id}" class="picker" value="" size="6">
</td>
<td>
<input type="button" id="addButton_${id}" class="add-button" value="Add row" />
<input type="button" class="remove-button" value="Remove row" />
</td>
</tr>
</template>
<!-- Template for just 'toggling' a second row -->
<!-- <template id="row_template_single">
<tr class="addRows">
<td>Start Date:</td>
<td>
<input type="text" name="StartDate_2" class="picker" value="" size="6">
</td>
<td>End Date:</td>
<td>
<input type="text" name="EndDate_2" class="picker" value="" size="6">
</td>
<td>
<input type="button" class="remove-button" value="Remove row" />
</td>
</tr>
</template> -->
I noticed my previous answer did not properly handle adding items in-between other items, i.e. not at the end of the list.
The following will better handle adding and removing items, while keeping the ids in order. This instead renders the fields based on the data we keep and manage in JavaScript.
(function () {
$(document).ready(function () {
field_data.init()
})
let field_data = {
data: [],
init: function () {
this.cacheDom();
this.bindEvents();
this.data.push(this.getItem());
this.renderData();
},
cacheDom: function () {
this.$render_container = $('#render_container');
this.row_template_html = $('#row_template').html();
},
bindEvents: function () {
$(document).on('click', '.remove-button', this.removeItem);
$(document).on('click', '.add-button', this.addItem);
this.$render_container.on('change', 'input', this.inputChange);
},
//When an item gets added, add new empty item to the data and re-render.
addItem: function () {
let target = parseInt($(this).attr('data-target'));
field_data.data.splice(target+1, 0, field_data.getItem());
field_data.renderData();
},
//When an item gets removed, remove it from the data and re-render.
removeItem: function () {
let target = parseInt($(this).attr('data-target'));
if (field_data.data.length > 1) { //Prevent from removing last item.
field_data.data.splice(target, 1);
field_data.renderData();
}
},
//Get a new/empty item.
getItem: function () {
return {
start_date: '',
end_date: '',
}
},
//Update the data when a value of an input changes
inputChange: function () {
let $this = $(this);
let id = parseInt($this.attr('data-id'));
let target = $this.attr('data-target');
field_data.data[id][target] = $this.val();
},
//Render the data according to the template.
renderData: function () {
let html = '';
for (let i = 0; i < field_data.data.length; i++) {
//Generate our row html from the template
html += field_data.getRowTemplate(
{
id: i,
start_date: field_data.data[i].start_date,
end_date: field_data.data[i].end_date,
}
);
}
field_data.$render_container.html(html);
},
//Gets the html for a single row based on our template
getRowTemplate: function (params) {
let names = Object.keys(params);
let values = Object.values(params);
return new Function(...names, `return \`${field_data.row_template_html}\`;`)(...values);
},
}
})();
.remove-button {
background-color: #f77;
color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="TextBoxesGroup">
<tbody id="render_container">
</tbody>
</table>
<template id="row_template">
<tr class="addRows">
<td>Start Date:</td>
<td>
<input type="text" name="StartDate_${id}" data-id="${id}" data-target="start_date" class="picker" value="${start_date}" size="6">
</td>
<td>End Date:</td>
<td>
<input type="text" name="EndDate_${id}" data-id="${id}" data-target="end_date" class="picker" value="${end_date}" size="6">
</td>
<td>
<input type="button" class="add-button" data-target="${id}" id="addButton_${id}" value="Add row"/>
<input type="button" class="remove-button" data-target="${id}" value="Remove row"/>
</td>
</tr>
</template>
I am trying to get the date and department info stored into an array, when a user inputs a value into my HTML. When I look at the console, I see it is being saved as E.fn.init. Here is my HTML code:
<form>
<p><b>Date:</b><input id="date_out" type='date' required /></p>
<p><b>Department:</b><input id='department_out' type='text' required /></p>
<button class="btn btn-primary" type="submit" id='submit' >SUBMIT</button>
</form>
And here is my Javascript Code:
let count = 1;
// Handler to Submit Data
$('#submit').click(() =>{
$('form').on('submit', function(e){
e.preventDefault();
const date_out = $("#date_out").val();
const department_out = $("#department_out").val();
let data = [];
// Iterate over all rows and store data
for (let i = 1; i <= count; i++){
// Skip Row if it was Removed
if (!$(`tr[index=${i}]`).length) continue;
// Store all Info from this row
let assetInfo = {
date_out: $(`#date_out${i}`).val(date_out),
department_out: $(`#department_out${i}`).val(department_out),
}
data.push(assetInfo);
console.log(data);
}
});
});
And the console prints the array as; date_out: E.fn.init, department_out: E.fn.init. How do I get it to save whatever the user inputs in the array?
I am not quite sure what is your HTML structure but as I understand, you have a table and you want to store each row in a data,
here is how I advise you to do it:
In my Table called depTable, I have each row with a unique ID like this:
date_out_1
department_out_1
so, when I want to access that, I just want to create that ID which is an easy task while I can get how many rows I have in that table, like this:
// Get ROW COUNT FROM TABLE
var count = $('#depTable tr').length;
Now, if you combine in For loop you will get all IDs
for (let i = 1; i <= count; i++){
var idDate = "#date_out_" + i;
var idDep = "#department_out_" + i;
}
here is my all code, hope I helped to solve your problem.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Stack21</title>
<script src="js/jquery-3.6.0.min.js"></script>
</head>
<body>
<table id="depTable">
<thead>
<tr>
<td>Date</td>
<td>Department</td>
</tr>
</thead>
<tbody>
<tr>
<td>
<input id="date_out_1" type='date' required />
</td>
<td>
<input id='department_out_1' type='text' required />
</td>
</tr>
<tr>
<td>
<input id="date_out_2" type='date' required />
</td>
<td>
<input id='department_out_2' type='text' required />
</td>
</tr>
<tr>
<td>
<input id="date_out_3" type='date' required />
</td>
<td>
<input id='department_out_3' type='text' required />
</td>
</tr>
<tr>
<td>
<input id="date_out_4" type='date' required />
</td>
<td>
<input id='department_out_4' type='text' required />
</td>
</tr>
</tbody>
</table>
<Button onclick="storeUserData()">Test me</Button>
<script>
let data = [];
function storeUserData(){
// Get ROW COUNT FROM TABLE
var count = $('#depTable tr').length;
console.log("Row Count: " + count)
for (let i = 1; i <= count; i++){
var idDate = "#date_out_" + i;
var idDep = "#department_out_" + i;
let assetInfo = {
date_out: $(idDate).val(),
department_out: $(idDep).val()
}
data.push(assetInfo);
}
console.log(data);
}
</script>
</body>
</html>
Demo code here:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Stack21</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- MY OFFLINE <script src="js/jquery-3.6.0.min.js"></script> -->
</head>
<body>
<table id="depTable">
<thead>
<tr>
<td>Date</td>
<td>Department</td>
</tr>
</thead>
<tbody>
<tr>
<td>
<input id="date_out_1" type='date' required />
</td>
<td>
<input id='department_out_1' type='text' required />
</td>
</tr>
<tr>
<td>
<input id="date_out_2" type='date' required />
</td>
<td>
<input id='department_out_2' type='text' required />
</td>
</tr>
<tr>
<td>
<input id="date_out_3" type='date' required />
</td>
<td>
<input id='department_out_3' type='text' required />
</td>
</tr>
<tr>
<td>
<input id="date_out_4" type='date' required />
</td>
<td>
<input id='department_out_4' type='text' required />
</td>
</tr>
</tbody>
</table>
<Button onclick="storeUserData()">Test me</Button>
<script>
let data = [];
function storeUserData(){
// Get ROW COUNT FROM TABLE
var count = $('#depTable tr').length;
console.log("Row Count: " + count)
for (let i = 1; i <= count; i++){
var idDate = "#date_out_" + i;
var idDep = "#department_out_" + i;
let assetInfo = {
date_out: $(idDate).val(),
department_out: $(idDep).val()
}
data.push(assetInfo);
}
console.log(data);
}
</script>
</body>
</html>
I have a button that the user clicks on to add a new row to the bottom of an input table. I would like this to also increment the id. So the next row would have desc2, hours2, rate2 and amount2 as the id. Is there a way to do this in the JavaScript function.
Also - just want to check my logic on this. After the user completes the filled out form, I will be writing all the data to a mysql database on two different tables. Is this the best way to go about this? I want the user to be able to add as many lines in the desc_table as they need. If this is the correct way to be going about this, what is the best way to determine how many lines they have added so I can insert into the db table using a while loop?
JS file:
function new_line() {
var t = document.getElementById("desc_table");
var rows = t.getElementsByTagName("tr");
var r = rows[rows.length - 1];
var x = rows[1].cloneNode(true);
x.style.display = "";
r.parentNode.insertBefore(x, r);
}
HTML:
<table id="desc_table">
<tr>
<td><font><br><h3>Description</h3></font></td>
<td><font><h3>Hours</h3></font></td>
<td><font><h3>Rate</h3></font></td>
<td><font><h3>Amount</h3></font></td>
<td></td>
</tr>
<tr>
<td ><textarea name="description" id="desc1" ></textarea></td>
<td> <input type="text" name="hours" id="hours1" ></td>
<td> <input type="text" name="rate" id="rate1"></td>
<td><input type="text" name="amount" id="amount1"></td>
<td>
<button type="button" name="add_btn" onclick="new_line(this)">+</button>
<button type="button" name="delete_btn" onclick="delete_row(this)">x</button>
</td>
</tr>
</table>
Thank you!
Check this code.After appending the row it counts the number of rows and and then assigns via if condition and incremental procedure the id's:
function new_line() {
var t = document.getElementById("desc_table");
var rows = t.getElementsByTagName("tr");
var r = rows[rows.length - 1];
var x = rows[1].cloneNode(true);
x.style.display = "";
r.parentNode.insertBefore(x, r);
for(var i=1;i<rows.length;i++){
if(rows[i].children["0"].children["0"].id.match((/desc/g))){
rows[i].children["0"].children["0"].id='desc'+i;
}
if(rows[i].children["1"].children["0"].id.match((/hours/g))){
rows[i].children["1"].children["0"].id='hours'+i;
}
if(rows[i].children["2"].children["0"].id.match((/rate/g))){
rows[i].children["2"].children["0"].id='rate'+i;
}
if(rows[i].children["3"].children["0"].id.match((/amount/g))){
rows[i].children["3"].children["0"].id='amount'+i;
}
}
}
<table id="desc_table">
<tr>
<td><font><br><h3>Description</h3></font></td>
<td><font><h3>Hours</h3></font></td>
<td><font><h3>Rate</h3></font></td>
<td><font><h3>Amount</h3></font></td>
<td></td>
</tr>
<tr>
<td ><textarea name="description" id="desc1" ></textarea></td>
<td> <input type="text" name="hours" id="hours1" ></td>
<td> <input type="text" name="rate" id="rate1"></td>
<td><input type="text" name="amount" id="amount1"></td>
<td>
<button type="button" name="add_btn" onclick="new_line(this)">+</button>
<button type="button" name="delete_btn" onclick="delete_row(this)">x</button>
</td>
</tr>
</table>
Please change variable names for more descriptive. :)
Example solution...
https://jsfiddle.net/Platonow/07ckv5u7/1/
function new_line() {
var table = document.getElementById("desc_table");
var rows = table.getElementsByTagName("tr");
var row = rows[rows.length - 1];
var newRow = rows[rows.length - 1].cloneNode(true);
var inputs = newRow.getElementsByTagName("input");
for(let i=0; i<inputs.length; i++) {
inputs[i].id = inputs[i].name + rows.length;
}
var textarea = newRow.getElementsByTagName("textarea")[0];
textarea.id = textarea.name + rows.length;
table.appendChild(newRow);
}
Note that I removed/edited below fragment.
x.style.display = "";
r.parentNode.insertBefore(x, r);
You could do this a lot easier with jquery or another dom manipulation language, but with vanilla JS here's an example of simply looping through the new row's inputs & textarea and incrementing a counter to append.
var count = 1;
function new_line() {
count++;
var t = document.getElementById("desc_table");
var rows = t.getElementsByTagName("tr");
var r = rows[rows.length - 1];
var x = rows[1].cloneNode(true);
x.style.display = "";
r.parentNode.insertBefore(x, r);
// update input ids
var newInputs = Array.from(x.getElementsByTagName('input'))
.concat(Array.from(x.getElementsByTagName('textarea')));
newInputs.forEach(function(input) {
var id = input.getAttribute('id').replace(/[0-9].*/, '');
input.setAttribute('id', id + count);
});
}
<table id="desc_table">
<tr>
<td><font><br><h3>Description</h3></font></td>
<td><font><h3>Hours</h3></font></td>
<td><font><h3>Rate</h3></font></td>
<td><font><h3>Amount</h3></font></td>
<td></td>
</tr>
<tr>
<td ><textarea name="description" id="desc1" ></textarea></td>
<td> <input type="text" name="hours" id="hours1" ></td>
<td> <input type="text" name="rate" id="rate1"></td>
<td><input type="text" name="amount" id="amount1"></td>
<td>
<button type="button" name="add_btn" onclick="new_line(this)">+</button>
<button type="button" name="delete_btn" onclick="delete_row(this)">x</button>
</td>
</tr>
</table>
I'm generating an HTML table which contains rows like this one: I've been able to successfully get the ID and the trackingNumber value, but I'm trying to get the data-categoryName-id value and I'm stumped. Here's my script:
$("input[type='text']").change(function() {
var parent = $(this).parents('tr');
var recid = $(this).closest('td').attr('id');
var trackingNumber = $(this).val();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<tr id="53462365">
<td>JB44566</td>
<td>SKU123</td>
<td>CARTON PAPER A4</td>
<td>PAPER</td>
<td></td>
<td>966257111</td>
<td></td>
<td id="53462365"><input type="text" class="form-control" placeholder="Tracking #" name="trackingNumber" data-categoryName-id="Office Supplies" autocomplete="off" value=""></td>
<td id="53462365"><input type="number" id="53462365" class="form-control" autocomplete="off" placeholder="ID Tag" name="idTag" value=""></td>
</tr>
Trying to add another like, e.g.:
var categoryName =
that returns the value for the data-categoryName-id for the current row but completely stumped.
you can use .attr()
$("input[type='text']").change(function() {
var parent = $(this).parents('tr');
var recid = $(this).closest('td').attr('id');
var trackingNumber = $(this).val();
var categoryName = $(this).attr('data-categoryName-id');
console.log(categoryName);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<tr id="53462365">
<td>JB44566</td>
<td>SKU123</td>
<td>CARTON PAPER A4</td>
<td>PAPER</td>
<td></td>
<td>966257111</td>
<td></td>
<td id="53462365"><input type="text" class="form-control" placeholder="Tracking #" name="trackingNumber" data-categoryName-id="Office Supplies" autocomplete="off" value=""></td>
<td id="53462365"><input type="number" id="53462365" class="form-control" autocomplete="off" placeholder="ID Tag" name="idTag" value=""></td>
</tr>
jQuery has a .data() method that allows you to get or set data-* attributes:
var categoryName = $(this).data('categoryName-id');
Trying to pull information from my form input fields and calculate them using JavaScript. It does not seem to be working.
HTML (default1.html)
<script type="text/javascript" src="multiplication.js" language="javascript"></script>
<form>
<table>
<tr><!--Row 2-->
<td class="tdSize7">
<input class="input" name="name1" type="text"/>
</td>
<td class="tdSize7">
<input class="input" name="source1" type="text"/>
</td>
<td class="tdSize8">
<p>$</p>
</td>
<td class="tdSize9">
<input class="input" name="income1" type="text"/>
</td>
<td class="tdSize8">
<p>X12</p>
</td>
<td class="tdSize8">
<p>$</p>
</td>
<td class="tdSize9">
<input name="ann1" disabled="disabled"/>
</td>
</tr>
<td class="tdSize9"><input class="inputSize2" name="" type="button" value="Calculate" onclick="addme(this.form)"/></td>
</table>
</form>
JavaScript (multiplication.js)
function addme(form) {
//Constant Variables
const twelve = Number (12);
const fourHun = Number (400);
const fourHunEighty = Number (480);
//Monthly Income 1
var income1 = Number(frm.income1.value);
var val = income1 * twelve;
frm.ann1.value = val;
}
My JavaScript will not calculate and input my results back into my form.
This is just a sample of my code. I am hoping this will tell you enough and help you, in helping me fixing my problem.
Did you intend to use form instead of frm? That is part of your problem
Try:
var income1 = Number(form.income1.value);
var val = income1 * twelve;
form.ann1.value = val;
Or change
function addme(form)
to
function addme(frm)