I need to copy in a multidimensional array the cells of a table.
I try the following code:
function tableManager ( table, rowitems ) {
var items = array () ;
var j = 0 ;
var arow = array() ;
$(table+' td').each(function() {
arow[j] = $(this).html() ;
j ++ ;
if ( j == rowitems) {
items.push(arow);
j = 0 ;
} ;
}) ;
this.show = function() {
.............
}
}
constructor is:
$(document).ready(function(){
var loadarr = new tableManager ( '#results', 4 ) ;
....
});
It seems do not execute the each() callback.
What is incorrect?
tableManager is a function, you don't have to construct it with "new". You have to call it as following :
$(document).ready(function(){
var loadarr = tableManager('#results', 4);
...
});
Also, you have a ";" after your "if(...){..}". You'll have to remove it :
if ( j == rowitems) {
items.push(arow);
j = 0 ;
} ; <= REMOVE THIS
More details here : https://www.w3schools.com/js/js_function_definition.asp
André
Your jquery function is not correct please see Working code here
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<style>
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
</style>
</head>
<body>
<table id="results">
<tr>
<th>Company</th>
<th>Contact</th>
<th>Country</th>
</tr>
<tr>
<td>Alfreds Futterkiste</td>
<td>Maria Anders</td>
<td>Germany</td>
</tr>
<tr>
<td>Centro comercial Moctezuma</td>
<td>Francisco Chang</td>
<td>Mexico</td>
</tr>
<tr>
<td>Ernst Handel</td>
<td>Roland Mendel</td>
<td>Austria</td>
</tr>
<tr>
<td>Island Trading</td>
<td>Helen Bennett</td>
<td>UK</td>
</tr>
<tr>
<td>Laughing Bacchus Winecellars</td>
<td>Yoshi Tannamuri</td>
<td>Canada</td>
</tr>
<tr>
<td>Magazzini Alimentari Riuniti</td>
<td>Giovanni Rovelli</td>
<td>Italy</td>
</tr>
</table>
</body>
<script type="text/javascript">
function tableManager ( table, rowitems ) {
var items = [] ;
$(table+' tr').each(function(i) {
var row = $(this);
if(rowitems == i){
row.find('td').each(function() {
console.log(this);
items.push($(this).html());
}) ;
}
});
console.log(items);
return items;
}
var itm = tableManager("#results", 4);
console.log(itm);
</script>
</html>
I hope this will help you.
If the problem is:
It seems do not execute the each() callback.
it is because tableManager is a function and you have to call it in the following way:
var loadarr = tableManager ( '#results', 4 ) ;
For more information visit W3Schools
Also, remove the ; after the closing brace of the if ( j == rowitems)
if ( j == rowitems) {
items.push(arow);
j = 0 ;
} // Removed ;
UPDATE
If the each method isn't reached then try to understand what's happening. Try using
console.log($(table+' td'));
just before the each method to be shure that the latter isn't executing because there are no elements.
console.log($(table+' td'));
$(table+' td').each(function() {
arow[j] = $(this).html() ;
...
Then you could add a console.log("Each executed") inside your parameter function to be shure that it is executed:
$(table+' td').each(function() {
console.log("Each executed");
arow[j] = $(this).html() ;
j ++ ;
if ( j == rowitems) {
items.push(arow);
j = 0 ;
}
}) ;
Related
I have the following JS code to import from a HTML table to Excel.
function fnExcelReport(){
var tab_text="<table border='2px'><tr bgcolor='#87AFC6'>";
var textRange; var j=0;
tab = document.getElementById('myTable'); // id of table
for(j = 0 ; j < tab.rows.length ; j++)
{
tab_text=tab_text+tab.rows[j].innerHTML+"</tr>";
}
tab_text=tab_text+"</table>";
tab_text= tab_text.replace(/<A[^>]*>|<\/A>/g, "");//remove if u want links in your table
tab_text= tab_text.replace(/<img[^>]*>/gi,""); // remove if u want images in your table
tab_text= tab_text.replace(/<input[^>]*>|<\/input>/gi, ""); // reomves input params
var ua = window.navigator.userAgent;
var msie = ua.indexOf("MSIE ");
if (msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./)) // If Internet Explorer
{
txtArea1.document.open("txt/html","replace");
txtArea1.document.write(tab_text);
txtArea1.document.close();
txtArea1.focus();
sa=txtArea1.document.execCommand("SaveAs",true,"Say Thanks to Sumit.xls");
}
else //other browser not tested on IE 11
sa = window.open('data:application/vnd.ms-excel,' + encodeURIComponent(tab_text));
return (sa);
}
I don't want to import the last column from the table. How can i do it?
If you use jquery then you can remove the last column easily by using last child selector
$('#myTable tr').find('th:last-child, td:last-child').remove()
But if you want to use JS, then try like below (it's just a dummy table for example purpose)
// GET ALL THE ROW OF THE TABLE USING TABLE ID
var tRow = document.getElementById('myTable').rows;
// LOOPING OVER EACH ROW
for (var i=0; i< tRow.length; i++) {
tRow[i].deleteCell(-1); //DELETE THE LAST COLUMN
}
for(j = 0 ; j < tRow.length ; j++)
{
console.log(tRow[j].innerHTML);
}
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
<table id="myTable">
<tr>
<th>Company</th>
<th>Contact</th>
<th>Country</th>
<th>ISO Code</th>
</tr>
<tr>
<td>Alfreds Futterkiste</td>
<td>Maria Anders</td>
<td>Germany</td>
<td>AL</td>
</tr>
<tr>
<td>Centro comercial Moctezuma</td>
<td>Francisco Chang</td>
<td>Mexico</td>
<td>MEX</td>
</tr>
<tr>
<td>Ernst Handel</td>
<td>Roland Mendel</td>
<td>Austria</td>
<td>AUS</td>
</tr>
<tr>
<td>Island Trading</td>
<td>Helen Bennett</td>
<td>UK</td>
<td>UK</td>
</tr>
<tr>
<td>Laughing Bacchus Winecellars</td>
<td>Yoshi Tannamuri</td>
<td>Canada</td>
<td>CAD</td>
</tr>
<tr>
<td>Magazzini Alimentari Riuniti</td>
<td>Giovanni Rovelli</td>
<td>Italy</td>
<td>ITL</td>
</tr>
</table>
So after getting the table data in your code, you can apply any of the methods you prefer.
If you choose second method then your code will be like below:
tab = document.getElementById('myTable'); // id of table
tabRows = tab.rows; //get the rows
for (var i=0; i< tabRows.length; i++) {
tabRows[i].deleteCell(-1); //DELETE THE LAST ONE
}
for(j = 0 ; j < tabRows.length ; j++) //DO YOUR ACTUAL WORK
{
//Your conditions
}
Using jquery or javascript, I'd like to get that how many element 500 in each column (1-4) of an html table is ? How should I do it ?
<html>
<table>
<thead>
<tr>
<th>Column-1</th>
<th>Column-2</th>
<th>Column-3</th>
<th>Column-4</th>
</tr>
</thead>
<tbody>
<tr>
<td>500</td>
<td>200</td>
<td>500</td>
<td>200</td>
</tr>
<tr>
<tr>
<td>501</td>
<td>500</td>
<td>500</td>
<td>200</td>
</tr>
</tbody>
</table>
</html>
The table is look like this format:
Column-1 Column-2 Column-3 Column-4
500 200 500 200
501 500 500 500
... ... .... ...
I would like to get : column-1: 1, column-2:1, column-3:2 column-4: 1
automatic display the numbers of "500" of each column .
Solution
filter the 's in row out
Store the column when the text of a td is 500
Count how often the column occurs
let trArr = $("table tr")
let res = [];
for (let i = 0; i < trArr.length; i++) {
let childs = trArr[i].children;
for (let j = 0; j < childs.length; j++) {
if(childs[j].tagName !== "TH"){
if (childs[j].textContent === "500" ) {
res.push({
"column": j+1
});
}
}
}
}
let result = new Set();
for (let i = 0; i < res.length; i++) {
let counter = 0;
for (let j = 0; j < res.length; j++) {
if (res[i].column === res[j].column) {
counter++;
}
}
result.add(`Column ${[res[i].column]}: ${counter} x 500`);
}
let resString = "";
for(let i of result){
resString += i + "\n";
}
document.getElementById("BLA").innerHTML = resString;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<table>
<thead>
<tr>
<th>Column-1</th>
<th>Column-2</th>
<th>Column-3</th>
<th>Column-4</th>
</tr>
</thead>
<tbody>
<tr>
<td>500</td>
<td>200</td>
<td>500</td>
<td>200</td>
</tr>
<tr>
<tr>
<td>501</td>
<td>500</td>
<td>500</td>
<td>200</td>
</tr>
</tbody>
</table>
<p id="BLA"></p>
</html>
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
I'm a completely newbie and looking for help.
Given the following table:
<table id="table">
<thead>
# FIRST ROW
<tr>
<th>Apple</th>
<th>Pizza</th>
<th>Eggs</th>
</tr>
<tbody>
# SECOND ROW
<tr>
<td>Apple</td> --> should end with 'success' class
<td>Juice</td>
<td>Lettuce</td>
<td>Oranges</td>
<td>Eggs</td> --> should end with 'success' class
</tr>
# THIRD ROW
<tr>
<td>Pizza</td> --> should end with 'success' class
<td>Chicken</td>
</tr>
</tbody>
</table>
I would like to add class 'success' to every td in SECOND and THIRD rows whenever it matches any td in FIRST row (and only in FIRST ROW).
For now I came up with adding <td> values of first row to array and I'm not sure what steps should I take next (filter? for loop and '===' comparison?):
function myFunction() {
var tHeadersValues = [];
var tHeaders = document.getElementById("table").rows[0].cells;
for (var i = 0; i < tHeaders.length; i++) {
tHeadersValues.push(tHeaders[i].textContent);
}
return tHeadersValues;
}
Object.keys(tHeaders).map(key => tHeaders[key].textContent) transforms the td objects to an array with the containing text. The rest is straight forward:
function toValues(tHeaders) {
return Object.keys(tHeaders).map(function(key){
return tHeaders[key].textContent;
});
}
function myFunction() {
var rows = document.getElementById("results-table").rows;
var tHeadersValues = toValues(rows[0].cells);
for (var i = 1; i < rows.length; i++) {
var rowCells = rows[i].cells;
var values = toValues(rowCells);
for(var j=0;j<values.length;j++) {
if(values[j].length > 0 && tHeadersValues.indexOf(values[j]) > -1) {
rowCells[j].className = "success";
}
}
}
}
myFunction();
<style>
.success {
background-color: green;
}
</style>
<table id="results-table">
<thead>
<tr>
<th>Apple</th>
<th>Pizza</th>
<th>Eggs</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>Apple</td>
<td>Juice</td>
<td>Lettuce</td>
<td>Oranges</td>
<td>Eggs</td>
</tr>
<tr>
<td>Pizza</td>
<td>Chicken</td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
function myFunc(){
var tds = document.getElementsByTagName("td");
var hds = document.getElementsByTagName("th");
for(var i=0; i<tds.length; i++) {
var tdContent = tds[i].innerHTML;
if(tdContent.length > 0){
for(var j = 0; j<hds.length; j++) {
if(tdContent === hds[j].innerHTML) {
document.getElementsByTagName("td")[i].className = "success";
}
}
}
}
}
myFunc();
<style>
.success {
background-color: green;
}
</style>
<table id="results-table">
<thead>
<tr>
<th>Apple</th>
<th>Pizza</th>
<th>Eggs</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>Apple</td>
<td>Juice</td>
<td>Lettuce</td>
<td>Oranges</td>
<td>Eggs</td>
</tr>
<tr>
<td>Pizza</td>
<td>Chicken</td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
I need your help.
Because of the way my data will be structured. I need to create some sort of a function that will allow a user to input the record number from column 1 into the input box "record". Then at the click of a button, the code will find the exact matching value from column 1 in my data table and select the row using the existing code to highlight it. I can't seem to be able to put together some sort of logic as to how to make this work.
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
#data tr.normal td {
color: #235A81;
background-color: white;
}
#data tr.highlighted td {
color: #FFFFFF;
background-color: #235A81;
}
</style>
<script type='text/javascript'>
function test() {
var table = document.getElementById("data");
var thead = table.getElementsByTagName("thead")[0];
var tbody = table.getElementsByTagName("tbody")[0];
var ishigh
tbody.onclick = function (e) {
e = e || window.event;
var td = e.target || e.srcElement
var row = td.parentNode;
if (ishigh&&ishigh!=row){
ishigh.className='';
}
row.className = row.className==="highlighted" ? "" : "highlighted";
ishigh=row;
}
document.onkeydown = function(e){
e = e || event;
var code = e.keyCode, rowslim = table.rows.length - 2, newhigh;
if(code === 38){ //up arraow
newhigh = rowindex(ishigh) - 2;
if(!ishigh || newhigh < 0){return GoTo('data', rowslim);}
return GoTo('data', newhigh);
} else if (code === 40){ //down arrow
newhigh = rowindex(ishigh);
if(!ishigh || newhigh > rowslim){return GoTo('data', 0);}
return GoTo('data', newhigh);
}
}
function GoTo(id,nu){
var obj=document.getElementById(id),
trs=obj.getElementsByTagName('TR');
nu = nu + 1;
if (trs[nu]){
if (ishigh&&ishigh!=trs[nu]){
ishigh.className='';
}
trs[nu].className = trs[nu].className=="highlighted" ? "" : "highlighted";
ishigh=trs[nu];
}
}
function rowindex(row){
var rows = table.rows, i = rows.length;
while(--i > -1){
if(rows[i] === row){return i;}
}
}
}//end of nested function
</script>
</head>
<body onload="test()">
<table style="cursor: default;" id="data" cellspacing="1" border="1">
<thead>
<tr>
<th>Record #</th>
<th>first name</th>
<th>last name</th>
<th>age</th>
<th>total</th>
<th>discount</th>
<th>diff</th>
</tr>
</thead>
<tbody>
<tr>
<td>5</td>
<td>peter</td>
<td>parker</td>
<td>28</td>
<td>9.99</td>
<td>20.3%</td>
<td>+3</td>
</tr>
<tr>
<td>3</td>
<td>john</td>
<td>hood</td>
<td>33</td>
<td>19.99</td>
<td>25.1%</td>
<td>-7</td>
</tr>
<tr>
<td>1</td>
<td>clark</td>
<td>kent</td>
<td>18</td>
<td>15.89</td>
<td>44.2%</td>
<td>-15</td>
</tr>
<tr>
<td>4</td>
<td>bruce</td>
<td>almighty</td>
<td>45</td>
<td>153.19</td>
<td>44%</td>
<td>+19</td>
</tr>
<tr>
<td>2</td>
<td>benjamin</td>
<td>evans</td>
<td>56</td>
<td>153.19</td>
<td>23%</td>
<td>+9</td>
</tr>
</tbody>
</table>
<br>
Example: type the record's number in the input box and then select it:
<input type="text" id="record" />
</body>
</html>
I'm still having trouble getting the big picture of what you're trying to do, but I wrote a function to grab the tr whose first td contains the record.
function findTrForRecord(record) {
var nodelist = document.getElementById('data').getElementsByTagName('tr');
for (var i = 0; i < nodelist.length; i++) {
var tr = nodelist.item(i);
var tds = tr.getElementsByTagName('td');
if (tds.length > 0 && tds[0].innerHTML.trim() == record)
return tr;
}
}
From there, you can highlight it or do whatever you want.
/**
* unhighlights previous row and highlights new row
* that matches the record
*/
button.onclick = function () {
var trs = document.getElementsByTagName('tr');
for (var i = 0; i < trs.length; i++)
if (trs[i].className.indexOf('highlighted') > 0) {
trs[i].className.replace('highlighted','');
break;
}
var record = document.getElementById('record').value;
var tr = findTrForRecord(record);
tr.className += ' highlighted';
}
I edited your html file you provided. Check this out. http://pastebin.com/Wz0EdBMV