how to make JavaScript cell take full row width - javascript

I have a table which takes data from an array. My problem is that I do not know how to make it so that the cell takes the whole row if the objects in the array have a value of zero. If it has a value greater than zero, 2 cells will be displayed one with an item name and another with its value. Any help is much appreciated.
//breaks loop if x is == to counters array
if (this.state.counters.length == x) {
break;
}
const info = this.state.counters[x]["text"];
const quantity = this.state.counters[x]["value"];
console.log(info, quantity);
//creates rows based on input
var table = document.getElementById("myList");
var row = table.insertRow(1);
document.getElementById("thTitle").style.maxWidth = "100px";
if (quantity <= 0) {
var itemCell = row.insertCell(0);
itemCell.innerHTML = info;
} else {
var itemCell = row.insertCell(0);
var quantityCell = row.insertCell(1);
itemCell.innerHTML = info;
itemCell.style.minWidth = "100px";
quantityCell.innerHTML = quantity;
}
This is my output:

put this in:
if (quantity <= 0) {
var itemCell = row.insertCell(0);
itemCell.innerHTML = info;
// this line
itemCell.setAttribute('colspan', '2');
}

there is the attribute colspan to td tag that the number is the number of rows he stretched on.
<table>
<tr>
<th>Month</th>
<th>Savings</th>
</tr>
<tr>
<td>January</td>
<td>$100</td>
</tr>
<tr>
<td>February</td>
<td>$80</td>
</tr>
<tr>
<td colspan="2">Sum: $180</td>
</tr>
</table>
//In Js just add
itemCell.setAttribute('colspan', '2');
when the quantity <= 0

Related

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 to table with JavaScript

I am trying to use JavaScript or ASP C# to add rows to a table in form when the user clicks the add row button. I have working code in JavaScript. I want to add the rows with text input boxes inside of the <td></td> tags. The row count is in my code becasue I am attempting to use it to add IDs to each element for use later.
element.innerHTML(<input id="tagcell"+(rowcount+1)+"" type="text"/>);
function addrow() {
var rowcount =
document.getElementById('tbl').getElementsByTagName('tbody').length;
window.alert(rowcount);
var tableRef = document.getElementById('tbl').getElementsByTagName('tbody')[0];
var newRow = tableRef.insertRow(tableRef.rows.length);
// Insert a cell in the row at index 0
var tagcell = newRow.insertCell(0);
var desccell = newRow.insertCell(1);
var loccell = newRow.insertCell(2);
var Namecell = newRow.insertCell(3);
var Sigcell = newRow.insertCell(4);
tagcell.innerHTML = "";
desccell.innerHTML="";
loccell.innerHTML = "";
Namecell.innerHTML="";
Sigcell.innerHTML = "";
}
<table id=tbl>
<tr>
<td id=tag_no>Col1</td>
<td id=desc> Col2</td>
<td id=loc> col3</td>
<td id=nme> col4</td>
<td id=sig> col5</td>
</tr>
</table>
<input type="button" value="clickme" onclick="addrow()" />
Here's how you could do that. (Obviously you can style the text boxes however you want.) Your code added the rows; I just added a textarea in each cell.
function addrow() {
var tableRef = document.getElementById('tbl').getElementsByTagName('tbody')[0];
var rowcount = tableRef.rows.length;
window.alert(rowcount);
var newRow = tableRef.insertRow(tableRef.rows.length);
var textBox = "<textarea></textarea>";
// Insert a cell in the row at index 0
var tagcell = newRow.insertCell(0);
var desccell = newRow.insertCell(1);
var loccell = newRow.insertCell(2);
var Namecell = newRow.insertCell(3);
var Sigcell = newRow.insertCell(4);
tagcell.innerHTML = textBox;
desccell.innerHTML= textBox;
loccell.innerHTML = textBox;
Namecell.innerHTML= textBox;
Sigcell.innerHTML = textBox;
}
<table id=tbl>
<tr>
<td id=tag_no>Col1</td>
<td id=desc> Col2</td>
<td id=loc> col3</td>
<td id=nme> col4</td>
<td id=sig> col5</td>
</tr>
</table>
<input type="button" value="clickme" onclick="addrow()" />
EDIT: Your row count shows the correct number now. (It was only showing 1 each time before.)
function addrow() {
var myTable = document.querySelector('#tbl');
var row = myTable .insertRow(0);
var cell1 = row.insertCell(0);
cell1.innerHTML = 'My first cell';
// and so on for other cells
}
p.s. please add "" to all your HTML attributes values. For example
<table id="tbl">

