How to append custom td to table generated from two-dimensional array? - javascript

I am working on the following code. I am trying to work out why I am not able to append all <td> in one row? What I want to do is appending a custom <td> at begging of each rows in a way to look like:
<tr>
<td>Defult TD</td>
<td>52</td>
<td>16</td>
<td>140</td>
<tr>
<tr>
<td>Defult TD</td>
<td>54</td>
<td>16</td>
<td>145</td>
<tr>
but what I am getting is
<tr>
<td>Defult TD</td>
</tr>
<tr>
<td>52</td>
<td>16</td>
<td>140</td>
<tr>
<tr>
<td>Defult TD</td>
</tr>
<tr>
<td>54</td>
<td>16</td>
<td>145</td>
<tr>
var sizes= [
[52, 16, 140],
[54, 16, 145]
];
var table = $('#size-rows');
var row, cell;
for (var i = 0; i < sizes.length; i++) {
row = $('<tr />');
table.append(row);
cell = $('<td>Default TD</td>')
for (var j = 0; j < sizes[i].length; j++) {
cell.append('<td>' + sizes[i][j] + '</td>');
row.append(cell);
}
}
td{
border:1px solid #ddd;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tbody id="size-rows"> </tbody>
</table>

You're appending to the <td>, instead, append the cell and the next <td>'s to the row:
var sizes = [
[52, 16, 140],
[54, 16, 145]
];
var table = $('#size-rows');
var row, cell;
for (var i = 0; i < sizes.length; i++) {
row = $('<tr />');
table.append(row);
cell = $('<td>Default TD</td>');
row.append(cell);
for (var j = 0; j < sizes[i].length; j++) {
row.append('<td>' + sizes[i][j] + '</td>');
}
}
td {
border: 1px solid #ddd;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tbody id="size-rows"> </tbody>
</table>

here is a solution using the map function.
var sizes= [
[52, 16, 140],
[54, 16, 145]
];
$('#size-rows').append(
sizes.map(
x => `<tr>
<td>Default TD</td>${x.map(y => `<td>${y}</td>`)}
</tr>`
)
);
td{
border:1px solid #ddd;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tbody id="size-rows"> </tbody>
</table>

Related

loop over table to set the background css

My HTML table has some classes and table tag is used
Want to retain the classes as is, but all my table and tr , th or td are using td bgcolor which is an old technique.
I want to loop over the table and find if that bgcolor is defined, use the same color and convert it to a css based background color so i can print it in IE
function setBackground() {
var table = document.getElementById("table1");
//i found this in a previous stack overflow answer and tried it
for (var i = 0, row; row = table.rows[i]; i++) {
for (var j = 0, col; col = row.cells[j]; j++) {
//this is for debugging purposes... I can't even get this to work
alert(table.rows[i].cells[j]);
table.rows[i].cells[j].style.background = "orange"; //just an example
}
}
}
because IE is not able to print the background lines and colors for some reason using the webkit property
I cleaned up the for loops a little. You can read the attribute with getAttribute and set the style.
var table = document.getElementById("table1");
for (var i = 0; i < table.rows.length; i++) {
var row = table.rows[i]
for (var j = 0; j < row.cells.length; j++) {
var cell = row.cells[j]
var bgc = cell.getAttribute('bgcolor')
if (bgc) {
cell.style.background = bgc
}
}
}
td {
width: 30px; height: 30px;
}
<table id="table1">
<tr>
<td bgcolor="red"></td>
<td></td>
<td bgcolor="blue"></td>
</tr>
<tr>
<td></td>
<td bgcolor="green"></td>
<td></td>
</tr>
<tr>
<td bgcolor="yellow"></td>
<td></td>
<td></td>
</tr>
<tr>
<td bgcolor="silver"></td>
<td></td>
<td></td>
</tr>
</table>
You can just do it with one loop with getElementsByTagName
var tds = document.getElementById("table1").getElementsByTagName("td");
for (var i = 0; i < tds.length; i++) {
var cell = tds[i]
var bgc = cell.getAttribute('bgcolor')
if (bgc) {
cell.style.background = bgc
}
}
td {
width: 30px; height: 30px;
}
<table id="table1">
<tr>
<td bgcolor="red"></td>
<td></td>
<td bgcolor="blue"></td>
</tr>
<tr>
<td></td>
<td bgcolor="green"></td>
<td></td>
</tr>
<tr>
<td bgcolor="yellow"></td>
<td></td>
<td></td>
</tr>
<tr>
<td bgcolor="silver"></td>
<td></td>
<td></td>
</tr>
</table>
Get the color if found and then do with it whatever needed...
function setBackgroundColor(colorValue) {
const table = document.getElementById("table1");
const rows = table.children[0].rows
for (let i = 0; i < rows.length; i++) {
const tds = rows[i].children;
for (let j = 0; j < tds.length; j++) {
if (tds[j].bgColor === colorValue) {
console.log('Color found, do action')
}
}
}
}
setBackgroundColor('red')
<table id="table1">
<tr>
<th>Month</th>
<th>Savings</th>
</tr>
<tr>
<td bgcolor="red">January</td>
<td bgcolor="green">$100</td>
</tr>
</table>
You can do this:
var cells = $("#targetTable td");
for(i in cells){
color = $(cells[i]).attr('bgcolor');
console.log(color);
$(cells[i]).css({background: color});
}
as Taplar mentioned in the comment :
Use document.querySelectorAll('td[bgcolor]') to get the td that have bgcolor, loop through them and set the background to that color :
document.querySelectorAll('td[bgcolor]').forEach(e => {
const bgColor = e.getAttribute('bgcolor');
e.removeAttribute('bgcolor'); // optional, if you want to remove the attribute
e.style.background = bgColor;
})
<table id="table1">
<thead>
<th>A</th>
<th>B</th>
<th>C</th>
</thead>
<tbody>
<tr>
<td bgcolor="red">1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>4</td>
<td bgcolor="green">5</td>
<td>6</td>
</tr>
<tr>
<td>7</td>
<td>8</td>
<td bgcolor="blue">9</td>
</tr>
</tbody>
</table>

Convert javascript alertbox to show it on a html textbox

I want to show my xy coordinates in html td cell using JavaScript but instead of showing an alert, I want it to be shown in an html textbox
var table = document.getElementsByTagName("table")[0];
var cells = table.getElementsByTagName("td"); //
for(var i = 1; i < cells.length; i++){
var cell = cells[i];
cell.onclick = function(){
var cellIndex = this.cellIndex + 1;
var rowIndex = this.parentNode.rowIndex + 1;
alert("X: " + cellIndex + " / Y: " + rowIndex );
}
}
I have loop over the td elements and bind click event.So each time you click on td you will see cellIndex and rowIndex.Check my code and let me know if it satisfies you.
var cells = document.querySelectorAll("table td");
for(var i = 0; i < cells.length; i++){
cells[i].addEventListener('click',showCoordinates);
}
function showCoordinates(){
var cellIndex = this.cellIndex + 1;
var rowIndex = this.parentNode.rowIndex + 1;
this.innerHTML = "X:"+cellIndex +" Y:"+rowIndex;
}
table td{ padding:10px; }
<table border="1">
<tr>
<td>TD</td>
<td>TD</td>
<td>TD</td>
</tr>
<tr>
<td>TD</td>
<td>TD</td>
<td>TD</td>
</tr>
</table>
There are different ways to achieve what I think you want. Feel free to update you question to reflect your will. Adding your HTML as inquired in comment, would be useful.
Lets assume that your table doesn't use rowspan or colspan. Something like this:
<table border="1">
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</table>
The basic way with two loops:
// Lets get all your rows
var rows = document.querySelectorAll("table tr");
// for each row...
for (var j = 0; j < rows.length; j++) {
var row = rows[j];
// ... we will find all this rows' cells.
var cells = row.querySelectorAll("td");
// for each cell...
for (var i = 0; i < cells.length; i++) {
var cell = cells[i];
// ... we will set its textContent to its coordinate in the table
cell.textContent = "X: " + (i + 1) + " / Y: " + (j + 1);
}
}
<table border="1">
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</table>
Another solution if you know beforehand the number of columns:
var colsCount = document.querySelectorAll("table tr:nth-child(1) td").length;
var cells = document.querySelectorAll("table td");
for (var i = 0; i < cells.length; i++) {
const y = i / colsCount | 0;
const x = i % colsCount;
cells[i].textContent = `X: ${x + 1} / Y: ${y + 1}`;
}
<table border="1">
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</table>

Delete a column

I have a table and I want to delete the column of a table. I have written a code to delete a particular column.
function deleteColumn(index) {
var total_row = document.getElementById("testBenchTable").rows;
for (var i=0; i<total_row.length; i++) {
if (total_row[i].cells.length > 1) {
total_row[i].deleteCell(index);
}
}
Now What should do so that I could select a particular column(header) and click on delete so that that particular column gets deleted?
You can refer this link for delete column http://www.mredkj.com/tutorials/tableaddcolumn.html
function deleteColumn(tblId)
{
var allRows = document.getElementById(tblId).rows;
for (var i=0; i<allRows.length; i++) {
if (allRows[i].cells.length > 1) {
allRows[i].deleteCell(-1);
}
}
}
// 2006-08-21 - Created
// 2006-11-05 - Modified - head and body
function addColumn(tblId)
{
var tblHeadObj = document.getElementById(tblId).tHead;
for (var h=0; h<tblHeadObj.rows.length; h++) {
var newTH = document.createElement('th');
tblHeadObj.rows[h].appendChild(newTH);
newTH.innerHTML = '[th] row:' + h + ', cell: ' + (tblHeadObj.rows[h].cells.length - 1)
}
var tblBodyObj = document.getElementById(tblId).tBodies[0];
for (var i=0; i<tblBodyObj.rows.length; i++) {
var newCell = tblBodyObj.rows[i].insertCell(-1);
newCell.innerHTML = '[td] row:' + i + ', cell: ' + (tblBodyObj.rows[i].cells.length - 1)
}
}
function deleteColumn(tblId)
{
var allRows = document.getElementById(tblId).rows;
for (var i=0; i<allRows.length; i++) {
if (allRows[i].cells.length > 1) {
allRows[i].deleteCell(-1);
}
}
}
<form>
<p>
<input type="button" value="add column" onclick="addColumn('tblSample')" />
<input type="button" value="delete column" onclick="deleteColumn('tblSample')" />
</p>
<table id="tblSample" border="1">
<thead>
<tr>
<th>[th] row:0, cell: 0</th>
<th>[th] row:0, cell: 1</th>
<th>[th] row:0, cell: 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>[td] row:0, cell: 0</td>
<td>[td] row:0, cell: 1</td>
<td>[td] row:0, cell: 2</td>
</tr>
<tr>
<td>[td] row:1, cell: 0</td>
<td>[td] row:1, cell: 1</td>
<td>[td] row:1, cell: 2</td>
</tr>
<tr>
<td>[td] row:2, cell: 0</td>
<td>[td] row:2, cell: 1</td>
<td>[td] row:2, cell: 2</td>
</tr>
</tbody>
</table>
</form>
To delete a particular column, you can use the cellIndex of the element (see: TableData cellIndex Property)
function deleteColumn(element) {
var idx = element.cellIndex;
var total_row = document.getElementById("testBenchTable").rows;
for (var i=0; i<total_row.length; i++) {
if (total_row[i].cells.length > 1) {
total_row[i].deleteCell(idx);
}
}
}
<table id="testBenchTable">
<tr>
<th onclick="deleteColumn(this)">Month</th>
<th onclick="deleteColumn(this)">Savings</th>
</tr>
<tr>
<td>January</td>
<td>$100</td>
</tr>
<tr>
<td>February</td>
<td>$80</td>
</tr>
</table>
function deleteColumn(event) {
var index = event.target.cellIndex;
var total_row = document.getElementById("testBenchTable").rows;
for (var i=0; i<total_row.length; i++) {
if (total_row[i].cells.length > 1) {
total_row[i].deleteCell(index);
}
}
}
<table style="width:100%" id="testBenchTable">
<tr>
<th onclick="deleteColumn(event)">Firstname</th>
<th onclick="deleteColumn(event)">Lastname</th>
<th onclick="deleteColumn(event)">Age</th>
</tr>
<tr>
<td>Jill</td>
<td>Smith</td>
<td>50</td>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td>94</td>
</tr>
</table>

Create a row using group off arrays

Lets say we have an Array that looks like this
(example)
Array1 = [Data_A,Data_B];
Array2 = [Data_1,Data_2,Data_3];
and I have a table that looks like this
How can I achieve this?
For now I can retreive the data in row order using for loop and this is my code
for (i = 0; i < Array1 .length; i++) {
for (x in Array1 [i]) {
console.log(data from array);
}
}
My target here is for every array is I need to make it as a row for every col. for example Array1 is fol Col1 and also note that my arrays are fixed for each col. col3 and 4 are for ex. only
Because the data in table columns don't usually change unlike they do in rows, I highly discourage managing table data by columns. It is best to do it by rows.
What I mean is to have Row1 = [Data_A, Data_1]; and Row2 = [Data_B, Data_2]; and so on, rather than how you had it set up.
function CreateRow(data) {
var tr = "<tr>"
for (var i = 0; i < data.length; i++) {
tr += "<td>" + data[i] + "</td>";
}
tr += "</tr>"
$('#table').append(tr);
}
function EditRow(data, rowIdx) {
var tr = $('#table').children().eq(0);
for (var i = 0; i < data.length; i++) {
tr.children().eq(i).text(data[i]);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>Col1</th>
<th>Col2</th>
<th>Col3</th>
<th>Col4</th>
</tr>
</thead>
<tbody id="table">
<tr>
<td>Data 0</td>
<td>Data 1</td>
<td>Data 2</td>
<td>Data 3</td>
</tr>
</tbody>
</table>
<button type="button" onclick="CreateRow(['A','B','C','D'])">Create Row</button>
<button type="button" onclick="EditRow(['EditedData1','EditedData2', 'EditedData3', 'EditedData4'], 0)">Edit First Row</button>
(Pure Javascript snippet for those who are interested)
function CreateRow(data) {
var table = document.getElementById("table");
var tr = document.createElement("tr");
for (var i = 0; i < data.length; i++) {
var td = document.createElement("td");
td.appendChild(document.createTextNode(data[i]));
tr.appendChild(td);
}
table.appendChild(tr);
}
function EditRow(data, rowIdx) {
var tr = document.getElementById("table").getElementsByTagName("tr")[rowIdx];
for (var i = 0; i < data.length; i++) {
tr.getElementsByTagName("td")[i].innerHTML = data[i];
}
}
<table>
<thead>
<tr>
<th>Col1</th>
<th>Col2</th>
<th>Col3</th>
<th>Col4</th>
</tr>
</thead>
<tbody id="table">
<tr>
<td>Data 0</td>
<td>Data 1</td>
<td>Data 2</td>
<td>Data 3</td>
</tr>
</tbody>
</table>
<button type="button" onclick="CreateRow(['A','B','C','D'])">Create Row</button>
<button type="button" onclick="EditRow(['EditedData1','EditedData2', 'EditedData3', 'EditedData4'], 0)">Edit First Row</button>

Clear previously selected table row, when the next row is selected

I have the following code to create a left and right border when a row is selected in a table. I want the borders to only appear when the row is currently selected, and to disappear when it is not selected.
I attach a mock up:
function addRowHandlers() {
var table = document.getElementById("example");
var rows = table.getElementsByTagName("tr");
for (i = 0; i < rows.length; i++) {
var currentRow = table.rows[i];
var createClickHandler =
function(row) {
return function() {
var cell = row.getElementsByTagName("td")[0];
row.getElementsByTagName("td")[0].style.backgroundColor = "white";
row.firstElementChild.style.borderLeft = "black solid 2px";
row.lastElementChild.style.borderRight = "black solid 2px";
var id = cell.innerHTML;
alert("id:" + id);
};
};
currentRow.onclick = createClickHandler(currentRow);
}
}
window.onload = addRowHandlers();
tr td:first-child { border-left:2px solid transparent;}
tr td:last-child { border-right:2px solid transparent;}
<div>
<table id="example">
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Age</th>
</tr>
<tr>
<td>Jill</td>
<td>Smith</td>
<td>50</td>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td>94</td>
</tr>
<tr>
<td>John</td>
<td>Doe</td>
<td>80</td>
</tr>
</table>
</div>
Use a class for the current selection styles ( I named it highlight) then on click remove this class from all rows with this
for (var i = 0; i < table.rows.length; i++) {
table.rows[i].classList.remove('highlight');
}
and then add it to the current row with row.className += "highlight"; check it out:
function addRowHandlers() {
var table = document.getElementById("example");
var rows = table.getElementsByTagName("tr");
for (i = 0; i < rows.length; i++) {
var currentRow = table.rows[i];
var createClickHandler =
function(row) {
return function() {
for (var i = 0; i < table.rows.length; i++) {
table.rows[i].classList.remove('highlight');
}
var cell = row.getElementsByTagName("td")[0];
row.getElementsByTagName("td")[0].style.backgroundColor = "white";
row.className += "highlight";
var id = cell.innerHTML;
};
};
currentRow.onclick = createClickHandler(currentRow);
}
}
window.onload = addRowHandlers();
tr:not(.highlight) td:first-child { border-left:2px solid transparent;}
tr:not(.highlight) td:last-child { border-right:2px solid transparent;}
tr.highlight td:first-child { border-left:2px solid black;}
tr.highlight td:last-child { border-right:2px solid black;}
<div>
<table id="example">
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Age</th>
</tr>
<tr>
<td>Jill</td>
<td>Smith</td>
<td>50</td>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td>94</td>
</tr>
<tr>
<td>John</td>
<td>Doe</td>
<td>80</td>
</tr>
</table>
</div>
Here I tried a differenct approach with less code.
If you inspect from console, you'll see the change: click event adds the class to that row, and resets other rows' classes.
var mytable = document.getElementById("example");
var myrows = mytable.rows;
function giveStyle(el) {
Array.from(myrows).map(e => e.className = "");
el.className = "someclass";
}
.someclass {
/*something here */
}
<table id="example">
<tr>
<td>First</td>
<td>Last</td>
<td>Age</td>
</tr>
<tr onclick="giveStyle(this)">
<td>John</td>
<td>Doe</td>
<td>50</td>
</tr>
<tr onclick="giveStyle(this)">
<td>Alice</td>
<td>Wilsom</td>
<td>40</td>
</tr>
<tr onclick="giveStyle(this)">
<td>Otto</td>
<td>Weininger</td>
<td>25</td>
</tr>
</table>
Please use this function also :
function resetRowHandlers() {
var table = document.getElementById("example");
var rows = table.getElementsByTagName("tr");
for (i = 0; i < rows.length; i++) {
var row = table.rows[i];
row.getElementsByTagName("td")[0].style.backgroundColor = "none";
row.firstElementChild.style.borderLeft = "transparent solid 2px";
row.lastElementChild.style.borderRight = "transparent solid 2px";
}
}
Also call this function on click of row i.e. createClickHandler

Categories

Resources