Loop Through Table and add values in JavaScript - javascript

Hello I am trying to loop through a table I have in html and want to add next to the cell depending on the value of the cell. For example the following table I have:
<div>
<h1>My Table</h1>
<table id = "table" class = "searchable sortable">
<tr class = "header">
<th>A</th>
<th>B</th>
<th>C</th>
</tr>
<tr>
<td> Up</td>
<td>Down</td>
<td> Up </td>
</tr>
<tr>
<td>Up</td>
<td>Up</td>
<td>Down</td>
</tr>
</table>
<div>
if the value of the cell is equal to up I would like to add a image in the cell of an up arrow,
if down add a image of a down arrow.

You can do it by
var table = document.getElementById('table');
for (var r = 0, n = table.rows.length; r < n; r++) {
for (var c = 0, m = table.rows[r].cells.length; c < m; c++) {
var image = document.createElement("img");
if(table.rows[r].cells[c].innerHTML === "Up"){
image.src = "/your_image_path_for_up";
} else {
image.src = "/your_image_path_for_down";
}
var newCell = row.insertCell(c+1);
newCell.appendChild(image);
}
}
This will append a new cell with an image to the right of your cell with "Up" or "Down".

Below is the script, which will find all of the cells, loop through them and add appropriate image
<script>
var cells = document.querySelectorAll('td');
for (var i = 0; i < cells.length; i++) {
var cell = cells[i];
var cellContent = cell.textContent.toLowerCase().trim();
var img = document.createElement('img')
if (cellContent === 'up') {
img.src = 'src_to_up_arrow_image';
} else if (cellContent === 'down') {
img.src = 'src_to_down_arrow_image';
};
cell.appendChild(img);
}
</script>

Related

How can I break row from specific <td> to next row?