Loop through my table's specific column

html
<table id="myList">
<thead>
<tr>
<td>Product ID</td>
<td>Product Name</td>
<td>Quantity</td>
</tr>
</thead>
<tbody>
</tbody>
</table>
Javascript
var tableRef = document.getElementById("myList").getElementsByTagName("tbody")[0];
var newRow = tableRef.insertRow(tableRef.rows.length);
var newCell = newRow.insertCell(0);
var otherCell = newRow.insertCell(2);
var check;
var myText = result.text;
var myTextTwo = myText.replace(/['"]+/g, '');
alert(myTextTwo);
for (var i = 0; i < tableRef.rows.length; i++) {
if (myTextTwo != tableRef.rows[i].cells[0].innerHTML) {
check = true
}
else if (myTextTwo == tableRef.rows[i].cells[0].innerHTML) {
tableRef.rows[i].cells[2].innerHTML += 1;
check = false;
break;
}
}
if (check) {
var newText = document.createTextNode(myTextTwo);
var otherText = document.createTextNode("1");
newCell.appendChild(newText);
otherCell.appendChild(otherText);
}
else {
alert("You have scanned this item before.");
}
What I have done is scanning a QR that contains a Product ID(e.g. "123") and insert the Product ID into the column called "Product ID", which I am able to do it.
However, what I am trying to do now is to, if the user scan a QR code that contains the same Product ID(e.g. "123"), my code will be able to detect the duplicate and add onto the quantity.
So what I planned to do is to loop through "Product ID" column and check if there's any duplicate. If there isn't any duplicates, the Quantity for the Product ID would be 1.
Product ID | Product Name | Quantity
123 | Hello | 1
Otherwise, duplicate exist, Quantity would be 2.
Product ID | Product Name | Quantity
123 | Hello | 2
Do you mean something like this?
var tableRef = document.getElementById("myList").getElementsByTagName("tbody")[0];
// save the row number of the existing product
var found = false;
var myText = result.text;
var myTextTwo = myText.replace(/['"]+/g, '');
// search the table for the existing product
for (var i = 0; i < tableRef.rows.length && !found; ++i) {
// if you found it then
if (tableRef.rows[i].cells[0].innerHTML == myTextTwo) {
// update the value
tableRef.rows[i].cells[2].innerHTML += 1;
// and say we found it
found = true;
}
}
// at this point, if we didn't find anything then add a new row
if (!found) {
var newRow = tableRef.insertRow(tableRef.rows.length);
newRow.insertCell(0).innerText = "...";
newRow.insertCell(0).innerText = "...";
newRow.insertCell(0).innerText = 1;
}
<table id="myList">
<thead>
<tr>
<td>Product ID</td>
<td>Product Name</td>
<td>Quantity</td>
</tr>
</thead>
<tbody>
</tbody>
</table>
I think this might help:
The function duplicateCell returns the number of the row that contains a duplicate on the given column or null if no duplicate found.
The function addOne requires a product ID to check for duplicates, a product Name (if no duplicates are found, the product will need a name, otherwise it is ignored) and it also needs to know what table to work on.
AddOne looks for duplicates using the above function and adds one to the quantity.
I started with 1 car 1 bike and 1 skateboard, added 2 bike (id2) and added 2 rockets (id 4).
var duplicateCell = function(tableId, columnNumber, stringToSearch) {
var myTbody = document.getElementById(tableId).getElementsByTagName("tbody")[0];
var tableRows = myTbody.rows.length;
for (var i = 0; i < tableRows; i++) {
if (myTbody.rows[i].cells[columnNumber].innerHTML.trim() == stringToSearch)
return i
}
return null;
}
function addOne(productId, productName, tableId) {
var myTbody = document.getElementById(tableId).getElementsByTagName("tbody")[0];
var rowIndex = duplicateCell(tableId, 0, productId)
if (rowIndex != null) {
myTbody.rows[rowIndex].cells[2].innerHTML = +myTbody.rows[rowIndex].cells[2].innerHTML.trim() + 1;
} else {
var tableRows = myTbody.rows.length;
var row = document.getElementById(tableId).insertRow();
c1 = row.insertCell(0);
c2 = row.insertCell(1);
c3 = row.insertCell(2);
c1.innerHTML = productId;
c2.innerHTML = productName;
c3.innerHTML = 1;
}
}
addOne("4", "Rocket", "myList")
addOne("4", "Rocket", "myList")
addOne("2", " ", "myList")
<table id="myList">
<thead>
<tr>
<td>Product ID</td>
<td>Product Name</td>
<td>Quantity</td>
</tr>
</thead>
<tbody>
<tr>
<td>1 </td>
<td>Car </td>
<td>1 </td>
</tr>
<tr>
<td>2 </td>
<td>Bike </td>
<td>1 </td>
</tr>
<tr>
<td>3 </td>
<td>Skateboard </td>
<td>1 </td>
</tr>
</tbody>
</table>

How to get min and max number from selected rows of table?

This refers to my previous question.
How to highlight/color multiple rows on selection?
<table id="toppings" border="1" cellpadding="2">
<tr id="id1">
<td>3</td>
<td>row12</td>
<td>row13</td>
</tr>
<tr id="id2">
<td>12</td>
<td>row22</td>
<td>row23</td>
</tr>
<tr id="id3">
<td>15</td>
<td>row32</td>
<td>row33</td>
</tr>
<tr id="id4">
<td>22</td>
<td>row42</td>
<td>row43</td>
</tr>
<tr id="id5">
<td>23</td>
<td>row52</td>
<td>row53</td>
</tr>
<tr id="id6">
<td>55</td>
<td>row62</td>
<td>row63</td>
</tr>
</table>
Javascript Code:
//Get list of rows in the table
var table = document.getElementById("toppings");
var rows = table.getElementsByTagName("tr");
var selectedRow;
//Row callback; reset the previously selected row and select the new one
function SelectRow(row) {
if (selectedRow !== undefined) {
selectedRow.style.background = "#d8da3d";
}
selectedRow = row;
selectedRow.style.background = "white";
}
//Attach this callback to all rows
for (var i = 0; i < rows.length; i++) {
var idx = i;
rows[idx].addEventListener("click", function(){SelectRow(rows[idx])});
}
But this time I have added an event to table for row selection and trying to get min and max value from selected rows (first column). Like above table, if I select middle four rows, i should get min = 12 and max = 23. How can this be implemented?
You can have two functions. I show the getMinValueExample().
function getMinValueExample(rows){
var minValue = null;
for (var i = 0; i < rows.length; i++){
var firstTd = rows[i].getElementsByTagName('td')[0];
var currentValue = parseInt(firstTd.innerHTML);
if(minValue == null || minValue > currentValue)
minValue = currentValue;
}
return minValue;
}
(not test so can contain some type errors but you should get the idea)
So if you call this after you've declared rows it returns the min value.
And if you call this one you get the max value
function getMaxValueExample(rows){
var maxValue = null;
for (var i = 0; i < rows.length; i++){
var firstTd = rows[i].getElementsByTagName('td')[0];
var currentValue = parseInt(firstTd.innerHTML);
if(maxValue == null || maxValue < currentValue)
maxValue = currentValue;
}
return maxValue;
}

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.

Categories