I am kind of new to javascript and trying to accomplish a simple (yet complicated for me) task. I am trying to exclude first row and first column from a table and got stuck in excluding first cell in every row from this table (HTMLTableRowElement). Following is my sample code.
function clickSchedule(){
var table
var grow // group row
table= document.getElementById("myTable");
grow = table.rows;
for(var i= 1; i<= grow.length ; i++ ){
var cellIndex = this.cells;
for( var j =1 ; j<= cellIndex.length ; j++ ){
this.onclick = function () {
alert("test");
}
}
}
The first "for loop" will grab all rows from the table excluding row[0] that is why you can see var i = 1. Next, I am storing cells from all rows to a variable and trying to exclude cell[0] using second "for loop" in order to perform an onclick event to the selected table area.
Also, is it possible to get the index value of the selected cell from this table?
I would really appreciated your help
Faraz Amjad
Your logical part is right and wrong.
Start iteration from index 1 is right.
i <= grow.length means when it's true, go on iteration. But when i == grow.length, grow[i] should be undefined, because grow.length-1 is the last index. So the right condition expression should be i < grow.length.
You didn't do event binding right in iterations.
Try this one:
(function(){
var table = document.querySelector('table')
var rows = table.rows
var cells
for(var i = 1; i < rows.length; i++ ) {
cells = rows[i].cells
for(var j = 1; j < cells.length; j++ ) {
cells[j].onclick = function() {
alert(this.innerHTML);
}
}
}
})()
<table>
<tr>
<td>a1</td><td>a2</td><td>a3</td><td>a4</td>
</tr>
<tr>
<td>b1</td><td>b2</td><td>b3</td><td>b4</td>
</tr>
<tr>
<td>c1</td><td>c2</td><td>c3</td><td>c4</td>
</tr>
<tr>
<td>d1</td><td>d2</td><td>d3</td><td>d4</td>
</tr>
</table>
Related
I have my input table which already filled by the user. now what I am trying to do is to loop on my table and change the value of each cell td using my JavaScript. some of my cells has input field and others only have text between td tags. I loop on my table correctly and I change the values of cells that has input field using the expression table.rows[R].cells[C].children[0].value = value; but I do not know how to change the cell that has only text between td tags without input field! tried to write table.rows[R].cells[C].value = value but its not working!
my table code:
var table = document.getElementById('table');
var rowCount = table.rows.length;
var colCount = document.getElementById('table').rows[0].cells.length;
for (var r = 1; r < rowCount; r++) {
for (var c = 1; c < colCount - 1; c++) {
table.rows[r].cells[c].children[0].value = somevalue; // this works with cells that has input field but not with cells that has not
table.rows[r].cells[c] value = somevalue; // tried this line but not working
}
}
Based on your explanation I understand that you want to modify the values of all td tags (input child or text child). In your snippet there are two problems in order to achieve this:
The start index of the “column loop” (c) is 1 and you loop until
this index is less than the length of all columns. This means that
you’ll loop through all the columns except the first and last one.
Maybe this is your intention.
You have a syntax error in the last line of the last for loop.
For your “main” problem, it seems like you are treating the cells the same even though some contain input elements and some text nodes. You can simply solve this by adding some logic and depending on if the cell has children (an input field) or not (text-node) you treat it respectively. For text nodes we simply modify the innerHTML.
Here's a snippet which should do the job for you if I understood you correctly:
var table = document.getElementById("table");
var rowCount = table.rows.length;
var colCount = document.getElementById("table").rows[0].cells.length;
var somevalue = "modified value";
for (var r = 1; r < rowCount; r++) {
for (var c = 0; c < colCount; c++) {
const cell = table.rows[r].cells[c];
if (cell.children.length) {
cell.children[0].value = somevalue;
} else {
cell.innerHTML = somevalue;
}
}
}
I'm creating an HTML table from a server-side array (google apps script; so tableArray is coming from there). I have two forEach functions which work. However, I'm attempting to use two for loops instead because I'd like to be able to add different classes to different <td>'s.
The output doesn't come out as expected (see #1 below). I can either get an array in one column (instead of each element of the array as a separate <td> or the arrays are repeated in each <td> (see #2 below).
What do I need to change in my for loops to get the expected output?
You can see the version that works HERE.
1 (works with forEach)
2 (does not work with for)
Index.html
function buildTable(tableArray) {
var table = document.getElementById('table');
var tableBody = document.createElement('tbody');
var tbodyID = tableBody.setAttribute('id', 'tbody');
for (var i = 0; i < tableArray.length; ++i) {
var column = tableArray[i];
var colA = column[0];
var colB = column[1];
var colC = column[2];
var colD = column[3];
if (colA != "") {
var row = document.createElement('tr');
for (var j = 0; j < column.length; ++j) {
var cell = document.createElement('td');
cell.appendChild(document.createTextNode(column));
row.appendChild(cell);
}
}
tableBody.appendChild(row);
}
table.appendChild(tableBody);
document.body.appendChild(table);
}
Instead of line cell.appendChild(document.createTextNode(column));
write cell.appendChild(document.createTextNode(column[j]));
You've forgotten to add index [j]
// Loop over rows
for (var i = 0; i < tableArr.length; i++) {
var row = tableArr[i];
// loop over columns
for( var j =0; j<row.length; j++){
//create each column and append to row
}
// append row to table body
}
// append table body to DOM
For performance reasons you want to write to the DOM only once and create the table in memory first.
Change
cell.appendChild(document.createTextNode(column));
to
cell.appendChild(document.createTextNode(column[i]));
This will make it loop through all of your column data properly instead of appending the same content of the whole array repeatedly.
Trying to get my dynamic table to have a button in last column. Have had no luck. Any help much appreciated.
var removeRow=document.createElement("BUTTON");
//Add the data rows.
for (var i = 1; i < data.length; i++) {
row = table.insertRow(-1);
for (var j = 0; j < 3; j++) {
var cell = row.insertCell(-1);
if (j==0) {
cell.innerHTML = data[i].userId}
if (j==1) {
cell.innerHTML = data[i].id}
if (j==2) {
cell.innerHTML = data[i].title}
if (j==3) {
cell.appendChild(removeRow)// Not working when replace data[i].field with button variable.
}
}
In your loop, j never gets to 3 (it says j < 3 in your second for statement).
If you change that to j < 4 or j <= 3 it should work.
Apart from that, you are only creating one BUTTON element, which you will be appending to all rows. Every time you append it to a row, it will be removed from the previous row it was on, so you'll still be left with just one button.
I am searching my Table Column for the string "None". It does this but I am unable to get the row number after. I am attempting to use the "rowIndex" attribute. Not sure why it is pulling "Not a Number" (NaN). Table is 50 rows 10 cols. I am assuming it may have to do with that I am pulling from a column instead of Row.
function F0416()
{
var tab = document.getElementById('part1Table');
var l = tab.rows.length;
var s = '';
for ( var i = 0; i < l; i++ )
{var tr = tab.rows[i];
var cll = tr.cells[2];
s += ' ' + cll.innerText;
}
var y = (s.indexOf('None') != -1)
document.write(this.rowIndex + 1)
Instead of concatenating all the values of the column into a string and searching the string, you could instead test the value of each cell in the column for the value 'None'. Then you would know the row number from the loop counter, and you could halt the loop if you find it instead of iterating over every row.
It would look more like this:
for ( var i = 0; i < l; i++ ) {
var tr = tab.rows[i];
var cll = tr.cells[2];
if(cll.innerText.indexOf('None') != -1) {
document.write(i + 1);
break;
}
}
You could also return the value of the row instead of outputting it.
I would recommend using a rich javascript library like JQuery.
Then given the following HTML:
<table>
<tr><td>Row 1- Column 1</td><td>Row 1 - Column 2</td>
<tr><td>none</td><td>Row 2 - Column 2</td>
<tr><td>Row 3- Column 1</td><td>Row 3 - Column 2</td>
</table>
You can use the following to get all the rows containing none:
var rows = $('table tr').filter(":contains('none')");
Have a look at this Fiddle example.
Lets say that I have a very simple table:
<table>
<tr>
<td>TextFirst</td>
<td>TextSecond</td>
</tr>
</table>
How can I traverse the table and remove "TextSecond". The table could be any number of rows or cells.
In your posted example you have, at least, two options I can think of:
$('td:nth-child(2)').remove();
Or:
$('tr td:eq(1)').remove(); // zero-based index, thanks #ZDYN for the catch
Or, in plain JavaScript:
var removeThis = document.getElementsByTagName('td')[1];
removeThis.parentNode.removeChild(removeThis);
JS Fiddle demo.
$("table td:nth-child(2)").remove()
//var table = document.getElementById("?");
for (i=0; i < table.rows.length; i++)
{
if (table.rows[i].cells.length > 1)
table.rows[i].cells[1].removeNode(true);
}
or if you want to delete cells based on some condition. just because
//var table = document.getElementById("?");
for (i=0; i < table.rows.length; i++)
{
for (j = table.rows[i].cells.length - 1; j >= 0; j--)
{
if (table.rows[i].cells[j].innerHTML == 'TextSecond')
table.rows[i].cells[j].removeNode(true);
}
}
You can use nth-child... :
$('table :nth-child(2)').remove();
JSFIDDLE