I need to break table headings well as table rows after 4 . Here I'm generating table dynamically from JSON string through jQuery. The table can contain maximum 16 columns, so I need to break it in 4 rows. The output should look like,
<table border=1>
<thead>
<tr>
<th>COLUMN1</th>
<th>COLUMN2</th>
<th>COLUMN3</th>
<th>COLUMN4</th>
</tr>
<tr>
<td>val1</td>
<td>val2</td>
<td>val3</td>
<td>val4</td>
</tr>
</thead>
<tbody>
<tr>
<th>COLUMN5</th>
<th>COLUMN6</th>
<th>COLUMN7</th>
<th>COLUMN8</th>
</tr>
<tr>
<td>val5</td>
<td>val6</td>
<td>val7</td>
<td>val8</td>
</tr>
</tbody>
</table>
I'm using below code to generate HTML Table from JSON,
var txnJson = JSON.parse('<%=jsonObj1%>');
var tableName;
var colspan = 0;
var colHeader = [];
var rowValue = [];
for (var key in txnJson) {
tableName = key;
console.log(key);
for (var secondKey in txnJson[key]) {
console.log(secondKey + ' : ' + txnJson[key][secondKey]);
for (var thirdkey in txnJson[key][secondKey]) {
colHeader.push(thirdkey);
rowValue.push(txnJson[key][secondKey][thirdkey]);
colspan = colspan +1;
console.log(thirdkey + ' : ' + txnJson[key][secondKey][thirdkey]);
}
}
}
// CREATE DYNAMIC TABLE.
var table = document.createElement("table");
var tr = table.insertRow(-1);
for (var i = 0; i < colHeader.length; i++) {
var th = document.createElement("th"); // TABLE HEADER.
th.setAttribute("class", "RptHeader");
th.innerHTML = colHeader[i];
tr.appendChild(th);
}
tr = table.insertRow(-1);
for (var j = 0; j < rowValue.length; j++) {
var tabCell = tr.insertCell(-1);
tabCell.innerHTML = rowValue[j];
}
$('#Div<%=i%>').append(table);
I have tried using $('').html($('#Test1 td:gt(4)')).appendTo('#Test1'); but it only breaks single row. I need to iterate it after every four td.
How can I do it?
I'm able to achieve the same using below code,
`var inp = document.createElement("input");
inp.setAttribute("type","hidden");
inp.setAttribute("id","colCnt<%=i%>");
inp.setAttribute("value",colLength);
$(function () {
var colCnt = $("#colCnt<%=i%>").val();
var thLen = 3;
var tdLen = 4;
$('<tr>').html($('#Tab<%=i%> th:gt('+thLen+')')).appendTo('#Tab<%=i%>');
$('<tr>').html($('#Tab<%=i%> td:gt('+tdLen+')')).appendTo('#Tab<%=i%>');
for (var k = 0; k < colCnt; k++) {
thLen = thLen + 4;
tdLen = tdLen + 4;
$('<tr>').html($('#Tab<%=i%> th:gt('+(thLen)+')')).appendTo('#Tab<%=i%>');
$('<tr>').html($('#Tab<%=i%> td:gt('+(tdLen)+')')).appendTo('#Tab<%=i%>');
}
});
Hope, this might help someone.

How can I adapt this code to make the rows selectable?

How can I adapt this code to make the rows which have been created by the function selectable. I will then use this in as a part of a form to manipulate the data in the specified row.
function staffData() {
if (firstTimeS) {
firstTimeS = false;
// Select the Table
var tbl = document.getElementById('staffInnerTable');
var th = document.getElementById('tableHead_S');
var headerText = ["ID", "Staff Name", "Role"];
// Set number of rows
var rows = 10;
// Set number of columns
var columns = headerText.length;
// create table header
for (var h = 0; h < columns; h++) {
var td = document.createElement("td");
td.innerText = headerText[h];
th.appendChild(td);
}
// create table data
for (var r = 0; r < rows; r++) {
var cellText = ["UNDEFINED", "UNDEFINED", "UNDEFINED"];
// generate ID
x = getRandomNumber(1000, 1);
cellText[0] = x;
// generate Status
x = generateName();
cellText[1] = x;
// generate Role
x = getRole();
cellText[2] = x;
var tr = document.getElementById("s_row" + r);
for (var c = 0; c < columns; c++)
{
var td = document.createElement("td");
td.innerText = cellText[c];
tr.appendChild(td);
}
}
}
}
EDIT - HTML. Tr already defined in html. Would it be possible to somehow put an onclick on the table rows?
<table style="width: 100%; color:white;" id="staffInnerTable">
<tr id="tableHead_S">
</tr>
<tr id="s_row0"></tr>
<tr id="s_row1"></tr>
<tr id="s_row2"></tr>
<tr id="s_row3"></tr>
<tr id="s_row4"></tr>
<tr id="s_row5"></tr>
<tr id="s_row6"></tr>
<tr id="s_row7"></tr>
<tr id="s_row8"></tr>
<tr id="s_row9"></tr>
</table>
If you do this:
var tr = document.getElementById("s_row" + r);
tr.onclick = function(event) {
alert('Clicked: ' + event.target.parentNode.id)
}
...you'll see that a click is detected that tells you which row was clicked on. Hopefully that's enough to get you started on whatever you wanted to do.

Calculate a new AveValue in TableCell while adding new Columns using JavaScript-not JQuery

I have a <th> header row with a stated class, and one fixed row with a stated class. Both are contenteditable. I'm adding new rows and new columns. I want to calculate the AverageValue in the final cell. I have tried the code on a fixed number of rows and it works, but when I try it this way it is only taking in the number of columns, not the DATA inserted. It is also not recognizing the row DATA. I'm clearly missing a function?!
I'm at the stage where I need an extra pair of eyes.
JavaScript:
func = function() {
var table = document.getElementById("mytable");
var rows = table.rows;
for (var j = 1; j < rows.length; j++) {
var total = 0;
var cells = rows[j].cells;
for (var i = 2; i < (cells.length - 1); i++) {
var a = document.getElementById("mytable").rows[j].cells[i].innerHTML;
a = parseInt(a);
if (!isNaN(a)) {
total = total + a;
}
}
total = total / (cells.length - 3);
total = Math.round(total);
if (total < 40) {
document.getElementById("mytable").rows[j].cells[cells.length - 1].style.backgroundColor = "red";
document.getElementById("mytable").rows[j].cells[cells.length - 1].style.color = "white";
}
document.getElementById("mytable").rows[j].cells[cells.length - 1].innerHTML = total + "%";
}
}
addRow = function() {
var table = document.getElementById('mytable'); // table reference
var row = table.insertRow(table.rows.length); // append table row
// insert table cells to the new row
for (i = 0; i < table.rows[0].cells.length; i++) {
createCell(row.insertCell(i), "-");
}
}
createCell = function(cell, text, style) {
var div = document.createElement('div');
txt = document.createTextNode(text);
div.appendChild(txt); // append text node to the DIV
div.setAttribute("class", style); // set DIV class attribute
div.setAttribute("className", style);
div.setAttribute("contenteditable", true);
div.setAttribute('placeholder', '' - '');
cell.appendChild(div); // append DIV to the table cell
}
createCellCol = function(cell, text, style) {
var div = document.createElement('div');
txt = document.createTextNode(text);
div.appendChild(txt); // append text node to the DIV
div.setAttribute("class", style); // set DIV class attribute
div.setAttribute("className", style);
div.setAttribute("contenteditable", true);
div.setAttribute("placeholder", "-");
cell.appendChild(div); // append DIV to the table cell
}
addColumn = function() {
var table = document.getElementById("mytable"); // table reference
var rowNums = table.rows.length;
for (i = 0; i < rowNums; i++) {
if (i == 0) {
createCell(table.rows[i].insertCell(table.rows[i].cells.length - 1), "-");
} else {
createCellCol(table.rows[i].insertCell(table.rows[i].cells.length - 1), "-");
}
}
}
HTML:
<table class="tg" id="mytable">
<tr>
<th class="tg-s6z2" contenteditable="true">Student Name</th>
<th class="tg-s6z2" contenteditable="true">Student ID</th>
<th class="tg-s6z2" contenteditable="true">Assignment 1</th>
<th class="tg-s6z2" contenteditable="true">Final Grade</th>
</tr>
<tr>
<td class="tg-031e" contenteditable="true">Student1</td>
<td class="tg-031e" contenteditable="true">StudentNo</td>
<td class="tg-0ord" contenteditable="true"></td>
<td class="tg-0ord" contenteditable="true"></td>
</tr>
</table>
<button id="btnFinalGrade" class="btn btn-action" onClick="func();">Final Grade</button>
<button id="btnaddRow" class="btn btn-action" onclick="addRow();">AddRow</button>
<button id="btnaddColumn" class="btn btn-action" onclick="addColumn();">AddColumn</button>
You were adding a div to td element which was throwing error while executing this line document.getElementById("mytable").rows[j].cells[i].innerHTML
which returns a div element not the text you entered!
No need to add a div, Here is the updated code,
func = function () {
var table = document.getElementById("mytable");
var rows = table.rows;
for (var j = 1; j < rows.length; j++) {
var total = 0;
var cells = rows[j].cells;
for (var i = 2; i < (cells.length - 1); i++) {
var a = document.getElementById("mytable").rows[j].cells[i].innerHTML;
a = parseInt(a);
if (!isNaN(a)) {
total = total + a;
}
}
total = total / (cells.length - 3);
total = Math.round(total);
if (total < 40) {
document.getElementById("mytable").rows[j].cells[cells.length - 1].style.backgroundColor = "red";
document.getElementById("mytable").rows[j].cells[cells.length - 1].style.color = "white";
}
document.getElementById("mytable").rows[j].cells[cells.length - 1].innerHTML = total + "%";
}
}
addRow = function () {
var table = document.getElementById('mytable'); // table reference
var row = table.insertRow(table.rows.length); // append table row
// insert table cells to the new row
for (i = 0; i < table.rows[0].cells.length; i++) {
createCell(row.insertCell(i), "-","tg-031e");
}
}
createCell = function (cell, text, style) {
var div = document.createElement('td');
txt = document.createTextNode(text);
cell.appendChild(txt); // append text node to the DIV
cell.setAttribute("class", style); // set DIV class attribute
cell.setAttribute("className", style);
cell.setAttribute("contenteditable", true);
cell.setAttribute('placeholder', '' - '');
//cell.appendChild(div); // append DIV to the table cell
}
createCellCol = function (cell, text, style) {
var div = document.createElement('td');
txt = document.createTextNode(text);
cell.appendChild(txt); // append text node to the DIV
cell.setAttribute("class", style); // set DIV class attribute
cell.setAttribute("className", style);
cell.setAttribute("contenteditable", true);
cell.setAttribute("placeholder", "-");
//cell.appendChild(div); // append DIV to the table cell
}
addColumn = function () {
var table = document.getElementById("mytable"); // table reference
var rowNums = table.rows.length;
for (i = 0; i < rowNums; i++) {
if (i == 0) {
createCell(table.rows[i].insertCell(table.rows[i].cells.length - 1), "-","tg-031e");
} else {
createCellCol(table.rows[i].insertCell(table.rows[i].cells.length - 1), "-","tg-s6z2");
}
}
}

find the <td> column value of respective cell using any javascript library

<table border="1">
<tr>
<td rowspan="3">0</td>
<td>1</td>
<td rowspan="3">2</td>
<td>3</td>
</tr>
<tr>
<td>A</td>
<td>B</td>
</tr>
<tr>
<td>X</td>
<td>Y</td>
</tr>
</table>
I want to find the column number of td containing X using jQuery or some other JavaScript library.
For example column number of td containing A is 1 and B is 3.
Also we know that column number of td containing X is 1. But how can we get that pragmatically.
My case here is I need to merge data of all the rows with first row. So while moving through each td I need to know from which column does it belong so that I can merge it to the td of first row of that column.
Please help me if there is any other approach to solve my problem.
Here is the Fiddle.
It gets the index and looks for rowspans and calculates the visible index.
function getColumnNumber(text) {
var $table = $("table").eq(0);
$("td:contains(" + text + ")").css("color", "red");
var $td = $("td:contains(" + text + ")"),
$tr = $td.parent(),
tdPosition = $td.index(),
trPosition = $tr.index(),
position = parseInt(tdPosition);
for (i = 0; i < trPosition; i++) {
for (j = 0; j <= tdPosition; j++) {
var rowSpan = parseInt($table.find('tr').eq(i).find('td').eq(j).attr("rowspan"));
if (typeof rowSpan !== "number") {
rowSpan = 0;
}
if (rowSpan > trPosition) {
position++;
tdPosition++;
}
}
}
console.log(text + " pos: " + position);
return position;
};
getColumnNumber('A');
getColumnNumber('B');
getColumnNumber('1');
getColumnNumber('Y');
This approach is basically storing your table data into an array, and intended if you ever want to expand or modify the structure of your table rowspan. (This does not support colspan)
$(function() {
var tableArr = [],
totalRow = $('table tr').length,
totalCol = 0;
$('table tr').each(function() {
var colLength = $(this).children('td').length;
totalCol = colLength > totalCol ? colLength : totalCol;
});
for (var r = 0; r < totalRow; r++) {
var row = [];
for (var c = 0; c < totalCol; c++) {
row.push(null);
}
tableArr.push(row);
}
$('td').each(function() {
var rowspan = $(this).attr('rowspan');
var rowIndex = $(this).parent('tr').index();
var colIndex = $(this).index();
var text = $(this).html();
if (rowspan && rowspan > 0) {
for (var i = 0; i < rowspan; i++) {
tableArr[i][colIndex] = text;
}
} else {
var lastNull = tableArr[rowIndex].indexOf(null);
tableArr[rowIndex][lastNull] = text;
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table border="1">
<tr>
<td rowspan="3">0</td>
<td>1</td>
<td rowspan="3">2</td>
<td>3</td>
</tr>
<tr>
<td>A</td>
<td>B</td>
</tr>
<tr>
<td>X</td>
<td>Y</td>
</tr>
</table>
Your table information is stored within tableArr, which you use to query if you want to get desired columnIndex based on the content of your td.
Usage
// This returns an array containing [row, column];
function getPositionByText(str) {
for (var r = 0; r < tableArr.length; r++) {
for (var c = 0; c < tableArr[r].length; c++) {
if (tableArr[r][c] === str) {
return [r, c]
}
}
}
return null;
}
var position = getPositionByText('X');
var xRow = position[0];
var xCol = position[1];

How to dynamically move <tr> into a newly created <div>?

I have the following HTML structure:
<table id="j_idt28:innerContent" class="innerContent">
<tbody>
<tr>
<tr>
<tr>
<tr>
.......
<tr>
<tr>
</tbody>
</table>
The tags are being populated with a parsed XML response.
I usually have 20 or so tr tags.
I want that after the 4th, 8th, 12, etc tag to create a and insert the 4 tags into it.
Here is my jquery so far:
var i = 1;
var j = 2;
var margin = 0;
var max = $('.innerContent tr').length;
for(i = 1; i<=max; i++)
{
var child1 = i - 3;
var child2 = i - 2;
var child3 = i - 1;
var hotel1 = $('.innerContent tr:nth-child('+child1+')');
var hotel2 = $('.innerContent tr:nth-child('+child2+')');
var hotel3 = $('.innerContent tr:nth-child('+child3+')');
var hotel4 = $('.innerContent tr:nth-child('+i+')');
if(i%4 == 0)
{
$('.innerContent tbody').prepend('<div class="line_wrapper"></div>');
$('.line_wrapper').append(hotel1,hotel2,hotel3,hotel4);
}
}
for(j =2; j<=max ;j++)
{
var hotel = $('.innerContent tr:nth-child('+j+')');
margin = margin + 280;
hotel.css('margin-left',margin+'px');
//$('.line_wrapper').append(hotel);
}
This just does not quite work as I would have expected. I want to add the divs in order for me to use bootstrap fluid layout.
You can do it using each:
$('#mytable tr').each(function (i) {
i%4?$(this).prev('div').append(this):$(this).wrap('<div/>');
});

Categories

Resources