I am attempting to get the input filled by the user from a table. The table has but 2 columns how can I get the input from these? I want to have a different var for each column of items? The table changed size dynamically by a slider which controls the rows. This is my table:
<div id="table-gen">
<p>Als je dezelfde herhaling doet voor alle sets, kan je slechts één waarde invullen: bvb. voor 4 sets
slechts éénmaal 10 invoeren voor de herhalingen. Dit wordt dan automatisch 4 x 10.</p>
<table id="resultTable" cellpadding="1" cellspacing="1" border="1">
<tr>
<th scope="col"></th>
<th scope="col">Hoeveelheid</th>
<th scope="col">Gewicht x KG</th>
</tr>
<tr>
<td>1</td>
<td><INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1" ></td>
<td><INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1" ></td>
</tr>
<tr>
<td>2</td>
<td><INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1" ></td>
<td><INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1" ></td>
</tr>
<tr>
<td>3</td>
<td><INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1" ></td>
<td><INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1" ></td>
</tr>
</table>
</div>
this is what it looks Like:
I tried the following:
var col1_Array = $('#resultTable td:nth-child(1)').map(function () {
return $(this).text();
}).get();
var col2_Array = $('#resultTable td:nth-child(2)').map(function () {
return $(this).text();
}).get();
this only gives me the very first column and an emptry string. I try to upload it to firebase which goes well. Except the first column is the defeault number, after i change the size of my table it somehow doesnt register.
function writeData(){
firebase.database().ref("Exercise").set({
nameExercise: exerciseName.value,
setAm: setAmount,
setReps:col1_Array,
weight:col2_Array,
})
}
How can i best go around this dynamically changing table? Is it better to reconstruct this table to divs? I feel like im digging a rabbithole at this point..
Add classes HoeveelheidField and GewichtField to td's
<tr>
<td>1</td>
<td class="HoeveelheidField"><INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1" ></td>
<td class="GewichtField"><INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1" ></td>
</tr>
and then in order to get all values
function getData(){
$('#resultTable .HoeveelheidField > input ').each(function() {
HoeveelheidArr.push($(this).val());
});
$('#resultTable .GewichtField > input').each(function() {
Gewicht.push($(this).val());
});
Run this snippet to test if it works
var HoeveelheidArr=[];
var Gewicht=[]
function getData(){
$('#resultTable .HoeveelheidField > input ').each(function() {
HoeveelheidArr.push($(this).val());
});
$('#resultTable .GewichtField > input').each(function() {
Gewicht.push($(this).val());
});
console.log(HoeveelheidArr);
console.log(Gewicht);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<table id="resultTable" cellpadding="1" cellspacing="1" border="1">
<tr>
<th scope="col"></th>
<th scope="col">Hoeveelheid</th>
<th scope="col">Gewicht x KG</th>
</tr>
<tr>
<td>1</td>
<td class="HoeveelheidField"><INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1" ></td>
<td class="GewichtField"><INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1" ></td>
</tr>
<tr>
<td>2</td>
<td class="HoeveelheidField"><INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1" ></td>
<td class="GewichtField"><INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1" ></td>
</tr>
<tr>
<td>3</td>
<td class="HoeveelheidField"><INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1" ></td>
<td class="GewichtField"><INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1" ></td>
</tr>
</table>
<button onclick="getData()">Get Data</button>
First, you should target the input in order to map the values.
Then, Since an jQuery lookup like $("#resultTable td:nth-child(2) input") returns a jQuery collection of elements, you have to apply the .get() on it before mapping... Not after.
Third, in the selectors, td:nth-child(n) is not zero based.
Fourth, in map(), the argument is a function. That function needs an argument in order to return something from it. Notice the input in .map(function (input) {
I made it so the arrays are refreshed on input change... But I don't know if that is relevant to you. Anyway, you should use an event to achieve this. Also notice the use of delegation, since your table is dynamically changing...
var col1_Array, col2_Array;
$(document).on("change","#resultTable td input", function () {
col1_Array = $("#resultTable td:nth-child(2) input")
.get()
.map(function (input) {
return input.value;
});
col2_Array = $("#resultTable td:nth-child(3) input")
.get()
.map(function (input) {
return input.value;
});
console.log(col1_Array, col2_Array);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="table-gen">
<p>Als je dezelfde herhaling doet voor alle sets, kan je slechts één waarde invullen: bvb. voor 4 sets
slechts éénmaal 10 invoeren voor de herhalingen. Dit wordt dan automatisch 4 x 10.</p>
<table id="resultTable" cellpadding="1" cellspacing="1" border="1">
<tr>
<th scope="col"></th>
<th scope="col">Hoeveelheid</th>
<th scope="col">Gewicht x KG</th>
</tr>
<tr>
<td>1</td>
<td><INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1"></td>
<td><INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1"></td>
</tr>
<tr>
<td>2</td>
<td><INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1"></td>
<td><INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1"></td>
</tr>
<tr>
<td>3</td>
<td><INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1"></td>
<td><INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1"></td>
</tr>
</table>
</div>
CodePen
Related
How can I make sure that the second part of function runs, calculating the columns and showing the result at the end of each row?
function sum_row_qty(el, poOrigin) {
let rowTotal = 0
if (el) {
let parent = el.closest("tr")
parent.querySelectorAll('.size_qty').forEach(function(e) {
rowTotal += parseFloat(e.value);
})
if (rowTotal) {
parent.querySelector('.qty').value = rowTotal;
}
} else {
document.querySelectorAll("#tableRows > tr > td:first-child input").forEach(sum_row_qty);
}
}
<table class="table table-hover table-vcenter" id="dtable">
<thead>
<tr>
<th style="width:4%; text-align: left">OS</th>
<th style="width:4%">XS</th>
<th style="width:4%">Total</th>
</tr>
</thead>
<tbody id="tableRows">
<tr>
<td><input class="size_qty" type="number" min="0" name="numberInputs" value="14" onchange="sum_row_qty(this);"></td>
<td><input class="size_qty" type="number" min="0" name="numberInputs" value="0" onchange="sum_row_qty(this)"></td>
<td><input type="number" min="0" class="qty" name="numberInputs" value="" readonly="true"></td>
</tr>
<tr>
<td><input class="size_qty" type="number" min="0" name="numberInputs" value="14" onchange="sum_row_qty(this);"></td>
<td><input class="size_qty" type="number" min="0" name="numberInputs" value="0" onchange="sum_row_qty(this);"></td>
<td><input type="number" min="0" class="qty" name="numberInputs" value="" readonly="true"></td>
</tr>
</tbody>
</table>
Here is the answer proposed by a gentleman on another platform:
function sumInputs(row) {
const inputsArr = [...row.querySelectorAll('.size_qty')];
return inputsArr.reduce((total, {
value
}) => total += parseFloat(value), 0);
}
function sum_row_qty(el) {
if (el) {
const currentRow = el.closest("tr");
currentRow.querySelector('.qty').value = sumInputs(currentRow);
}
}
tableRows.querySelectorAll('tr').forEach(row => {
row.querySelector('.qty').value = sumInputs(row);
});
<table class="table table-hover table-vcenter" id="dtable">
<thead>
<tr>
<th style="width:4%; text-align: left">OS</th>
<th style="width:4%">XS</th>
<th style="width:4%">Total</th>
</tr>
</thead>
<tbody id="tableRows">
<tr>
<td><input class="size_qty" type="number" min="0" name="numberInputs" value="14" onchange="sum_row_qty(this);"></td>
<td><input class="size_qty" type="number" min="0" name="numberInputs" value="0" onchange="sum_row_qty(this)"></td>
<td><input type="number" min="0" class="qty" name="numberInputs" value="" readonly="true"></td>
</tr>
<tr>
<td><input class="size_qty" type="number" min="0" name="numberInputs" value="14" onchange="sum_row_qty(this);"></td>
<td><input class="size_qty" type="number" min="0" name="numberInputs" value="0" onchange="sum_row_qty(this);"></td>
<td><input type="number" min="0" class="qty" name="numberInputs" value="" readonly="true"></td>
</tr>
</tbody>
</table>
I'm new to programming and still learn. I just want to ask how to make code validation for more than one input? I have data table item. I want to run validation input for each row.
My Code below is only run for the first row, and cannot running in the second row.
<tr>
<td><input id="stock" type="number" name="stock" value="<?php echo $row->stock; ?>" readonly></td>
<td><input id="qty" onInput="calc();" type="number" name="qty"></td>
</tr>
<script type="text/javascript">
function calc(){
var stock = document.getElementById("stock").value;
var qty = document.getElementById("qty").value;
if(qty > stock){
alert("Qty More Than Stock!");
document.getElementById("qty").value = 1;
}
}
</script>
You can use querySelectorAll with an data-attribute for select all inputs then forEach it and check the value like:
document.querySelectorAll('input[data-check]').forEach(el => {
el.addEventListener('change', () => {
if (parseInt(el.value) > parseInt(el.parentElement.previousElementSibling.children[0].value)) {
alert("Qty More Than Stock!");
el.value = 0;
}
});
});
<table>
<tr>
<td>Stock</td>
<td>Qty</td>
</tr>
<tr>
<td><input id="stock" type="number" name="stock" value="2" readonly></td>
<td><input data-check type="number" name="qty"></td>
</tr>
<tr>
<td><input id="stock" type="number" name="stock" value="3" readonly></td>
<td><input data-check type="number" name="qty"></td>
</tr>
</table>
PS. Remember to use always a structure like my example else my code probably doesn't work.in fact el.parentElement.previousElementSibling.children[0].value it's like say: element - parent of element (td) - previous element (other td) - the first children of the previus element (input).
Another option is use another data-attribute for select the stock value like:
document.querySelectorAll('input[data-check]').forEach(el => {
el.addEventListener('change', () => {
let stock = document.querySelector('input[data-index="'+el.dataset.stock+'"]');
if (parseInt(el.value) > parseInt(stock.value)) {
alert("Qty More Than Stock!");
el.value = 0;
}
});
});
<table>
<tr>
<td>Stock</td>
<td>Qty</td>
</tr>
<tr>
<td><input data-index='0' type="number" name="stock" value="2" readonly></td>
<td><input data-check data-stock='0' type="number" name="qty"></td>
</tr>
<tr>
<td><input data-index='1' type="number" name="stock" value="25" readonly></td>
<td><input data-check data-stock='1' type="number" name="qty"></td>
</tr>
</table>
I am trying to get the input from a table form. The table has but 2 columns how can I get the input from these? I want to have a different var for each column of items? Should I use an array? This is my table:
<table id="resultTable" cellpadding="1" cellspacing="1" border="1">
<tr>
<th scope="col"></th>
<th scope="col">Hoeveelheid</th>
<th scope="col">Gewicht x KG</th>
</tr>
<tr>
<td>1</td>
<td><INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1" ></td>
<td><INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1" ></td>
</tr>
<tr>
<td>2</td>
<td><INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1" ></td>
<td><INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1" ></td>
</tr>
<tr>
<td>3</td>
<td><INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1" ></td>
<td><INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1" ></td>
</tr>
</table>
What is the best way to get around this? I tried to select by tag name.
Here a quick one for jQuery:
Replace tableid with the id of your table
var col1_Array = $('#tableid td:nth-child(1)').map(function(){
return $(this).text();
}).get();
var col2_Array = $('#tableid td:nth-child(2)').map(function(){
return $(this).text();
}).get();
I have an array with three values, and 1 seperate value all acquired from a form.
I am trying to multiply the top number (3) with the others (12, 3 and 31) and add those up.
This is what i tried:
HTML:
<p>Aantal sets: <span id="dynamicSet"></span></p>
<table id="resultTable" cellpadding="1" cellspacing="1" border="1">
<tr>
<th scope="col"></th>
<th scope="col">Hoeveelheid</th>
<th scope="col">Gewicht x KG</th>
</tr>
<tr>
<td>1</td>
<td class="HoeveelheidField"><INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1" ></td>
<td class="GewichtField"><INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1" ></td>
</tr>
<tr>
<td>2</td>
<td class="HoeveelheidField"><INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1" ></td>
<td class="GewichtField"><INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1" ></td>
</tr>
<tr>
<td>3</td>
<td class="HoeveelheidField"><INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1" ></td>
<td class="GewichtField"><INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1" ></td>
</tr>
</table>
And my JS:
var HoeveelheidArr=[];
var total = 0;
const setAmount = document.getElementById("dynamicSet").innerHTML;
function getData(){
$('#resultTable .HoeveelheidField > input ').each(function() {
HoeveelheidArr.push($(this).val());
});
console.log(HoeveelheidArr);
HoeveelheidArr.forEach(function getReps (value) {
console.log(value);
for(var i = 0; i < HoeveelheidArr.length; i++){
total += value[i] * setAmount;
}
});
console.log(total);
}
However as you may see in the picture i keep getting Not a Number back from the console. Despite the console showing all of them appear as ints? Do you see what I do wrong? I also tried:
parseInt(value[i])
Your setAmount variable is a string from innerHTML.
Use parseInt() on both variables:
total += parseInt(value[i]) * parseInt(setAmount);
Update
After a deeper review, you got a couple of other problems.
Your setAmount variable is "", because it's not set in the HTML.
You are looping through the HoeveelheidArr twice
You should use value instead of value[i]
I made a working example:
var HoeveelheidArr = [];
var total = 0;
const setAmount = document.getElementById("dynamicSet").innerHTML || 0;
function getData() {
HoeveelheidArr = [];
total = 0;
$('#resultTable .HoeveelheidField > input').each(function() {
HoeveelheidArr.push($(this).val() || 0);
});
console.log("HoeveelheidArr:", HoeveelheidArr);
for (var i = 0; i < HoeveelheidArr.length; i++) {
console.log("setAmount:", setAmount);
total += parseInt(HoeveelheidArr[i]) * parseInt(setAmount);
}
console.log("Total:", total);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Aantal sets: <span id="dynamicSet">1</span></p>
<table id="resultTable" cellpadding="1" cellspacing="1" border="1">
<tr>
<th scope="col"></th>
<th scope="col">Hoeveelheid</th>
<th scope="col">Gewicht x KG</th>
</tr>
<tr>
<td>1</td>
<td class="HoeveelheidField">
<INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1">
</td>
<td class="GewichtField">
<INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1">
</td>
</tr>
<tr>
<td>2</td>
<td class="HoeveelheidField">
<INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1">
</td>
<td class="GewichtField">
<INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1">
</td>
</tr>
<tr>
<td>3</td>
<td class="HoeveelheidField">
<INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1">
</td>
<td class="GewichtField">
<INPUT TYPE="NUMBER" MIN="0" MAX="10" STEP="1">
</td>
</tr>
</table>
<button onclick="getData()">Test</button>
why are you using value[i] value is not an array it's just a number.
console.log([value[i]);
the value[1] and value[2] is undefined that why you are getting NaN
If you tell me what do you want to do through this code, I can correct it
I'm trying to get the slider value of the current row when the users changes any of the inputs for class="entryprice_class".
Commented out in the code is some of what I have tried.
I have been at this for hours. Still no luck.
Where am I going wrong?
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.1/jquery.mobile-1.2.1.min.css"/>
<script src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
<script src="http://code.jquery.com/mobile/1.2.1/jquery.mobile-1.2.1.min.js"></script>
<body>
<div data-role="page">
<div data-role="content">
<!-- entry points table -->
<section id="entry_points_section">
<div class="input_fields_wrap">
<table class="responsive" id="input_entries_table">
<tbody>
<tr>
<th scope="col" id="entry_price_column">Entry price</th>
<th scope="col">Percent</th>
<th scope="col">Order amount</th>
<th scope="col">Capital value</th>
<th scope="col">Breakeven</th>
<th scope="col"></th>
</tr>
<tr>
<td width="17%" style="min-width:3em"><input type="number" class="entryprice_class"
id="entryprice_1" size="5" min="0" placeholder="0"
value="0"></td>
<td style="min-width:2em"><input type="range" name="slider-fill_1" class="entry_percent"
id="entry_percent_1" value="50" placeholder="50%" min="0"
max="100"
data-highlight="true"/></td>
<td width="17%" style="min-width:3em"><input type="text" class="order_amount"
name="order_amount" size="5" min="0"
placeholder="0" length="10px" disabled></td>
<td width="17%" style="min-width:3em"><input type="text" class="capital_value"
name="capital_value" size="5" min="0"
placeholder="0" disabled></td>
<td width="17%" style="min-width:3em"><input type="text" class="breakeven" name="breakeven"
size="5" min="0" placeholder="0" disabled></td>
<td width="28px" style="display:none">
<button data-role="button" data-icon="delete" data-iconpos="notext" data-inline="true">
</button>
</td>
</tr>
<tr>
<td width="17%" style="min-width:3em"><input type="number" class="entryprice_class"
name="entryprice" id="entryprice_2" size="5"
min="0" placeholder="0" value="0"></td>
<td style="min-width:2em"><input type="range" name="slider-fill" id="entry_percent_2" value="50"
placeholder="50%" min="0" max="100"
data-highlight="true"/></td>
<td width="17%" style="min-width:3em"><input type="text" class="order_amount"
name="order_amount" size="5" min="0"
placeholder="0" length="10px" disabled></td>
<td width="17%" style="min-width:3em"><input type="text" class="capital_value"
name="capital_value" size="5" min="0"
placeholder="0" disabled></td>
<td width="17%" style="min-width:3em"><input type="text" class="breakeven" name="breakeven"
size="5" min="0" placeholder="0" disabled></td>
<td width="28px"><a href="#" class="remove_field">
<button data-role="button" data-icon="delete" data-iconpos="notext" data-inline="true">
</button>
</a></td>
</tr>
</tbody>
</table>
</div>
<div class="ui-grid-solo">
<div class="ui-block-a">
<div>
<button id='add_new_entry_button' data-icon="plus" data-inline="false">Add</button>
</div>
</div>
</div>
</section>
</div></div>
<!-- /page -->
<script>
var entryprice = $('.entryprice_class');
var entryprice_totals = $('#entryprice_totals_1');
entryprice.live('change', function () {
entry_price = $(':focus').val();
alert(entry_price);
var current_percent = $(this).next('td').next("input").val();
alert(slider_value);
//var current_percent = $(this).closest('tr').attr('val'); // table row ID
//var current_percent = $(this).closest('tr').where// table row ID
// $(this).closest('td').next('td').find('input').show();
//alert($row.val(), row.val());
//var current_percent = $(this).siblings('.entry_percent').val();
//var current_percent = $(this).next('input').val();
// var current_percent = $(this).closest('td').next('td').find('#entry_percent_1');
//var current_percent = $('.entry_percent').val();
//var current_percent = $(this).closest("td").next().find("input").slider("option", "value");
//var current_percent = $(this).next('td').next("input").val();
//var current_percent = $(this).next('.entry_percent').val();
//var current_percent = $(this).next("input[name='slider-fill']").val();
// var current_percent = $(this).closest('input .entry_percent').val();
//var current_percent = $(this).closest("div.options").find("input[name='slider-fill_1']").val();
//var current_percent = $(this).closest('tr').find("input[name='slider-fill_1']").val();
//var current_percent = $(this).parent().next().children('.entry_percent').val( this.value );
//var current_percent = $(this).sibling().val();
// var current_percent = $(this).closest("tr").find("input[name='slider-fill']").val();
// current_percent = $(':focus').next('td').find("input[name='slider-fill']").val();
alert(current_percent);
});
</script>
</body>
</html>
Here you go:
var entryprice_totals = $('#entryprice_totals_1');
$('.entryprice_class').on('change', function () {
entry_price = $(':focus').val();
alert(entry_price);
// this one works with jQuery Mobile 1.2.0
var current_percent = $(this).closest("tr").find('td:nth-child(2) input' ).val();
// var current_percent = $(this).closest("tr").find('input[type="range"]' ).val();
alert(current_percent);
});
I used the closest method to find the nearest table row, and after that the find method was used to find input type range value. You came very close of finding the right solution. Fiddle
Updated Fiddle
You can use that:
var current_percent = $(this).parent().next("td").find("input[id^='entry_percent']").val();
This works.
Add the class entry_percent to all sliders in every row, like this:
<input type="range" name="slider-fill" id="entry_percent_2" class="entry_percent" value="50" placeholder="50%" min="0" max="100" data-highlight="true">
then use this JavaScript code:
$(function () {
$(".entryprice_class").on("change", function () {
var val = $(this).closest("tr").find(".entry_percent").val();
alert(val);
});
});
For more information see these documentation pages:
https://api.jquery.com/closest/
https://api.jquery.com/find/