Bug in the calculation of total in a dynamic table - javascript

I designed a table where you can add dynamic rows, the user can select a quantity and a price for each of them. I have a series of very simple functions that allow me to delete, empty the entire table or calculate the total of all products plugged.
So far everything works fine, the problem occurs when I create 3 rows, I add it to each of their values​​, then I decided to delete the second row and calculate the total. As you can see, the calculation is flawed, in fact I only returns the total of the first product added to the table. I can not understand why the script does not work properly. Can anyone help me solve this problem?
<html>
<table style='width:100%' id='table'>
<tr>
<td colspan='3'><input type="button" style="background-color:#00FA9A" value="add product" onclick="add()" id="button"><input type="button" style="background-color:red" value="Delete all" onclick="deleteall()" id="button">
</td>
</tr>
<tr>
<td>Quantity</td>
<td>€</td>
<td>Delete</td>
</tr>
</table>
<input type="button" id="button" value="Calc total" onclick="total()"><input type="text" class='input' id="total">€
</html>
<script>
var idx = 0;
var cont = 0;
var buttcont = 0;
var quantity, priece;
function deleteall()
{
location.reload();
}
function add()
{
var tableRef = document.getElementById('table').getElementsByTagName('tbody')[0];
var newRow = tableRef.insertRow(tableRef.rows.length);
newRow.id = "row" + cont;
cont++;
var newCell1 = newRow.insertCell(0);
var newCell2 = newRow.insertCell(1);
var newCell3 = newRow.insertCell(2);
var input1 = document.createElement('input'),
input2 = document.createElement('input');
input3 = document.createElement('button');
input1.type = 'number';
input1.style.width = "100%";
input1.id = "priece" + idx;
input1.min = 0;
input1.value = 1;
input2.type = 'text';
input2.min = 1;
input2.style.width = "100%";
input2.id = "quantity" + idx;
input3.class = 'button';
input3.innerHTML = "Delete";
if(input3.attachEvent) input3. attachEvent('onclick',function(e){deleted(e);})
else if(input3.addEventListener) input3.addEventListener('click',function(e){deleted(e);},false)
newCell1.appendChild(input1);
newCell2.appendChild(input2);
newCell3.appendChild(input3);
idx++;
}
function deleted(e)
{
if(document.removeChild && document.getElementById && document.getElementsByTagName)
{
if(!e) e = window.event;
var srg = (e.target)?e.target:e.srcElement;
while(srg.tagName != "TR"){srg = (srg.parentNode)?srg.parentNode:srg.parentElement}
var tb = document.getElementById('table').getElementsByTagName('TBODY')[0];
tb.removeChild(srg);
cont--;
idx--;
}
}
function total()
{
var total = 0;
for(var i = 0; i < idx; i++)
{
quantity = document.getElementById('quantity' + i).value;
priece = document.getElementById('priece' + i).value;
total += quantity * priece;
document.getElementById('total').value = total;
}
}

The problem comes from the fact that when you delete a row inside a table (not the last one) you have a gap in ids. getElementById will return null and your total function will raise an exception.
Add 3 products: idx is 3, ids in the DOM are 0, 1, 2;
Remove product 1: idx is 2, ids in the DOM are 0, 2; => total will throw for i == 1
Actually you can avoid looping through ids by assigning a class to your inputs. Demo.
function total()
{
var total = 0,
prices = document.querySelectorAll('.price'),
quantities = document.querySelectorAll('.quantity'),
i = 0, len = prices.length;
for(; i < len; i++) {
total += prices[i].value*quantities[i].value;
}
document.getElementById('total').value = total;
}

Related

edit a table's cells by clicking an edit button with Javascript

