I am having trouble with what seems like it should be simple. I want to remove an entire row in an HTML table that is holding data from Firebase. I have been able to remove the entire Firebase parent node of users on click of "Delete" from the delete_row function, but I would like to only remove the row that the delete button was clicked on. Thanks in advance!
// table
<table style="width:100%">
<tr>
<td>Id: </td>
<td><input type="text" name="id" id="user_id" /></td>
</tr>
<tr>
<td>Place Name: </td>
<td><input type="text" name="user_name" id="user_name" /></td>
</tr>
<tr>
<td colspan="2">
<input type="button" value="Add Place" onclick="create_row();" />
<input type="button" value="Delete" onclick="delete_row();" />
</td>
</tr>
</table>
<table id="tbl_users_list" border="1">
<tr>
<td>#Id</td>
<td>PLACE NAME</td>
</tr>
</table>
// script to create and delete rows
<script>
var tblUsers = document.getElementById("tbl_users_list");
// firebase reference
var database = firebase.database().ref('users/');
var rowIndex = 1;
database.once('value', function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var childKey = childSnapshot.key;
var childData = childSnapshot.val();
var row = tblUsers.insertRow(rowIndex);
var cellId = row.insertCell(0);
var cellName = row.insertCell(1);
var cellButtons = row.insertCell(2).outerHTML="<tr id='row"+rowIndex+"'><td><input type='button' value='Delete' class='delete' onclick='delete_row()'></td></tr>";
cellId.appendChild(document.createTextNode(childKey));
cellName.appendChild(document.createTextNode(childData.user_name));
rowIndex = rowIndex + 1;
});
});
function create_row() {
var user_name = document.getElementById('user_name').value;
var uid = firebase.database().ref().child('users').push().key;
var data = {
user_id: uid,
user_name: user_name
}
var updates = {};
updates['/users/' + uid] = data;
firebase.database().ref().update(updates);
alert('the user was created successfully');
reload_page();
}
function delete_row() {
var key = document.getElementById(row).row.childData;
firebase.database().ref().child('users/' + row + '/').remove();
alert('row was removed');
reload_page();
}
function reload_page() {
window.location.reload();
}
</script>
You can pass the childKey to your delete_row() method. This way you can tell Firebase which node to delete:
database.once('value', function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var childKey = childSnapshot.key;
var childData = childSnapshot.val();
var row = tblUsers.insertRow(rowIndex);
var cellId = row.insertCell(0);
var cellName = row.insertCell(1);
var cellButtons = row.insertCell(2).outerHTML=
"<tr id='row"+rowIndex+"'><td><input type='button' value='Delete' class='delete' onclick='delete_row("+childKey+")'></td></tr>";
cellId.appendChild(document.createTextNode(childKey));
cellName.appendChild(document.createTextNode(childData.user_name));
rowIndex = rowIndex + 1;
});
});
function delete_row(childKey) {
var key = document.getElementById(row).row.childData;
firebase.database().ref().child('users/' + childKey + '/').remove();
alert('row was removed');
reload_page();
}
So I am facing a similar kind of issue. The main problem is that for all the delete buttons the same key is being passed.
userImagesRef1.once("value", function(snapshot) {
var ParentKey = snapshot.key;
console.log(ParentKey);
snapshot.forEach(function(childSnapshot) {
childSnapshot.forEach(function(snap){
childKey = snap.key;
console.log(childKey);
// alert("child key" + childKey);
var TenderID = snap.child("TenderID").val();
console.log(TenderID);
var NoticeNumber = snap.child("NoticeNumber").val();
var NameofWork = snap.child("NameofWork").val();
var pictures = snap.child("pictures").val();
Link1 = pictures[0];
console.log(Link1);
Link2 = pictures[1];
console.log(pictures[1]);
var Link3 = pictures[2];
console.log(Link3)
if(Link3 == undefined){
Link3 = " ";
}
if(Link3 == null){
Link3 = " ";
}
var Service = String(snap.child("Service").val());
console.log(Service)
var ts = snap.child("timestamp").val();
console.log("TS:" + ts);
var SNo = "";
var id = snap.child("id").val();
var Corrigendum = snap.child("Corrigendum").val();
var State = snap.child("Status").val();
var StartDate = snap.child("StartDate").val();
var EndDate = snap.child("EndDate").val();
var Remarks = snap.child("Remarks").val();
$("#tableBody").append("<tr><td>"+ SNo +"</td><td>"+ id +"</td><td><p>"+TenderID+"</p><p><a href = '" + Link1+"'>" +NoticeNumber+"</p></td>"+"<td>" +NameofWork+"</td><td>" + StartDate + "</td><td>"+EndDate+"</td><td>" + Corrigendum + "</td> <td><a href = '" +Link2+ "'>" +Remarks+"</a></td><td>"+ State +"'<input type='button' value='Delete' class='delete' onclick='delete_row(childKey)'>"+"</td></tr>" );
})
});
});
function delete_row(childKey) {
// var key = document.getElementById(row).row.childData;
// alert("12232");
alert(childKey);
firebase.database().ref().child('user-images/' + childKey + '/').remove();
alert('row was removed');
// reload_page();
}
Related
Today I was working to script, when I wanted to test it, I could see that it didn't works correctly it show the value [object Object] and not the real value (It didn't change the value too). It shows: Click here for see the picture
Its necessary click on "Edit" near of Google or Yahoo. I want to show the correct value when I click "Edit" near Google and Edit it when I click edit. I tried to change the value Checked[Item] for Checker[Name] but it only shows undefined.
html:
<!DOCTYPE html>
<html>
<head>
<title>SSL Checker</title>
<link rel="stylesheet" type="text/css" href="css/style.css">
<script type="text/javascript" src="js/script.js"></script>
<script type="text/javascript" src="js/json.json" charset="utf-8"></script>
</head>
<body onLoad="start()">
<div id="title">
<h1>SSL Checker</h1>
</div>
<div id="data">
<form action="javascript:void(0);" method="POST" onsubmit="SSL.Add()">
<input type="text" id="add-name" placeholder="Name"></input>
<input type="text" id="add-link" placeholder="Link"></input>
<input type="submit" value="Add">
</form>
<div id="edit" role="aria-hidden">
<form action="javascript:void(0);" method="POST" id="saveEdit">
<input type="text" id="edit-name">
<input type="submit" value="Edit" /> <a onclick="CloseInput()" aria-label="Close">✖</a>
</form>
</div>
<p id="counter"></p>
</div>
<div id="table">
<table style="overflow-x:auto;">
<tr>
<th>Sites:</th>
</tr>
<tbody id="urls">
</tbody>
</table>
</div>
</body>
</html>
js:
function start() {
var SSL = new function() {
//List urls to check
this.el = document.getElementById('urls');
this.Count = function(data) {
var el = document.getElementById('counter');
var name = 'url';
if (data) {
if (data > 1) {
name = 'urls';
}
el.innerHTML = 'There are:' + ' ' + data + ' ' + name;
} else {
el.innerHTML = 'No ' + name;
}
};
//Buttons configuration
this.FetchAll = function() {
var data = '';
if (Checker.length > 0) {
for (i = 0; i < Checker.length; i++) {
data += '<tr>';
data += '<td>' + Checker[i].name + '</td>';
data += '<td><button onclick="SSL.Edit(' + i + ')">Edit</button></td>';
data += '<td><button onclick="SSL.Delete(' + i + ')">Delete</button></td>';
data += '</tr>';
}
}
this.Count(Checker.length);
return this.el.innerHTML = data;
};
//Add name
this.Add = function() {
el = document.getElementById('add-name');
el1 = document.getElementById('add-link')
var url = el.value;
var url1 = el1.value;
if (url) {
if (url) Checker.push({
"name": url,
"url": url1
})
el.value = '';
this.FetchAll();
}
}
//Edit
this.Edit = function(item) {
var el = document.getElementById('edit-name');
el.value = Checker[item];
document.getElementById('edit').style.display = 'block';
self = this;
document.getElementById('saveEdit').onsubmit = function() {
var url = el.value;
if (url) {
self.Checker.splice(item, 1, name.trim());
self.FetchAll();
CloseInput();
}
}
};
//Delete
this.Delete = function(item) {
Checker.splice(item, 1);
this.FetchAll();
};
};
SSL.FetchAll();
function CloseInput() {
document.getElementById('edit').style.display = 'none';
}
window.CloseInput = CloseInput;
window.SSL = SSL;
}
json:
var Checker = [{
name:"Google",
url: "google.es",
},
{
name:"Yahoo",
url: "yahoo.com",
}
]
Add another input tag for each attribute of Checkers objects.
<input type="text" id="edit-name">
<input type="text" id="edit-url">
And set each input separately
var el = document.getElementById('edit-name');
el.value = Checker[item].name;
var el2 = document.getElementById('edit-url');
el2.value = Checker[item].url;
Working code:
var Checker = [{
name: "Google",
url: "google.es",
},
{
name: "Yahoo",
url: "yahoo.com",
}
]
document.getElementById('edit').style.display = 'none';
function start() {
var SSL = new function() {
//List urls to check
this.el = document.getElementById('urls');
this.Count = function(data) {
var el = document.getElementById('counter');
var name = 'url';
if (data) {
if (data > 1) {
name = 'urls';
}
el.innerHTML = 'There are:' + ' ' + data + ' ' + name;
} else {
el.innerHTML = 'No ' + name;
}
};
//Buttons configuration
this.FetchAll = function() {
var data = '';
if (Checker.length > 0) {
for (i = 0; i < Checker.length; i++) {
data += '<tr>';
data += '<td>' + Checker[i].name + '</td>';
data += '<td><button onclick="SSL.Edit(' + i + ')">Edit</button></td>';
data += '<td><button onclick="SSL.Delete(' + i + ')">Delete</button></td>';
data += '</tr>';
}
}
this.Count(Checker.length);
return this.el.innerHTML = data;
};
//Add name
this.Add = function() {
el = document.getElementById('add-name');
el1 = document.getElementById('add-link')
var url = el.value;
var url1 = el1.value;
if (url) {
if (url) Checker.push({
"name": url,
"url": url1
})
el.value = '';
this.FetchAll();
}
}
//Edit
this.Edit = function(item) {
var el = document.getElementById('edit-name');
el.value = Checker[item].name;
var el2 = document.getElementById('edit-url');
el2.value = Checker[item].url;
document.getElementById('edit').style.display = 'block';
self = this;
document.getElementById('saveEdit').onsubmit = function() {
var url = el2.value;
var name = el.value;
if (url && name) {
Checker[item].name = name;
Checker[item].url = url;
self.FetchAll();
CloseInput();
}
}
};
//Delete
this.Delete = function(item) {
Checker.splice(item, 1);
this.FetchAll();
};
};
SSL.FetchAll();
function CloseInput() {
document.getElementById('edit').style.display = 'none';
}
window.CloseInput = CloseInput;
window.SSL = SSL;
}
<html>
<head>
<title>SSL Checker</title>
</head>
<body onLoad="start()">
<div id="title">
<h1>SSL Checker</h1>
</div>
<div id="data">
<form action="javascript:void(0);" method="POST" onsubmit="SSL.Add()">
<input type="text" id="add-name" placeholder="Name"></input>
<input type="text" id="add-link" placeholder="Link"></input>
<input type="submit" value="Add">
</form>
<div id="edit" role="aria-hidden">
<form action="javascript:void(0);" method="POST" id="saveEdit">
<input type="text" id="edit-name">
<input type="text" id="edit-url">
<input type="submit" value="Edit" /> <a onclick="CloseInput()" aria-label="Close">✖</a>
</form>
</div>
<p id="counter"></p>
</div>
<div id="table">
<table style="overflow-x:auto;">
<tr>
<th>Sites:</th>
</tr>
<tbody id="urls">
</tbody>
</table>
</div>
</body>
</html>
You are getting correct output with [object Object], because Object.toString() returns exactly [object Object].
To represent your object in a custom format you can change the part of your SSL.Edit() method where you do el.value = Checker[item] to something like
el.value = Checker[item].name; // To show the name
el.value = Checker[item].url; // To show the url
el.value = Checker[item].url + ' ' + Checker[item].url; // To show both
This is the way on how I populate data in my table.
<script>
function GenerateTable() {
<? var data = getData(); ?>
var table = document.getElementById("TableContainer");
<? for (var i = 12; i < data.length; i++) { ?>
var getval;
var row = table.insertRow(-1);
var row_did = row.insertCell(0);
var row_area = row.insertCell(1);
var row_cusname = row.insertCell(2);
var row_pic = row.insertCell(3);
var row_remarks = row.insertCell(4);
var row_status = row.insertCell(5);
var row_docudate = row.insertCell(6);
var row_button = row.insertCell(7);
row_did.innerHTML = '<td id="dataid" class="dataid">'+ <?= data[i][0] ?> + '</td>';
row_area.innerHTML = '<td id="area" class="area">'+ <?= data[i][1] ?> +'<td>';
row_cusname.innerHTML = '<td id ="cusname" class="cusname">' + <?= data[i][2] ?> +'<td>';
row_pic.innerHTML = '<td id ="cic" class="cic">' + <?= data[i][3] ?> +'<td>';
row_remarks.innerHTML = '<td id ="remarks" class="remarks">' + <?= data[i][4] ?> +'<td>';
row_status.innerHTML = '<td id ="status" class="status">' +<?= data[i][5] ?> +'<td>';
row_docudate.innerHTML = '<td id ="docdate" class="docdate">'+ <?= data[i][6] ?> +'<td>';
row_button.innerHTML = '<td><img id = "selectdata" class = "click-to-select" src="https://docs.google.com/uc?id=0By6kUPbaVMWCbUI0LTJTR2g2N3M" alt="Submit" width="13px" height="13px" title = "Edit Selected Data" data-toggle="modal" data-target="#myModal"/></td>';
<? } ?>
}
</script>
and this is my table where i put the data based on code above.
<table id = "TableContainer" cellspacing="2" cellpadding="3" width ="100%" align = "center" class="hoverTable">
<tr>
<th bgcolor = "darkgreen"><font color="white">#</font></th>
<th bgcolor = "darkgreen"><font color="white">Area</font></th>
<th bgcolor = "darkgreen" width = "200px"><font color="white">Customer Name</font></th>
<th bgcolor = "darkgreen"><font color="white">Person In Charge</font></th>
<th bgcolor = "darkgreen" width = "250px"><font color="white">Remarks</font></th>
<th bgcolor = "darkgreen"><font color="white">Status</font></th>
<th bgcolor = "darkgreen"><font color="white">Doc. Date</font></th>
<th bgcolor = "darkgreen"></th>
</tr>
<tr>
</tr>
</table>
Please bear with me. this code is perfectly running and im running the code by '<body onLoad = "GenerateTable()"> how ever as what you see on my code there is a code that looks like this.
<td><img id = "selectdata" class = "click-to-select" src="https://docs.google.com/uc?id=0By6kUPbaVMWCbUI0LTJTR2g2N3M" alt="Submit" width="13px" height="13px" title = "Edit Selected Data" data-toggle="modal" data-target="#myModal"/></td>';
now it will create an image button for every row in my table and that code has a purpose and that is to transfer the data from td to textbox and other elements and here is my code for that.
<script>
$('.click-to-select').click(function() {
var dataid = $(this).closest('tr').find('td.dataid').text();
var area = $(this).closest('tr').find('td.area').text();
var cusname = $(this).closest('tr').find('td.cusname').text();
var cicoption = $(this).closest('tr').find('td.cic').text();
var remarks = $(this).closest('tr').find('td.remarks').text();
var statoption = $(this).closest('tr').find('td.status').text();
var documentdate = $(this).closest('tr').find('td.docdate').text();
$('#dataid').val(dataid)
$('#areaoption').val(area)
$('#cusname').val(cusname)
$('#cicoption').val(cicoption)
$('#remarks').val(remarks)
$('#statoption').val(statoption)
$('#documentdate').val(documentdate)
});
</script>
this is where the error starts when im clicking the image the row data is not transferring in my textbox whats the error?
Updated Code
<script>
function GenerateTable() {
<? var data = getData(); ?>
var table = document.getElementById("TableContainer");
<? for (var i = 12; i < data.length; i++) { ?>
var row = table.insertRow(-1);
var row_did = row.insertCell(0);
var row_area = row.insertCell(1);
var row_cusname = row.insertCell(2);
var row_pic = row.insertCell(3);
var row_remarks = row.insertCell(4);
var row_status = row.insertCell(5);
var row_docudate = row.insertCell(6);
var row_button = row.insertCell(7);
row_did.innerHTML = '<td id="dataid" class="dataid">'+ <?= data[i][0] ?> + '</td>';
row_area.innerHTML = '<td id="area" class="area">'+ <?= data[i][1] ?> +'<td>';
row_cusname.innerHTML = '<td id ="cusname" class="cusname">' + <?= data[i][2] ?> +'<td>';
row_pic.innerHTML = '<td id ="cic" class="cic">' + <?= data[i][3] ?> +'<td>';
row_remarks.innerHTML = '<td id ="remarks" class="remarks">' + <?= data[i][4] ?> +'<td>';
row_status.innerHTML = '<td id ="status" class="status">' +<?= data[i][5] ?> +'<td>';
row_docudate.innerHTML = '<td id ="docdate" class="docdate">'+ <?= data[i][6] ?> +'<td>';
row_button.innerHTML = '<td><img id = "selectdata" class = "click-to-select" src= "https://docs.google.com/uc?id=0By6kUPbaVMWCbUI0LTJTR2g2N3M" alt="Submit" width="13px" height="13px" title = "Edit Selected Data" data-toggle="modal" data-target="#myModal"/></td>';
<? } ?>
$('.click-to-select').click(function() {
var dataid = $(this).closest('tr').find('td.dataid').text();
var area = $(this).closest('tr').find('td.area').text();
var cusname = $(this).closest('tr').find('td.cusname').text();
var cicoption = $(this).closest('tr').find('td.cic').text();
var remarks = $(this).closest('tr').find('td.remarks').text();
var statoption = $(this).closest('tr').find('td.status').text();
var documentdate = $(this).closest('tr').find('td.docdate').text();
$('#dataid').val(dataid)
$('#areaoption').val(area)
$('#cusname').val(cusname)
$('#cicoption').val(cicoption)
$('#remarks').val(remarks)
$('#statoption').val(statoption)
$('#documentdate').val(documentdate)
});
}
</script>
TYSM
Could you put your second script $('.click-to-select').click(function(){...}) inside of GenerateTable() and after the for loop? Then check if the click handler is running by putting console.log('The dataid is:' + dataid) in here.
$('.click-to-select').click(function(){...
...
var documentdate = $(this).closest('tr').find('td.docdate').text();
console.log('The dataid is:' + dataid)
$('#dataid').val(dataid)
...
}
I can't tell for sure the order that your code executes because you have two separate script tags here, but it's possible your second script can't bind the click handler because the .click-to-selects haven't been created yet by GenerateTable().
Here is a working fiddle using nth-of-type selectors
First you need to remove the id from td because some of it matches with textbox element.
Then replace it with below line of code and do the same for each column.
var dataid = $(this).parent().siblings('.dataid').text();
I think , This function should be like below
Don't use the php tags because these are javascript variables .
function GenerateTable() {
var data = getData();
var table = document.getElementById("TableContainer");
for (var i = 12; i < data.length; i++) {
var row = table.insertRow(-1);
var row_did = row.insertCell(0);
var row_area = row.insertCell(1);
var row_cusname = row.insertCell(2);
var row_pic = row.insertCell(3);
var row_remarks = row.insertCell(4);
var row_status = row.insertCell(5);
var row_docudate = row.insertCell(6);
var row_button = row.insertCell(7);
row_did.innerHTML = '<td id="dataid" class="dataid">'+ data[i][0] + '</td>';
row_area.innerHTML = '<td id="area" class="area">'+ data[i][1] +'<td>';
row_cusname.innerHTML = '<td id ="cusname" class="cusname">' + data[i][2] +'<td>';
row_pic.innerHTML = '<td id ="cic" class="cic">' + data[i][3] +'<td>';
row_remarks.innerHTML = '<td id ="remarks" class="remarks">' + data[i][4] +'<td>';
row_status.innerHTML = '<td id ="status" class="status">' + data[i][5] +'<td>';
row_docudate.innerHTML = '<td id ="docdate" class="docdate">'+ data[i][6] +'<td>';
row_button.innerHTML = '<td><img id = "selectdata" class = "click-to-select" src= "https://docs.google.com/uc?id=0By6kUPbaVMWCbUI0LTJTR2g2N3M" alt="Submit" width="13px" height="13px" title = "Edit Selected Data" data-toggle="modal" data-target="#myModal"/></td>';
}
$('.click-to-select').click(function() {
var dataid = $(this).closest('tr').find('td.dataid').text();
var area = $(this).closest('tr').find('td.area').text();
var cusname = $(this).closest('tr').find('td.cusname').text();
var cicoption = $(this).closest('tr').find('td.cic').text();
var remarks = $(this).closest('tr').find('td.remarks').text();
var statoption = $(this).closest('tr').find('td.status').text();
var documentdate = $(this).closest('tr').find('td.docdate').text();
$('#dataid').val(dataid)
$('#areaoption').val(area)
$('#cusname').val(cusname)
$('#cicoption').val(cicoption)
$('#remarks').val(remarks)
$('#statoption').val(statoption)
$('#documentdate').val(documentdate)
});
}
Hopefully , it may help you .
I have:
$('#createStockOrder').click(function () {
modal('create-stock-order', {}, function () {
var $modal = $(this);
var submitted = false;
var model = [];
$('.glyphicon-plus').click(function () {
var product_id = $('#productSelect option:selected').text(),
size_id = $('#sizeSelect option:selected').text(),
colour_id = $('#colourSelect option:selected').text(),
quantity = $('#quantity').val();
// Get index of the element where all the fields matches
var index = getObjectIndex(model, product_id, size_id, colour_id);
// If object found in the array
if (index !== false) {
// Update the quantity in the same element
model[index].quantity = quantity;
} else {
// Add the element in the array
model.push({
product_id: product_id,
size_id: size_id,
colour_id: colour_id,
quantity: quantity
});
}
printStock(model);
});
var form = document.getElementById('create_sale');
var $form = $(form);
$form.on('submit', function (e) {
e.preventDefault();
if (!submitted) {
submitted = true;
$('#create_sale .btn-primary').addClass('disabled');
var formData = new FormData(form);
qwest.post(form.action, formData)
.then(function (resp) {
$modal.modal('hide');
})
.catch(function (xhr, response, e) {
var html = '';
$.each(response, function (i, v) {
html += '<p>' + v + '</p>';
});
$('#create_sale .alert').html(html).removeClass('hide');
$('#create_sale .btn-primary').removeClass('disabled');
submitted = false;
});
}
})
}, {width: 1000});
});
// Currently the function is Static, but it can be changed to dynamic
// by using nested loop and a flag to store the match status
function getObjectIndex(arr, product_id, size_id, colour_id) {
// Loop over array to find the matching element/object
for (var i = 0; i < arr.length; i++) {
var obj = arr[i];
if (obj.product_id === product_id && obj.size_id === size_id && obj.colour_id === colour_id) {
// When all key-value matches return the array index
return i;
}
}
// When no match found, return false
return false;
}
function printStock(model) {
var html = '';
var total_row_quantity = 0;
var total_row_value = 0;
$.each(model, function (i1, v1) {
html += '<tr>';
$.each(v1, function (i2, v2) {
html += '<td>' + v2 + '</td>';
$('#product_totals tr').each(function(i3, v3){
var product_code = $('td', v3).eq(0).html();
if(product_code == v2) {
total_row_quantity += parseInt(model[i1].quantity);
total_row_value += parseFloat($('td', v3).eq(2).html()*model[i1].quantity);
$('td', v3).eq(1).html(total_row_quantity);
$('td', v3).eq(3).html(accounting.formatMoney(total_row_value, ''));
} else {
total_row_quantity = 0;
total_row_value = 0;
}
})
});
html += '</tr>';
});
$('#stock_order tbody').html(html);
}
The HTML is:
<tbody id="product_totals">
<tr data-id="1">
<td>JW1501</td>
<td class="code-quantity-total">0</td>
<td>79.00</td>
<td class="code-cost-total">0</td>
</tr>
<tr data-id="2">
<td>JW1502</td>
<td class="code-quantity-total">0</td>
<td>99.00</td>
<td class="code-cost-total">0</td>
</tr>
<tr data-id="3">
<td>JW1501-1</td>
<td class="code-quantity-total">0</td>
<td>20.00</td>
<td class="code-cost-total">0</td>
</tr>
<tr data-id="4">
<td>JW1502-2</td>
<td class="code-quantity-total">0</td>
<td>25.00</td>
<td class="code-cost-total">0</td>
</tr>
</tbody>
The list of rows (JW1501, JW1502) is dynamic.
The problem I am having is that if a variant of e.g. JW1502 is added, only the total quantity and value is calculated for that one. Any previous different variants of JW1502 are ignored.
How can I fix this?
Example content of var model:
[
{"product_id":"JW1501","size_id":"70A","colour_id":"小豹纹","quantity":"1"},
{"product_id":"JW1501","size_id":"75B","colour_id":"小豹纹","quantity":"2"},
{"product_id":"JW1502","size_id":"85A","colour_id":"黑色","quantity":"1"}
]
The above for JW1501 would show the incorrect quantity of 2, not 3.
...
$('#product_totals tr').each(function (i3, v3) {
console.log(v1, v2, v3)
...
Outputs:
Object {product_id: "JW1501", size_id: "70A", colour_id: "小豹纹", quantity: "2"}
"JW1501"
<tr data-id="1"><td>JW1501</td><td class="code-quantity-total">2</td><td>79.00</td><td class="code-cost-total">158.00</td></tr>
I have completely changed your printStock function to achieve your goal:
function printStock(model) {
$("#product_totals tr").each(function(){
var id = $("td:eq(0)", this).text().trim();
var price = parseFloat($("td:eq(2)", this).text());
var count = 0;
$.each(model, function(i, item){
if (item.product_id == id) count += (+item.quantity);
});
$("td:eq(1)", this).text(count);
$("td:eq(3)", this).text((count * price).toFixed(2));
});
var rows = $.map(model, function(item){
return [
"<td>" + item.product_id + "</td>",
"<td>" + item.size_id + "</td>",
"<td>" + item.colour_id + "</td>",
"<td>" + item.quantity + "</td>"
].join("");
});
var html = "<tr>" + rows.join("</tr><tr>") + "</tr>";
$('#stock_order tbody').html(html);
}
The main difference is that my code groups items in model by product_id for further counting.
Also refer my fiddle.
I have two functions - one takes a URL in a certain format (e.g. "test.com?action=query&max_results=20") and breaks it down into dynamically generated textboxes for editing. The other puts it back together along with any edits. Both functions are called by clicking a button.
The second function is unable to find the ids of the dynamically generated textboxes - they're coming back as "null". How do I get the function to recognise ids created after the page loads?
Code:
<script>
function Split()
{
//Get table body for insert
var table = document.getElementById("ValueTableBody");
//Clear table of rows
table.innerHTML = '';
//Grab URL
var URLquery = document.getElementById("oldquery").value;
//Split on ? to isolate query
var querysplit = oldquery.split("?");
//Store main url
var mainURL = document.getElementById('mainURL');
mainURL.value=querysplit[0];
//Split on & to isolate variables
var splitagain = querysplit[1].split("&");
var i = 0;
//Loop on number of variables in query
for(i = 0; i < splitagain.length; i++){
//Split on = to isolate variables and values
var splitthird = splitagain[i].split("=");
//Insert new row into table
var row = table.insertRow(i);
row.insertCell(0).innerHTML = '<input type="text" id="query' + i + '"/>';
row.insertCell(1).innerHTML = '<input size="50" type="text" id="queryvalue' + i + '"/>';
//Insert variable and value into respective inputs.
var split1 = document.getElementById('query' + i);
split1.value=splitthird[0];
var split2 = document.getElementById('queryvalue' + i);
split2.value=splitthird[1];
}
}
function Unsplit()
{
var mainURL = document.getElementById('mainURL').value;
var completequery = [];
var URLarray = [];
var rowCount = document.getElementById('ValueTableBody').rows.length;
for(i = 0; i <= rowCount; i++){
//Get variable of current row
var value1 = document.getElementById('query' + i).value;
//Get value of current row
var value2 = document.getElementById('queryvalue' + i).value;
if (value1) {
if (value2) {
//If both have value, then push into array
valueArray = [];
valueArray.push(value1);
valueArray.push(value2);
//Merge into one to push into next array
var newvalue = valueArray.join("=");
URLarray.push(newvalue);
}
}
}
//Join all sections of the query together
mergearray = URLarray.join("&");
//Push mainURL
completequery.push(mainURL);
//Push completed query
completequery.push(mergearray);
//Join the query together to make complete new URL
mergearray2 = completequery.join("?");
//Display new URL
var newquery = document.getElementById('newquery');
newquery.value=mergearray2;
//Output new URL to iframe
document.getElementById('webservicedisplay').src = mergearray2;
}
</script>
HTML:
<div style="float:left;">
<h1>Webservice Tester</h1>
<p><label style="font-weight:bold; display:inline-block; vertical-align:top;">Old Webservice Call:</label> <textarea cols="60" rows="4" id="oldquery"></textarea></p>
<input type="submit" name="button" id="splitbutton" onclick="Split()" value="Split!" /> <br><br>
<p><label style="font-weight:bold;">URL:</label> <input type="text" size="50" id="mainURL"></input></p><br>
<table id="ValueTable">
<thead>
<th>Variable</th>
<th>Value</th>
</thead>
<tbody id="ValueTableBody">
</tbody>
</table>
<br>
<p><input type="submit" name="button" id="unsplit" onclick="Unsplit()" value="Unsplit!" /></p> <br><br>
<p><label style="font-weight:bold; vertical-align:top;">New Webservice Call:</label> <textarea cols="60" rows="4" id="newquery"></textarea></p>
</div>
<div style="float:left; padding-left:20px;">
<p><label style="font-weight:bold;">Output:</label></p><br>
<iframe height="450" width="500" id="webservicedisplay" src="">
</iframe>
This was fixed by the author because the 'issue was actually the loop having the "<=" condition - it was looking for one more table row that didn't exist.'
I had suggested to write the JS differently as so:
row.insertCell(0).innerHTML = '<input type="text" id="query' + i + '" value="' + splitthird[0] + '"/>';
row.insertCell(1).innerHTML = '<input size="50" type="text" id="queryvalue' + i + '" value="' + splitthird[1] + '"/>';
And remove:
//Insert variable and value into respective inputs.
var split1 = document.getElementById('query' + i);
split1.value=splitthird[0];
var split2 = document.getElementById('queryvalue' + i);
split2.value=splitthird[1];
I have a problem with JavaScript dynamic input fields. I have three fields, one with a number and two with a & b. My problem is displaying the b input field under the a input field.
My code:
<script language="JavaScript" type="text/javascript">
function addRowToTable()
{
var tbl = document.getElementById('tblSample');
var lastRow = tbl.rows.length;
// if there's no header row in the table, then iteration = lastRow + 1
var iteration = lastRow;
var row = tbl.insertRow(lastRow);
// left cell
var cellLeft = row.insertCell(0);
var textNode = document.createTextNode(iteration);
cellLeft.appendChild(textNode);
// right cell
var cellRight1 = row.insertCell(1);
var el = document.createElement('input');
el.type = 'text';
el.name = 'element_45_1' + iteration;
el.id = 'element_45_1' + iteration;
el.size = 40;
//el.onkeypress = keyPressTest;
cellRight1.appendChild(el);
// right cell
var cellRight2 = row.insertCell(2);
var el = document.createElement('input');
el.type = 'text';
el.name = 'element_45_2' + iteration;
el.id = 'element_45_2' + iteration;
el.size = 40;
//el.onkeypress = keyPressTest;
cellRight2.appendChild(el);
// right cell
var cellBottom3 = row.insertCell(3);
var el = document.createElement('input');
el.type = 'text';
el.name = 'element_45_12' + iteration;
el.id = 'element_45_12' + iteration;
el.size = 40;
//el.onkeypress = keyPressTest;
cellBottom3.appendChild(el);
}
function removeRowFromTable()
{
var tbl = document.getElementById('tblSample');
var lastRow = tbl.rows.length;
if (lastRow > 2) tbl.deleteRow(lastRow - 1);
}
</script>
<form action="tableaddrow_nw.html" method="get">
<table width="540" border="1" id="tblSample">
<tr>
<th colspan="3">Sample table</th>
</tr>
<tr>
<td width="8">1</td>
<td width="240">
<input type="text" name="element_45_1"
id="element_45_1" size="40" />
</td>
<td width="20">
<div1>
a.
<input type="text" name="element_45_2"
id="element_45_2" size="40" />
</div1>
</td>
<td width="20">
b.
<input type="text" name="element_45_12"
id="element_45_12" size="40" />
</td>
</tr>
</table>
</form>
<p>
<input type="button" value="Add" onclick="addRowToTable();" />
<input type="button" value="Remove" onclick="removeRowFromTable();" />
</p>
If you are trying to dynamically add a row which has the Iteration Count as first data-cell (td), one input box as second cell and two input boxes placed one below the other as the third cell, you can try the following piece of code.
// right cell
var cellRight2 = row.insertCell(2);
var textNode = document.createTextNode('a');
cellRight2.appendChild(textNode);
var el1 = document.createElement('input');
el1.type = 'text';
el1.name = 'element_45_2' + iteration;
el1.id = 'element_45_2' + iteration;
el1.size = 40;
cellRight2.appendChild(el1);
var textNode = document.createTextNode('b');
cellRight2.appendChild(textNode);
var el2 = document.createElement('input');
el2.type = 'text';
el2.name = 'element_45_12' + iteration;
el2.id = 'element_45_12' + iteration;
el2.size = 40;
//el.onkeypress = keyPressTest;
cellRight2.appendChild(el2);
Based on your response, I think this is what you are looking for.
function addMoreVillageNames(){
rowNumber = (this.id).substring((this.id.length)-1, this.id.length); //to get Row Number where one more input needs to be added.
var parentCell = this.parentNode;
var inputCount = parentCell.getElementsByTagName('label').length; //to get the count of input fields present already
var newFieldNo = inputCount + 1; //input current count by 1 to dynamically set next number for the new field
parentCell.removeChild(this); //temporarily remove the add village button to insert the new field before it
var lineBreak = newElement('br');
parentCell.appendChild(lineBreak); //add a line break after the first field
var el_label = newElement('label');
el_label.for = 'village_text_' + rowNumber + '_' + newFieldNo;
var el_labelValue = newFieldNo + ' ';
var textNode = newTxt(el_labelValue);
el_label.appendChild(textNode);
parentCell.appendChild(el_label); //create and add label
var el_input = newElement('input');
el_input.type = 'text';
el_input.name = 'village_text_' + rowNumber + '_' + newFieldNo;
el_input.id = 'village_text_' + rowNumber + '_' + newFieldNo;
el_input.size = 40;
parentCell.appendChild(el_input); //create and add input field
var el_btn = newElement('input'); //add the village name add button again
el_btn.type = 'button';
el_btn.name = 'village_btn_' + rowNumber;
el_btn.id = 'village_btn_' + rowNumber;
el_btn.value = 'Add Village_' + rowNumber;
el_btn.addEventListener('click',addMoreVillageNames, false);
parentCell.appendChild(el_btn);
}
Use rowspan for making the a and b in same row.
<tr>
<td width="8" rowspan="2">1</td>
<td width="240" rowspan="2">
<input type="text" name="element_45_1"
id="element_45_1" size="40" />
</td>
<td width="20">
<div1>
a.
<input type="text" name="element_45_2"
id="element_45_2" size="40" />
</div1>
b.
<input type="text" name="element_45_12"
id="element_45_12" size="40" />
</td>
</tr>
Here is the working fiddle: Fiddle