Javascript insert row into table after row with certain id - javascript

I have a table where each row has its unique id. Say there are rows with id='id25' and id='id26'. I need to insert a new row after row with id='id25'. I am using Vanilla JS without jQuery.
I have tried this:
var refElement = document.getElementById('id'+id);
var newrow = document.createElement("tr");
if (refElement) {
refElement.insertBefore(newrow, refElement.nextSibling);
}
but it throws me an error saying
Failed to execute 'insertBefore' on 'Node'
The node before which the new node is to be inserted is not a child of this node.
I know how to insert rows into top or bottom of the table but now I have an id as a reference to a particular row.
Any suggestions would be welcome

You want to insert into the refElement's parent, not refElement itself:
refElement.parentNode.insertBefore(newrow, refElement.nextSibling);
// -------^^^^^^^^^^^
var id = 1;
var refElement = document.getElementById('id' + id);
var newrow = document.createElement("tr");
newrow.innerHTML = "<td>new row</td>";
if (refElement) {
refElement.parentNode.insertBefore(newrow, refElement.nextSibling);
}
<table>
<tbody>
<tr id="id1"><td>refElement</td></tr>
<tr><td>original next sibling</td></tr>
</tbody>
</table>
(And yes, for anyone wondering, it'll work even if the refElement is the last row in the table.)
Inserting five rows per comment:
var id = 1;
var refElement = document.getElementById('id' + id);
var n, newrow;
if (refElement) {
for (n = 0; n < 5; ++n) {
newrow = document.createElement("tr");
newrow.innerHTML = "<td>new row #" + n + "</td>";
refElement.parentNode.insertBefore(newrow, refElement.nextSibling);
}
}
<table>
<tbody>
<tr id="id1">
<td>refElement</td>
</tr>
<tr>
<td>original next sibling</td>
</tr>
</tbody>
</table>
Note the order in which those appeared. If you want them in 0 - 4 order instead:
var id = 1;
var refElement = document.getElementById('id' + id);
var n, newrow;
if (refElement) {
for (n = 0; n < 5; ++n) {
newrow = document.createElement("tr");
newrow.innerHTML = "<td>new row #" + n + "</td>";
refElement.parentNode.insertBefore(newrow, refElement.nextSibling);
refElement = refElement.nextSibling; // *** This is the change
}
}
<table>
<tbody>
<tr id="id1">
<td>refElement</td>
</tr>
<tr>
<td>original next sibling</td>
</tr>
</tbody>
</table>

function addRowAfter(rowId){
var refElement = document.getElementById('id'+id);
var newrow= document.createElement('tr');
refElement.parentNode.insertBefore(newrow, refElement.nextSibling );
return newRow;
}
Check this.

Related

Find values in table cells with Javascript

I'm using a dynamic table in HTML, but I need to verify the values are not repeated. I'm trying to do it with the value inside the cell rather than the text. These are the values and what I have so far:
var tBody = $("#tablaAplicaciones > TBODY")[0];
//Add Row.
var row = tBody.insertRow(-1);
//Add Name cell.
var cell = $(row.insertCell(-1));
cell.html(nameCountry);
cell.val(idCountry);
//Add Country cell.
cell = $(row.insertCell(-1));
cell.html(nameCompany);
cell.val(idCompany);
if (($('#tablaApp tr > td:contains(' + countryName + ') + td:contains(' + companyName + ')').length) == 1) {
.
.
.
}
Welcome to Stack Overflow. Consider the following code.
$(function() {
var idCountry = "9";
var nameCountry = "United States";
var idCompany = "9";
var nameCompany = "Genentech";
var tBody = $("#tablaAplicaciones > tbody");
//Create Row
var row = $("<tr>");
//Add Country cell to Row
$("<td>", {
class: "name-country"
})
.data("id", idCountry)
.html(nameCompany)
.appendTo(row);
//Add Company cell to Row
$("<td>", {
class: "name-company"
})
.data("id", idCompany)
.html(nameCompany)
.appendTo(row);
// Assume vales are not in the table
var found = -1;
$("tr", tBody).each(function(i, el) {
// Test each row, if value is found set test to tue
if ($(".name-country", el).text().trim() == nameCountry) {
found = i;
}
if ($(".name-company", el).text().trim() == nameCompany) {
found = i;
}
});
if (found == -1) {
// If test is false, append the row to table
row.appendTo(tBody);
console.log("Row Added", row);
} else {
console.log("Values already in Table, row: " + found);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="tablaAplicaciones">
<thead>
<tr>
<th>Country</th>
<th>Company</th>
</tr>
</thead>
<tbody>
<tr>
<td data-id="1" class="name-country">United States</td>
<td data-id="1" class="name-company">Apple Inc.</td>
</tbody>
</table>
Using .each(), you can iterate over each row and compare the values. A variable can be used as a flag to indicate if the needle was found in the haystack. If not found, you can append the row. Otherwise, do not add the row.
Hope that helps.

Creating HTML table based on values

I have an html table that I want to read from and create a new table underneath it from reading the first table. The first table looks like this:
ID | Value
100 | 3
200 | 2
400 | 7
100 | 4
and should output this
ID | Total
100 | 7
200 | 2
400 | 7
I'm having trouble creating the new rows after the first row and adding them based on ID, heres what I have so far
var id = document.getElementByID("total");
var td = document.createElement('td');
var eleName = document.getElementsByName('initValue');
var total = 0;
for (var i = 1; i < eleName.length; i++) {
total += parseInt(eleName[i].value);
}
td.textContent = total;
id.appendChild(td);
Right now its just adding all the values
The ID can only increase by 100 and can have more than just 100-400 and more entries. The inital table is made with php
original table html
<table>
<tr><th>ID</th><th>Value</th></tr>
<tr><td name="itin" id="itin">100</td><td id="initValue" name="initValue">3</td></tr>
<tr><td name="itin" id="itin">200</td><td id="initValue" name="initValue">2</td></tr>
<tr><td name="itin" id="itin">400</td><td id="initValue"name="initValue">7</td></tr>
<tr><td name="itin" id="itin">100</td><td id="initValue" name="initValue">4</td></tr>
</table>
As a few people have said in the comments an element's ID, <el id="something">, must be unique and there cannot be any duplicates of it on the page. If you want to "group" similar elements use a class.
For solving your problem, since the value of your ID is is a direct sibling we only need one selector to get the ID and Value:
const itin = document.querySelectorAll('[name="itin"]');
With this we can loop over every ID element, name="itin", and get the value with el.nextElementSibling.textContent. We're going to be keeping track of our IDs and Values in an object since javascript doesn't have key/value pair arrays: let values = {}.
We use .nextElementSibling to ignore white spaces and only get the next element.
We check if values already has a record of our ID with hasOwnProperty, if it does, we add the values together, if not we create a property in values with our ID and give it a value:
if (values.hasOwnProperty(inner)) {
values[inner] = values[inner] += parseInt(next);
} else {
values[inner] = parseInt(next);
}
Next we create a second loop to iterate over all properties in values and build our new table with that and the rest is pretty straight forward.
The two loops could likely be combined into one with a bit more logic to search for matching IDs.
const itin = document.querySelectorAll('[name="itin"]');
let values = {};
itin.forEach(item => {
const inner = item.textContent;
let next = null;
/* For direct sibling use this */
//const next = item.nextElementSibling.textContent;
/* For an unknown sibling use this */
for ( let a = 0; a < item.parentElement.children.length; a++ ) {
const n = item.parentElement.children[a];
if ( n.getAttribute('name') === 'initValue') {
next = n;
}
}
next = next.textContent;
/****/
if (values.hasOwnProperty(inner)) {
values[inner] = values[inner] += parseInt(next);
} else {
values[inner] = parseInt(next);
}
});
const table_two = document.querySelector('.table-two tbody');
for (let prop in values) {
const val = values[prop];
let tr = document.createElement('tr');
let td1 = document.createElement('td');
let td2 = document.createElement('td');
td1.innerHTML = prop;
td2.innerHTML = val;
tr.appendChild(td1);
tr.appendChild(td2);
table_two.appendChild(tr);
}
<table>
<tr>
<th>ID</th>
<th>Value</th>
</tr>
<tr>
<td name="itin">100</td>
<td name="initValue">3</td>
</tr>
<tr>
<td name="itin">200</td>
<td name="initValue">2</td>
</tr>
<tr>
<td name="itin">400</td>
<td name="initValue">7</td>
</tr>
<tr>
<td name="itin">100</td>
<td name="initValue">4</td>
</tr>
</table>
<table class="table-two">
<thead>
<tr>
<th>ID</th>
<th>Value</th>
</tr>
</thead>
<tbody></tbody>
</table>
An entirely javascript solution based on what you have provided is available on this jsfiddle
var tds = document.getElementsByName("itin");
var tdDict = {};
var keys = [];
for(var i=0;i<tds.length;i++){
var tdId = tds[i];
var tdVal = tds[i].nextSibling;
if(tdId.textContent in tdDict){
var curTotal = tdDict[tdId.textContent];
var newTotal = curTotal + parseInt(tdVal.textContent);
tdDict[tdId.textContent] = newTotal;
}
else{
tdDict[tdId.textContent] = parseInt(tdVal.textContent);
keys.push(tdId.textContent);
}
}
var totalDiv = document.getElementById("totals");
var totalTable = document.createElement("table");
totalDiv.append(totalTable);
var hrow = document.createElement("tr");
var idHeader = document.createElement("th");
idHeader.textContent = "ID";
var totalHeader = document.createElement("th");
totalHeader.textContent = "Total";
totalTable.append(hrow);
hrow.append(idHeader);
hrow.append(totalHeader);
for(var i=0;i<keys.length; i++){
var newRow = document.createElement("tr");
var idVal = keys[i];
var valVal = tdDict[idVal];
var idValTd = document.createElement("td");
idValTd.textContent = idVal;
var valValTd = document.createElement("td");
valValTd.textContent = valVal;
newRow.appendChild(idValTd);
newRow.appendChild(valValTd);
totalTable.appendChild(newRow);
}
<table>
<tr><th>ID</th><th>Value</th></tr>
<tr><td name="itin" id="itin">100</td><td id="initValue" name="initValue">3</td></tr>
<tr><td name="itin" id="itin">200</td><td id="initValue" name="initValue">2</td></tr>
<tr><td name="itin" id="itin">400</td><td id="initValue"name="initValue">7</td></tr>
<tr><td name="itin" id="itin">100</td><td id="initValue" name="initValue">4</td></tr>
</table>
<div id="totals">
</div>

Add rows and data

So currently I can add rows with this code:
function addRow(){
var tableRef = document.getElementById('myTable').getElementsByTagName('tbody')[0];
// Insert a row in the table at row index 0
var newRow = tableRef.insertRow(tableRef.rows.length);
// Insert a cell in the row at index 0
var newCell = newRow.insertCell(0);
// Append a text node to the cell
var newText = document.createTextNode('New row')
newCell.appendChild(newText);
}
Here is my table:
<table id="myTable" border="2px">
<tbody>
<td>
Module 1
</td>
<td>
Introduction
</td>
<td id="info">
</td></tr>
<tr>
<td>
<div id="button"> Add Another Row </div>
</td></tr>
</tbody>
</table>
Here is how I add data to the row:
function showChoices()
{
//retrieve data
var selLanguage = document.getElementById("productchoice3");
//set up output string
var result="<ul> \n";
//step through options
for (i = 0; i < selLanguage.length; i++)
{
//examine current option
currentOption = selLanguage[i];
//print it if it has been selected
if (currentOption.selected == true)
{
console.log(currentOption.label);
result += " <li>" + currentOption.label + "<br>" + currentOption.value + "<\/li> \n";
} // end if
} // end for loop
//finish off the list and print it out
result += "<\/ul> \n";
output = document.getElementById("info");
output.innerHTML = result;
document.getElementById('info').style.display='block';
}
What I want to do is have the "add another row" move down each time I click it, so I can add infinite rows, and have a way to add data to the newest row that was created.
You could easily add an id to the row, by doing:
var newRow = tableRef.insertRow(tableRef.rows.length);
newRow.id = "whateverYouWant";

Javascript cell color according to math

I have an html table with numbers. For example:
Col1 Col2 Col3
5 3 1
1 2 1
10 3 2
And I want to use Javascript in order each cell has a specific color background according to the following math:
if one of the three columns (for each row) is greater than the sum of the other 2 columns
for example:
Col1 > Col2 + Col3 => bkg color: #000
Col2 > Col1 + Col3 => bkg color: #333
Col3 > Col1 + Col3 => bkg color: #666
Can I do it with Javascript? Can anyone help with the code?
Here's something for you (http://jsfiddle.net/AbnCz/3/). This doesn't scale that well as an algo, but works as per your requirements. If you end up adding more rows/cols, add the appropriate colors in the colors array.
> update: made a perf update to cache the sum as opposed to determining it through each cell traversal
HTML
<table id="dataTable">
<tr>
<td>20</td>
<td>50</td>
<td>70</td>
</tr>
<tr>
<td>40</td>
<td>2</td>
<td>7</td>
</tr>
<tr>
<td>5</td>
<td>2</td>
<td>60</td>
</tr>
</table>
Javascript
var colors = ["#000","#333","#666"];
var t = document.getElementById('dataTable');
var rows = t.getElementsByTagName('tr'), row, cells, tgtCell, rowSum, othersSum;
// let's go through the rows
for(var r=0; r<rows.length; r++){
row = rows[r];
cells = row.getElementsByTagName('td');
rowSum = 0;
// lets get the sum for the row.
// we'll subtract each cell from it to get the remaining sum.
for(var _c=0; _c<cells.length; _c++){
rowSum += parseInt(cells[_c].textContent,10);
}
// let's go through the cells
for(var c=0; c<cells.length; c++){
tgtCell = cells[c];
tgtVal = parseInt(tgtCell.textContent, 10);
othersSum = rowSum - tgtVal;
// if the target is greater than the remaining sum, style it
if(tgtVal > othersSum){
tgtCell.style.backgroundColor = colors[c % colors.length];
}
}
}
Try this :
HTML:
<table id="dataTable">
<tr>
<td>3</td>
<td>5</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>4</td>
</tr>
<tr>
<td>16</td>
<td>13</td>
<td>2</td>
</tr>
</table>
JAVASCRIPT :
var table = document.getElementById('dataTable'), activeCells
row = table.getElementsByTagName('tr'),
cell = table.getElementsByTagName('td');
var colorArray = new Array('red', 'blue', 'yellow');
//loop through all rows
for ( var i = 0; i < row.length; ++i) {
//get cells currently being read
activeCells = row[i].getElementsByTagName('td');
//prepare storage
var cellArray = new Array(),
newCellArray = new Array(),
cellElementArray = new Array(),
sum = 0;
//loop through active cells
for ( var x = 0; x < activeCells.length; ++x ) {
var currentCell = activeCells[x],
cellVal = parseInt( currentCell.innerHTML );
cellArray[x] = cellVal;
newCellArray[x] = cellVal;
cellElementArray[x] = currentCell;
}
//loop through Cell Array
for ( var y = 0; y < cellArray.length; ++y ) {
newCellArray.splice(y, 1);
for ( var z = 0; z < newCellArray.length; ++z ) {
sum += newCellArray[z];
}
newCellArray = [];
for ( var n = 0; n < cellArray.length; ++n ) {
newCellArray[n] = cellArray[n];
}
console.log( sum);
if ( cellArray[y] > sum ) {
console.log( 'in');
cellElementArray[y].style.backgroundColor = colorArray[y];
}
sum = 0;
}
}
An additional feature that I implemented is that this is dynamic. Try to increase the number of cells and it will still calculate.
And please change the colorArray according to your preference. It is by column ordered. something like var colorArray = new Array('#000','#333','#667');
jsfiddle demo: http://jsfiddle.net/aVqCU/
I haven't tested this code myself. But it should be something like this:
var table = document.getElementById("table"); //Replace "table" with the id of your table in the HTML
var table = document.getElementById("table"); //Replace "table" with the id of your table in the HTML
for (var i = 0, row; row = table.rows[i]; i++) //iterate through rows
{
var cell1 = row.cells[0];
var cell2 = row.cells[1];
var cell3 = row.cells[2];
if(parseFloat(cell1.innerHTML) > (parseFloat(cell2.innerHTML) + parseFloat(cell3.innerHTML)))
{
cell1.style.backgroundColor = "#000";
}
if(parseFloat(cell2.innerHTML) > parseFloat(cell3.innerHTML) + parseFloat(cell1.innerHTML))
{
cell2.style.backgroundColor = "#333";
}
if(parseFloat(cell3.innerHTML) > parseFloat(cell2.innerHTML) + parseFloat(cell1.innerHTML))
{
cell3.style.backgroundColor = "#666";
}
}
You may need to use parseInt or parseFloat on the row.cells to convert the text to a number.

Dynamic table from user input with cell id as grid reference

I am trying to create a table that is generated by user input data.
The table is reflecting a grid therfore I want the id of each cell to be the co ordinate of that grid. So the id of the bottom left cell would be id00. The top right cell id would be the maximum size of the grid that the user has entered.
So for example if data entered; x value=3; y value=3
this would produce the following table:
<table>
<tr><td id="id03"></td><td id="id13"></td><td id="id23"></td><td id="id33"></td></tr>
<tr><td id="id02"></td><td id="id12"></td><td id="id22"></td><td id="id32"></td></tr>
<tr><td id="id01"></td><td id="id11"></td><td id="id21"></td><td id="id31"></td></tr>
<tr><td id="id00"></td><td id="id10"></td><td id="id20"></td><td id="id30"></td></tr>
</table>
I have identified the basic concept for the code as you can see below:
<table>
Create a loop, initial value of r= 0; maximum value of r=y
r =0 <tr> create a secondary loop, initial value of n=0; maximum value of n = x; r remains constant for row
n=0; r= 0 <td id = “id” + “[x- (x-n)]” + “[y-r]” > </td>
….
n=3; r= 0* <td id = “id” + “[x- (x-n)]” + “[y-r]” > </td>
</tr>
….
r =3 <tr> n=0; r= 3 <td id = “id” + “[x- (x-n)]” + “[y-r]” > </td>
….
n=3; r= 3<td id = “id” + “[x- (x-n)]” + “[y-r]” > </td>
</tr>
</table>
I want to develop it in Javascript but I am new to the language and I am having trouble coding it.
Any help anyone could provide would be greatly appreciated.
Try this :
var x = 3; // value from input
var y = 4; // value from input
var table = document.getElementById("myTable");
for(var i = 0; i < y; i++) {
var row = table.insertRow(-1);
for(var j = 0; j < x; j++) {
var cell = row.insertCell(-1);
cell.id = "id" + (j) + (y - i - 1);
cell.innerHTML = cell.id;
}
}
​
Working example
Try something like this :
var rows = parseInt(document.getElementById('rows').value,10); // get input value
var cols = parseInt(document.getElementById('cols').value,10); // get input value
var table = document.createElement('table'); // create table element
table.border = "1"; // set some attributes
var prevrow; // used to store previous row element
for (var r = 0; r < (rows+1); r++) { // loop rows
var row = document.createElement('tr'); // create tr
for (var c = 0; c < (cols+1); c++) { // loop cols
var col = document.createElement('td'); // create td
col.id = 'id' + r + c; // set id of tr
col.innerHTML = col.id; // add some text
row.appendChild(col); // append td to tr
}
// if first tr then create append to table else insert before previous tr
if (prevrow) {
table.insertBefore(row, prevrow);
} else {
table.appendChild(row);
}
// store newly create tr
prevrow = row;
}
// append the new table to the output div
document.getElementById('output').appendChild(table);
Uses document.createElement(), element.appendChild() and element.insertBefore() to build the table
Working example here

Categories