I don't know the problem with my code, I'm trying to make an editable cell when you click edit it edits the cell plus instead of the edit and delete buttons there should appear a save button that works, (I have a problem with that it doesn't work), here is my html code of my table:
function deleteButtons(btns, tdBtns) {
for (let index = 0; index < btns.length; index += index) {
tdBtns.removeChild(btns[index]);
}
}
function createButtons(bool, td) {
if (bool) {
var Edit = document.createElement('input');
Edit.type = "button";
Edit.value = "Edit";
Edit.setAttribute('onclick', 'Edit(this)');
td.appendChild(Edit);
var Delete = document.createElement('input');
Delete.type = "button";
Delete.setAttribute('onclick', 'Delete(this)');
Delete.value = "Delete";
td.appendChild(Delete);
} else {
var Save = document.createElement('input');
Save.type = "button";
Save.value = "Save";
Save.setAttribute('onclick', 'Save(this)');
td.appendChild(Save);
}
}
function Add() {
var p1 = document.getElementById("txt").value;
const row1 = document.getElementById("row1");
var table = document.getElementById("MyTable");
//insert row beginning or end
var element = document.createElement("tr");
var table = document.getElementById("MyTable");
table.appendChild(element);
if (document.getElementById('input1').checked) {
table.insertBefore(element, table.firstElementChild);
} else if (document.getElementById('input2').checked) {
table.lastElementChild.after(element);
}
var case1 = document.createElement("td");
case1.innerHTML = p1;
element.appendChild(case1);
var case2 = document.createElement("td");
element.appendChild(case2);
createButtons(true, case2);
}
//delete:
function Delete(element) {
element.parentNode.parentNode.parentNode.removeChild(element.parentNode.parentNode);
}
//Edit:
function Edit(element) {
const row = element.parentNode.parentNode;
const tdList = row.children;
for (let index = 0; index < tdList.length - 1; index++) {
const element = tdList[index];
var str = element.childNodes[0].nodeValue;
var input = document.createElement("input");
input.type = "text";
input.id = "edit" + (index + 1).toString();
input.value = str;
element.removeChild(element.childNodes[0]);
element.appendChild(input);
}
const tdBtns = tdList[1];
const btns = tdBtns.children;
deleteButtons(btns, tdBtns);
createButtons(false, tdBtns);
}
function Save(element) {
const row = element.parentNode.parentNode;
const tdList = row.children;
/* const edit = [
['edit1'],
['edit2']
]; */
const edit = [];
for (let index = 0; index <= 1; index++) {
edit[index] = document.getElementById("edit" + (index + 1).toString()).value;
if (edit[index] == "") {
alert("You must not keep textboxes empty");
var empty = true;
}
}
if (!empty) {
for (let index = 0; index < tdList.length - 1; index++) {
tdList[index].removeChild(tdList[index].children[0]);
var text = document.createTextNode(edit[index]);
tdList[index].appendChild(text);
}
const tdBtns = tdList[1];
const btns = tdBtns.children;
deleteButtons(btns, tdBtns);
createButtons(true, tdBtns);
}
}
<h1>Table</h1>
<div id="principal">
<div id="cntr"><input type="text" id="txt" placeholder="Element to add.">
<input type="button" value="Add" onclick="Add()"><br><br></div>
<form id="frm">
Add :
<input type="radio" name="test" id="input1"> at the beginning
<input type="radio" name="test" id="input2"> at the end
</form><br>
<table id="MyTable">
<tbody>
<tr id="row1">
<td id="name_row1">Element 1 </td>
<td>
<input type="button" id="edit_button1" value="Edit" onclick="Edit(this)">
<input type="button" value="Supprimer" onclick="Delete(this)">
</td>
</tr>
</table>
</div>
I would appreciate any help
The console is your friend. When you try to edit a td, it clearly warns you that you're trying to access "value" from a null object. It's to do with this part of the Save() function:
for (let index = 0; index <= 1; index++) {
edit[index] = document.getElementById("edit" + (index + 1).toString()).value;
The big issue here is where does index <= 1 come from? In theory you're looping through the tds in the row, right? Right now there's only one, and I see no way to add more for now.
So it tries to access the value property of an element with id "edit2" in the second iteration of the for loop. "edit2" doesn't exist, hence the error.
Funny thing is that the solution is already in your code. In your Edit() function you loop through the number of row children, with index < tdList.length - 1. Well, simply use that in your Save() function and it works fine!
You'll see it working in the snippet:
function deleteButtons(btns, tdBtns) {
for (let index = 0; index < btns.length; index += index) {
tdBtns.removeChild(btns[index]);
}
}
function createButtons(bool, td) {
if (bool) {
var Edit = document.createElement('input');
Edit.type = "button";
Edit.value = "Edit";
Edit.setAttribute('onclick', 'Edit(this)');
td.appendChild(Edit);
var Delete = document.createElement('input');
Delete.type = "button";
Delete.setAttribute('onclick', 'Delete(this)');
Delete.value = "Delete";
td.appendChild(Delete);
} else {
var Save = document.createElement('input');
Save.type = "button";
Save.value = "Save";
Save.setAttribute('onclick', 'Save(this)');
td.appendChild(Save);
}
}
function Add() {
var p1 = document.getElementById("txt").value;
const row1 = document.getElementById("row1");
var table = document.getElementById("MyTable");
//insert row beginning or end
var element = document.createElement("tr");
var table = document.getElementById("MyTable");
table.appendChild(element);
if (document.getElementById('input1').checked) {
table.insertBefore(element, table.firstElementChild);
} else if (document.getElementById('input2').checked) {
table.lastElementChild.after(element);
}
var case1 = document.createElement("td");
case1.innerHTML = p1;
element.appendChild(case1);
var case2 = document.createElement("td");
element.appendChild(case2);
createButtons(true, case2);
}
//delete:
function Delete(element) {
element.parentNode.parentNode.parentNode.removeChild(element.parentNode.parentNode);
}
//Edit:
function Edit(element) {
const row = element.parentNode.parentNode;
const tdList = row.children;
for (let index = 0; index < tdList.length - 1; index++) {
const element = tdList[index];
var str = element.childNodes[0].nodeValue;
var input = document.createElement("input");
input.type = "text";
input.id = "edit" + (index + 1).toString();
input.value = str;
element.removeChild(element.childNodes[0]);
element.appendChild(input);
}
const tdBtns = tdList[1];
const btns = tdBtns.children;
deleteButtons(btns, tdBtns);
createButtons(false, tdBtns);
}
function Save(element) {
const row = element.parentNode.parentNode;
const tdList = row.children;
/* const edit = [
['edit1'],
['edit2']
]; */
const edit = [];
for (let index = 0; index < tdList.length -1; index++) {
if (!document.getElementById("edit" + (index + 1).toString())) {
console.warn('no element with id ' + "edit" + (index + 1).toString());
continue;
}
edit[index] = document.getElementById("edit" + (index + 1).toString()).value;
if (edit[index] == "") {
alert("You must not keep textboxes empty");
var empty = true;
}
}
if (!empty) {
for (let index = 0; index < tdList.length - 1; index++) {
tdList[index].removeChild(tdList[index].children[0]);
var text = document.createTextNode(edit[index]);
tdList[index].appendChild(text);
}
const tdBtns = tdList[1];
const btns = tdBtns.children;
deleteButtons(btns, tdBtns);
createButtons(true, tdBtns);
}
}
<h1>Table</h1>
<div id="principal">
<div id="cntr"><input type="text" id="txt" placeholder="Element to add.">
<input type="button" value="Add" onclick="Add()"><br><br></div>
<form id="frm">
Add :
<input type="radio" name="test" id="input1"> at the beginning
<input type="radio" name="test" id="input2"> at the end
</form><br>
<table id="MyTable">
<tbody>
<tr id="row1">
<td id="name_row1">Element 1 </td>
<td>
<input type="button" id="edit_button1" value="Edit" onclick="Edit(this)">
<input type="button" value="Supprimer" onclick="Delete(this)">
</td>
</tr>
</table>
</div>

How to add information to a table based on a button click in Javascript?

I have 2 functions, one dynamically creates a list, the other inserts a row after the row was added to the table.
What's happening now is when I click add to order, the product is added to the table, the new row is created, and when I click another product to add to the table, the old product disappears and the most recent product takes it's place and then creates a new row, so now I have 3 rows total, but only 1 product in the table, and 2 empty rows in the table. every time I add a product to the order, it just replaces the first row with the new product, and the old one is wiped away. I want every product I click to be added to the table and a new row created there after.
html:
<table id = "productsTable">
<tr>
<th>#</th>
<th>SKU</th>
<th>Product Name</th>
<th>Quantity</th>
<th>Retail Price</th>
<th>List Price</th>
</tr>
<tr>
<td>1</td>
<td><input type="text" id="productSKU" readonly ="true"/></td>
<td><input type="text" id="productName" readonly = "true"/></td>
<td><input type="text" id="quantity" /></td>
<td><input type="text" id="retailPrice" readonly = "true"/></td>
<td><input type="text" id="listPrice" readonly = "true"/></td>
<input type="button" id = "btnDeleteRow" value="-">
</tr>
</table>
JavaScript:
function populateProductList(jsonArr){
var html = "";
html += `<ul id="myULProducts">`;
for(var x = 0; x < jsonArr.length; x++){
html += `
<li SKU = "${jsonArr[x].SKU}">
<a href="#" class="products">
<strong>Product SKU:</strong> ${jsonArr[x].SKU}
<br><strong>Product Name:</strong> ${jsonArr[x].product_name}
<br><strong>Retail Price:</strong> ${jsonArr[x].retail_price}
<br><strong>List Price:</strong> ${jsonArr[x].list_price}
<br><br></a>
<button type="button" class="btnAddProductToOrder">Add to Order</button>
</li>
</div>`
}
html += `</ul>`;
var ol = document.createElement("ol");
ol.innerHTML = html;
var tableContainer = document.getElementById("product-list-container");
tableContainer.innerHTML = "";
tableContainer.appendChild(ol);
tableContainer.addEventListener("click", function(evt){
//populateCardGroupList();
var target = evt.target;
//if statement to see if the classList has a button edit
if(target.classList.contains("btnAddProductToOrder")){
//get the id of the card group clicked
var selectedId = target.closest("li").getAttribute("SKU");
//get the card group attached to that id and pass it the rest of the json Array of objects
var selectedProduct = getProductId(selectedId, jsonArr);
populateOrderFormProducts(selectedProduct);
}
});
}
document.getElementById("btnGetProductList").addEventListener("click", ()=>{
getAllProducts();
});
function populateOrderFormProducts(jsonArr){
document.querySelector("#productSKU").value = jsonArr.SKU;
document.querySelector("#productName").value = jsonArr.product_name;
document.querySelector("#quantity").value = 1;
document.querySelector("#retailPrice").value = jsonArr.retail_price;
document.querySelector("#listPrice").value = jsonArr.list_price;
insertRow();
}
function insertRow() {
var x = document.getElementById('productsTable');
var new_row = x.rows[1].cloneNode(true);
var len = x.rows.length;
new_row.cells[0].innerHTML = len;
var inp1 = new_row.cells[1].getElementsByTagName('input')[0];
inp1.id += len;
inp1.value = '';
var inp2 = new_row.cells[2].getElementsByTagName('input')[0];
inp2.id += len;
inp2.value = '';
var inp3 = new_row.cells[3].getElementsByTagName('input')[0];
inp3.id += len;
inp3.value = '';
var inp4 = new_row.cells[4].getElementsByTagName('input')[0];
inp4.id += len;
inp4.value = '';
var inp5 = new_row.cells[5].getElementsByTagName('input')[0];
inp5.id += len;
inp5.value = '';
x.appendChild(new_row);
}
This is what i'm trying to do but obviously this doesn't work:
function populateOrderFormProducts(jsonArr){
if(document.querySelector("#productSKU").value = null){
document.querySelector("#productSKU").value = jsonArr.SKU;
document.querySelector("#productName").value = jsonArr.product_name;
document.querySelector("#quantity").value = 1;
document.querySelector("#retailPrice").value = jsonArr.retail_price;
document.querySelector("#listPrice").value = jsonArr.list_price;
insertRow();
}
else if(document.querySelector("#productSKU").value != null){
document.querySelector("#productSKU2").value = jsonArr.SKU;
document.querySelector("#productName2").value = jsonArr.product_name;
document.querySelector("#quantity2").value = 1;
document.querySelector("#retailPrice2").value = jsonArr.retail_price;
document.querySelector("#listPrice2").value = jsonArr.list_price;
insertRow();
}
else if(document.querySelector("#productSKU2").value != null){
document.querySelector("#productSKU3").value = jsonArr.SKU;
document.querySelector("#productName3").value = jsonArr.product_name;
document.querySelector("#quantity3").value = 1;
document.querySelector("#retailPrice3").value = jsonArr.retail_price;
document.querySelector("#listPrice3").value = jsonArr.list_price;
insertRow();
}
}

Dynamic add/remove rows and auto calculating totals- Problem with calculation when deleting inner rows

So I have pieced together a script I want to use to create invoices. It adds "Invoice Items" as a table row which includes checkbox, Quantity, Item, Unit Cost, and Price.
You can then check item, or use check-all option (Upper Left) to remove rows. As well as that it auto calculates row totals as well as a Sub Total for the whole "Invoice". As long as you remain linear, add items as will without removing them (unless removing all of them) it adds up fine. The issue I am having is if you remove any items in the middle it wont calculate total anymore.
Here is a jsfiddle too.
This is my first post and any help is greatly appreciated- Thanks in advance!!
<INPUT type="button" value="Add Invoice Item" onclick="addRow('dataTable')" />
<INPUT type="button" value="Delete Item(s)" onclick="deleteRow('dataTable')" />
<form action="" method="post" enctype="multipart/form-data">
<TABLE id="dataTable" width="350px" border="1" style="border-collapse:collapse;">
<TR>
<TH>
<INPUT type="checkbox" name="select-all" id="select-all" onclick="toggle(this);">
</TH>
<TH>Quanity</TH>
<TH>Item</TH>
<TH>Unit Cost</TH>
<TH formula="cost*qty" summary="sum">Price</TH>
</TR>
<TR>
<TD>
<INPUT type="checkbox" name="chk[]">
</TD>
<TD>
<INPUT type="text" id="qty1" name="qty[]" onchange="totalIt()"> </TD>
<TD>
<INPUT type="text" id="item1" name="item[]"> </TD>
<TD>
<INPUT type="text" id="cost1" name="cost[]" onchange="totalIt()"> </TD>
<TD>
<INPUT type="text" id="price1" name="price[]" readonly="readonly" value="0.00"> </TD>
</TR>
</TABLE>
</form>
Sub Total: <input type="text" readonly="readonly" id="total"><br><input type="submit" value="Create Invoice">
<!-------JAVASCRIPT--------->
<script>
function calc(idx) {
var price = parseFloat(document.getElementById("cost" + idx).value) *
parseFloat(document.getElementById("qty" + idx).value);
//alert(idx+":"+price);
document.getElementById("price" + idx).value = isNaN(price) ? "0.00" : price.toFixed(2);
//document.getElementById("total") = totalIt;
}
function totalIt() {
var qtys = document.getElementsByName("qty[]");
var total = 0;
for (var i = 1; i <= qtys.length; i++) {
calc(i);
var price = parseFloat(document.getElementById("price" + i).value);
total += isNaN(price) ? 0 : price;
}
document.getElementById("total").value = isNaN(total) ? "0.00" : total.toFixed(2);
}
window.onload = function() {
document.getElementsByName("qty[]")[0].onkeyup = function() {
calc(1)
};
document.getElementsByName("cost[]")[0].onkeyup = function() {
calc(1)
};
}
var rowCount = 0;
function addRow(tableID) {
var table = document.getElementById(tableID);
var rowCount = table.rows.length;
var row = table.insertRow(rowCount);
var cell1 = row.insertCell(0);
var element1 = document.createElement("input");
element1.type = "checkbox";
element1.name = "chk[]";
cell1.appendChild(element1);
var cell3 = row.insertCell(1);
var element3 = document.createElement("input");
element3.type = "text";
element3.name = "qty[]";
element3.id = "qty" + rowCount;
element3.onkeyup = totalIt;
cell3.appendChild(element3);
var cell4 = row.insertCell(2);
var element4 = document.createElement("input");
element4.type = "text";
element4.name = "item[]";
element4.id = "item" + rowCount;
cell4.appendChild(element4);
var cell5 = row.insertCell(3);
var element5 = document.createElement("input");
element5.type = "text";
element5.name = "cost[]";
element5.id = "cost" + rowCount;
element5.onkeyup = totalIt;
cell5.appendChild(element5);
var cell6 = row.insertCell(4);
var element6 = document.createElement("input");
element6.type = "text";
element6.name = "price[]";
element6.id = "price" + rowCount;
element6.value = "0.00";
$(element6).attr("readonly", "true");
cell6.appendChild(element6);
}
function deleteRow(tableID) {
try {
var table = document.getElementById(tableID);
var rowCount = table.rows.length;
document.getElementById("select-all").checked = false;
for (var i = 1; i < rowCount; i++) {
var row = table.rows[i];
var chkbox = row.cells[0].childNodes[0];
if (null != chkbox && true == chkbox.checked) {
table.deleteRow(i);
rowCount--;
i--;
}
}
} catch (e) {
alert(e);
}
}
</script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js"></script>
<script>
$("input").blur(function() {
if ($(this).attr("data-selected-all")) {
//Remove atribute to allow select all again on focus
$(this).removeAttr("data-selected-all");
}
});
$("input").click(function() {
if (!$(this).attr("data-selected-all")) {
try {
$(this).selectionStart = 0;
$(this).selectionEnd = $(this).value.length + 1;
//add atribute allowing normal selecting post focus
$(this).attr("data-selected-all", true);
} catch (err) {
$(this).select();
//add atribute allowing normal selecting post focus
$(this).attr("data-selected-all", true);
}
}
});
function toggle(source) {
var checkboxes = document.querySelectorAll('input[type="checkbox"]');
for (var i = 0; i < checkboxes.length; i++) {
if (checkboxes[i] != source)
checkboxes[i].checked = source.checked;
}
}
</script>
The error occurs after a row in the middle is deleted due to the current code being bound to the indices that are used in html (e.g. ids like "cost1", "price1" etc).
When totalIt function is invoked, it tries to access rows that have been already deleted. To have this issue fixed, you can abstract from particular indices by using more broad selectors. Here is a drop in replacement totalIt function that does not depend on indices:
function totalIt() {
var costs = document.getElementsByName("cost[]");
var quantities = document.getElementsByName("qty[]");
var prices = document.getElementsByName("price[]");
var total = Array.prototype.reduce.call(costs, function(total, cost, index) {
var price = parseFloat(cost.value) * parseFloat(quantities[index].value);
prices[index].value = isNaN(price) ? "0.00" : price.toFixed(2);
return isNaN(price) ? total : total + price;
}, 0)
document.getElementById("total").value = isNaN(total) ? "0.00" : total.toFixed(2);
}
Also, should you want to recompute the total on row delete - call totalIt in the delete handler (deleteRow). Note that you will likely need to wrap it in setTimeout so that re-computation will occur in the next event loop iteration, after the record is actually removed from DOM

.innerHTML += id, no duplicates

Here what I have so I have a long list of check-boxes and I want to display them in text if they are check I was thinking of using the code below, but the problem I'm having is if they check and uncheck a check-box it shows up multiple times any suggestion on how to fix this?
.innerHTML += id;
If you need some more details here's a code dump of the relevant code:
Javascript
function findTotal() {
var items = new Array();
var itemCount = document.getElementsByClassName("items");
var total = 0;
var id = '';
for (var i = 0; i < itemCount.length; i++) {
id = "c" + (i + 1);
if (document.getElementById(id).checked) {
total = total + parseInt(document.getElementById(id).value);
document.getElementById(id).parentNode.classList.add("active");
document.getElementById(id).parentNode.classList.remove("hover");
document.getElementById('display').innerHTML += id;
} else {
document.getElementById(id).parentNode.classList.remove("active");
document.getElementById(id).parentNode.classList.add("hover");
}
}
console.log(total);
document.getElementById('displayTotal').value = total;
}
HTML
<label class="hover topping" for="c4">
<input class="items" onclick="findTotal()" type="checkbox" name="topping" value="1.00" id="c4">BABYBEL</label>
Note: many more label classes
Previous answer should do it. Here your code (see comment "clear container"
Additionally I have simplified your code a bit. Readability greatly increased.
Maybe you should switch to jQuery in general, much simpler for your example.
var displayElement = document.getElementById('display'),
displayTotalElement = document.getElementById('displayTotal');
function findTotal() {
var items = [],
itemCount = document.getElementsByClassName("items"),
total = 0,
id = '';
// clear container
displayElement.innerHTML = "";
for (var i = 0; i < itemCount.length; i++) {
id = "c" + (i + 1);
var element = document.getElementById(id),
elementsParent = element.parentNode;
if (element.checked) {
total = total + parseInt(element.value, 10);
elementsParent.classList.add("active");
elementsParent.classList.remove("hover");
displayElement.innerHTML += id;
} else {
elementsParent.classList.remove("active");
elementsParent.classList.add("hover");
}
}
console.log(total);
displayTotalElement.value = total;
}
Reset the text before the loop:
document.getElementById('display').innerHTML = '';
At the moment you're just always adding to whatever's already there…

Value of Radio buttons using Loop and add HTML text to it

Please see the fiddle link at the bottom. I have two questions:
How to add HTML text to these radio buttons. I have to give them $ and % value (for the user).
Find the values of every radio button selected. For example, the user added 10 rows (each having 2 radio buttons). I have iterated a loop to find the input type and see if the button is checked and then find its value.
NOT WORKING, guide me what wrong am I doing.
FIDDLE
var i=0;
window.myAdd = function(){
var x = i;
var butts = document.createElement("INPUT");
butts.setAttribute("type", "radio");
butts.setAttribute("name", "currency"+x);
butts.setAttribute("value", "%");
butts.setAttribute("id", "radio"+i);
//var node = document.createTextNode("%");
//butts.appendChild(node);
i=i+1;
//console.log(butts);
var butts_1 = document.createElement("INPUT");
butts_1.setAttribute("type", "radio");
butts_1.setAttribute("name", "currency"+x);
butts_1.setAttribute("value", "$");
butts_1.setAttribute("id", "radio"+i);
i=i+1;
//console.log(butts_1);
var row = document.createElement("TR");
//document.getElementById('tab').appendChild(butts);
//document.getElementById('tab').appendChild(butts_1);
row.appendChild(butts);
row.appendChild(butts_1);
document.getElementById('tab').appendChild(row);
x=x+1;
}
window.myfunction = function(table){
//var x = String(document.getElementById('radioP').value);
//alert(x);
for(var i=0;i<table.elements.length;i++){
if(table.elements[i].type =='radio'){
if(table.elements[i].checked == true){
alert(table.elements[i].value);
}
}
}
}
I have corrected your script to work:
var i = 0;
window.myAdd = function() {
var x = i;
var butts = document.createElement("INPUT");
butts.setAttribute("type", "radio");
butts.setAttribute("name", "currency" + x);
butts.setAttribute("value", "%");
butts.setAttribute("id", "radio" + i);
//var node = document.createTextNode("%");
//butts.appendChild(node);
i = i + 1;
//console.log(butts);
var butts_1 = document.createElement("INPUT");
butts_1.setAttribute("type", "radio");
butts_1.setAttribute("name", "currency" + x);
butts_1.setAttribute("value", "$");
butts_1.setAttribute("id", "radio" + i);
i = i + 1;
//console.log(butts_1);
var row = document.createElement("TR");
//document.getElementById('tab').appendChild(butts);
//document.getElementById('tab').appendChild(butts_1);
row.appendChild(butts);
row.appendChild(butts_1);
document.getElementById('mytable').appendChild(row);
x = x + 1;
}
window.myfunction = function(table) {
//var x = String(document.getElementById('radioP').value);
//alert(x);
//debugger;
for (var i = 0; i < table.rows.length; i++) {
var row = table.rows[i];
for (var j = 0; j < row.childNodes.length; j++) {
if (row.childNodes[j].type == 'radio') {
if (row.childNodes[j].checked == true) {
alert(row.childNodes[j].value);
}
}
}
}
}
<button onclick='myAdd()'>Add Radio Buttons</button>
<table id="mytable" name="mytable"></table>
<button onclick='myfunction(document.getElementById("mytable"))'>GET VALUE</button>
1) You have to use <label> element, e.g.:
<input id="radio_1" type="radio" value="1" />
<label for="radio_1">$</label>
<input id="radio_2" type="radio" value="2" />
<label for="radio_2">%</label>
2) You have to iterate through them. Considering all of the radios are within some div with class "container", you'll need something like this:
document.getElementById('get_values').addEventListener('click', function() {
var radios = document.querySelectorAll('.container input[type="radio"]');
values = {};
for(i=0; i<radios.length; i++) {
var radio = radios[i];
var name = radio.getAttribute('name');
if(radio.checked) {
values[name] = radio.value;
} else {
values[name] = values[name] || null;
}
}
alert(JSON.stringify(values));
});
See this fiddle: http://jsfiddle.net/andunai/gx6quyo0/

Categories