I'm trying to add a "clearing" function to my table that calculates totals. So that when person first time presses button that does the calculation, then changes amounts of products and then presses again, the previous answer would be cleared and new added.
I have tried like this:
function clear () {
var table = document.getElementById("pricetable");
var rows = table.getElementsByTagName("tr");
for (var i = 0; i < rows.length; i++) {
rows[i].className = "";
var cells = rows[i].getElementsByTagName("td");
for (var j = 1; j < cells.length - 1; j++) {
cells[j].className = "";
}
}
}
Then I'm calling the function in the beginning of my previous function that calculates the amounts and prices:
function calculate () {
clear ();
...
}
But nothing happens. I was thinking that it might have something to do with the fact that I have created the last row and also the last column (which both include the totals) dynamically. The id of the row is lastRow, and the column doesn't have id.
And I don't want to use jquery or add classes, ids etc to the html file. So does anyone know what's wrong with my code?
className just clears styling.
You're looking for innerHTML:
...
for (var j = 1; j < cells.length - 1; j++) {
cells[j].innerHTML = "";
}
...
className refers to the CSS class name(s) applied to an element. Here's what your current code does:
Before
<td class='foo'>999</td>
After
<td class=''>999</td>
innerHTML pretty much does what it says:
Before
<td class='foo'>999</td>
After
<td class='foo'></td>
Also, I just noticed your for loop starts at 1. Hopefully this was intentional ;)
I can see that you are setting the className to nothing rather than setting the innerHTML to nothing...
Try replacing this:
cells[j].className = "";
With this:
cells[j].innerHTML = "";
Related
I want to change the color of specific table cells when clicking a button.
<button onclick="highlight()">Toggle highlighting</button>
And JS:
function highlight() {
var x = document.getElementsByClassName('best');
for (var i = 0; i < x.length; i++) {
x.get(i).style.color = "green";
}
}
I added the table cells I want to change to the class "best", but when clicking the button, nothing changes. I first tried to assign them all to a single ID and use document.getElementById('best').style.color = "green";, but this only changed the first element that had the id "best" and not all. How should highlight() look like?
You don't need to use x.get(i) there. Just access the element using x[i]
See the following code:
function highlight() {
var x = document.getElementsByClassName('best');
for (var i = 0; i < x.length; i++) {
x[i].style.color = "green";
}
}
First off, I'd recommend using Javascript's built in forEach() function when working with a nodeList like this as there is less chance of an off by one error:
bestElements.forEach(best => {
best.style.color = "green";
});
Second, I believe you may be looking for the background-color attribute, not the color attribute if you are trying to change the color of the entire cell.
bestElements.forEach(best => {
best.style.backgroundColor = "green";
});
Let's say I have a grid that looks like this (the numbers inside the cell is just for labeling, it could just be empty cells):
Written in HTML as follows:
<table>
<tr>
<td>0 </td>
<td>1 </td>
</tr>
<tr>
<td>2 </td>
<td>3 </td>
</tr>
</table>
There are two things that I would like to do:
Add some JavaScript code that log the number of the cell to the console when each cell is clicked. Here is how I did it:
const cells = document.querySelectorAll('td');
for (var i = 0; i < cells.length; i++) {
cells[i].addEventListener('click', function () {
console.log(i);
});
}
But the console always returns the value 4 wherever I click the table. My questions are:
By adding cells[i].addEventListener in each iteration of the for loop, does it add an event listener for each cell?
Why does the console always return 4 even if I clicked the cells[0], cells[\1], cells[2] or cells[3]?
What should I do to make the console return the desired position in the array cells, i.e. return 0 if I clicked cells[0], return 1 if I clicked cells[\1], return 2 if I clicked cells[2], return 3 if I clicked cells[3]?
Next,
The second thing that I would like to do is to change the colour of each cell depending on the colour that I chose from the colour picker as set by the HTML: <input type="color" id="colorPicker">
Here is how I did it:
const cells = document.querySelectorAll('td');
for (var i = 0; i < cells.length; i++) {
cells[i].addEventListener('click', function () {
const color = document.querySelector('#colorPicker').value;
cells[i].style.backgroundColor = color;
});
}
But the colour of the cell did not change.
I don't plan to use jQuery, I would just like to use basic JavaScript that add an event listener to each cell. I have tried to figure some ways out for hours but still clueless in the end. Could somebody please give some help? I really appreciate it, thanks!
Since i is incrementing then after the for loop is complete i == cells.length.
in place of...
for (var i = 0; i < cells.length; i++) {
cells[i].addEventListener('click', function () {
console.log(i);
});
}
use...
for (var i = 0; i < cells.length; i++) {
cells[i].addEventListener('click', function (e) {
console.log(e.target);
});
}
And the same for your latter example...
is because you use "i" variable on your callback. And "i" have value : 4 at the end of your loop, so when you click callback, your app use this last value.
Just change your code by :
const cells = document.querySelectorAll('td');
for (var i = 0; i < cells.length; i++) {
console.log(cells[i].innerText);
cells[i].addEventListener('click', (event) => {
console.log(event.target.innerText); // Take the text node from the element who fire the click event.
// If you don't want to use innerText, you can do like this.
console.log(
//We transform querySelectorAll to traversable array. Then we find index of current event target.
Array.from(document.querySelectorAll('td')).findIndex(e => e === event.target)
);
});
}
And for you second case base on colorPicker :
const cells = document.querySelectorAll('td');
for (var i = 0; i < cells.length; i++) {
cells[i].addEventListener('click', function (event) {
const color = document.querySelector('#colorPicker').value;
event.target.style.backgroundColor = color;
});
}
live sample
I have generated a dynamic html table using java script. Now I need to get the css class of the cell clicked by the user.
How am I supposed to do this?
Here is the code:
function generateSeatMatrix() {
var rows = parseInt(document.getElementById('txtRows').value);
var cols = parseInt(document.getElementById('txtCols').value);
if (!validateMatrixInput(rows, cols)) {
// TODO display error message
return;
}
var matrixTable = document.getElementById('tblMatrix');
if (matrixTable.rows.length > 0) {
for (var k = matrixTable.rows.length - 1; k >= 0; k--) {
matrixTable.deleteRow(k);
}
}
for (var i = 0; i < rows; i++) {
matrixTable.insertRow(i);
for (var j = 0; j < cols; j++) {
matrixTable.rows[i].insertCell(j);
matrixTable.rows[i].cells[j].className = 'matrix-cell';
matrixTable.rows[i].cells[j].setAttribute('onclick', 'hello()');
}
}
}
The 'hello()' function is supposed to handle the required logic. Right now, the function is called properly but I have no idea how to get the selected cell css class. Actually, i tried to send the position as declaring the event (using setAttribute), but then an error raised.
I see you are trying to add a onclick as you built but if you create some jquery like so you can do it. But you would have to have jQuery loaded. Although if you are building this dynamically you may need to use $('document').find('td'). This may not be the solution you are looking for but will get the job done.
$('td').on('click', function(){
var myClass = this.className;
})
Tried adding in comment but wouldn't show code view.
Here is how easily this could be handled..
matrixTable.rows[i].cells[j].setAttribute('onclick', 'hello(' + i + ',' + j + ')');
Well done!
I'm trying to get data from app engine datastore using javascript and json. it's also allowed jsonp service, here the javascript code:
$.getJSON("http://1.handy-post-402.appspot.com/show?callback=?", function(json) {
for (var i = 0; i < json.length; i++) {
var map = json[i].propertyMap;
var content = map.isi;
var user = map.No_HP;
var date = map.tanggal;
$('#date').text(date);
$('#nohp').text(user);
$('#content').text(content);
}
});
you can also check it here: http://jsfiddle.net/YYTkK/7/
unfortunately, it just retrieve 1 latest data from the datastore. am I doing something wrong with this code?
thanks in advance.
You're not appending elements, but simply changing the value of the same 3 elements in question three times. So you simply overwrite the value you put into it the time before. The easiest way to solve this is to designate the existing tr as a .template and clone it in your loop, make the necessary changes (filling in the values) and then appending it.
Fixing some other unclear things this gives the following
$.getJSON("http://1.handy-post-402.appspot.com/show?callback=?", function(records) {
for (var i = 0; i < records.length; i++) {
//Clone the row/unit which we will be using for each record (the class should refer to the type of item it /actually/ is)
row = $(".row.template").clone();
//The template class is hidden, so remove the class from the row/unit
row.removeClass("template");
var map = records[i].propertyMap;
var content = map.isi;
var user = map.No_HP;
var date = map.tanggal;
//Make the required changes (find looks for the element inside var row)
row.find('.date').text(date);
row.find('.nohp').text(user);
row.find('.content').text(content);
//Append it to the parent element which contains the rows/units
$("tbody").append(row);
}
});
See functional demo: http://jsfiddle.net/YYTkK/13/
You must append a new row in the table in every loop. Here's the working fiddle.
fiddle
$.getJSON("http://1.handy-post-402.appspot.com/show?callback=?", function(json) {
for (var i = 0; i < json.length; i++) {
var map = json[i].propertyMap;
var content = map.isi;
var user = map.No_HP;
var date = map.tanggal;
var row = '<tr><td>'+date+'</td><td>'+user+'</td><td>'+content+'</td></tr>';
$('#valuetable').append(row);
}
});
what you have to do is create dynamic "tr" s and append to tbody and use thead for header and separate the body using tbody and create tr s on each iteration and after the loop append that tr to tbody. that will do the job, as you do now it will override the values at each iteration.
#chamweer answer is correct you have to create a new tr with td's dynamically
like this:
http://jsfiddle.net/YYTkK/14/
Because you're overriding the same td's over and over again.
$.getJSON("http://1.handy-post-402.appspot.com/show?callback=?", function(json) {
for (var i = 0; i < json.length; i++) {
var map = json[i].propertyMap;
var content = map.isi;
var user = map.No_HP;
var date = map.tanggal;
// create a temporary tr
var tr = $("<tr />");
// append to the tr the td's with their values
tr.append($("<td />").text(date), $("<td />").text(user),
$('<td />').text(content));
// finally append the new tr to the table's tbody
$("#js-tbody").append(tr);
}
});
I have a requirement of changing all dropdown values in all the rows in a tale based on master dropdown. say someone selects "value 2" in dropdown1, dropdown2 values in all the rows in the table should show "value2".
function change(){
var cid = document.frm.locdropdown.selectedIndex;
document.frm.locdropdown2.selectedIndex = cid;
}
is the java script I use to change it but this changes only first row.
please help..
From your example code it looks like you've given the same ID to all your locdropdown2 elements? Maybe you should post an example of your table HTML. It's normal practice to give unique IDs to elements, so you may want to test the NAME attribute instead, but anyway something like the following should work:
function change() {
var cid = document.frm.locdropdown.selectedIndex;
var inputs = document.getElementsByTagName("input");
for (var i=0, l = inputs.length; i < l; i++) {
if (inputs[i].id == "locdropdown2")
inputs[i].selectedIndex = cid;
}
}
Another option is to loop through each row in the table. The following example assumes your locdropdown2 inputs are the only thing in the third column, but you can adapt to suit your actual layout:
function change() {
var cid = document.frm.locdropdown.selectedIndex;
var tableRows = document.getElementById("yourTableId").tBodies[0].rows;
for (var i=0, l=tableRows.length; i < l; i++) {
tableRows[i].cells[2].firstChild.selectedIndex = cid;
}
}
Note: I haven't actually tested any of that code, but it should be more than enough to get you started and you can tweak as needed. (You can use Google to learn about tBodies, rows, cells, firstChild, etc.)