Delete specific column when importing to excel - javascript

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
}

Related

How to add new column with specific header name and content in Javascript

I have a HTML table and a button that allow user to add a new column. Right now user able to add new column when pressing "add", however i wish the header of the added column can be named as Group1 and Group2, Group3.. for the other press attempt.
Currently it only showed the number of the rows and columns:
Expected Output (When user click add column 3 times, the header should become Group1 and so on):
// append column to the HTML table
function appendColumn() {
var tbl = document.getElementById('member_table'), // table reference
i;
// open loop for each row and append cell
for (i = 0; i < tbl.rows.length; i++) {
createCell(tbl.rows[i].insertCell(tbl.rows[i].cells.length), i, 'col');
}
}
// create DIV element and append to the table cell
function createCell(cell, text, style) {
var div = document.createElement('div'), // create DIV element
txt = document.createTextNode(text); // create text node
div.appendChild(txt); // append text node to the DIV
div.setAttribute('class', style); // set DIV class attribute
div.setAttribute('className', style); // set DIV class attribute for IE (?!)
cell.appendChild(div); // append DIV to the table cell
}
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="member_table">
<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>
<button onclick="javascript:appendColumn()">Add column</button>
You can just add a line to update the value after the column is built. Note that I have made some best-practice improvements to variable names and initialization (type, location).
Also, you should refactor a bit so that the first cell in the column is a th.
let groupNum = 1;
const tableEl = document.getElementById('member_table');
// append column to the HTML table
function appendColumn() {
// open loop for each row and append cell
for (let i = 0; i < tableEl.rows.length; i++) {
createCell(tableEl.rows[i].insertCell(tableEl.rows[i].cells.length), i, 'col');
}
tableEl.rows[0].querySelector('td:last-child').textContent = 'Group' + groupNum;
groupNum++;
}
// create DIV element and append to the table cell
function createCell(cell, text, style) {
var div = document.createElement('div'), // create DIV element
txt = document.createTextNode(text); // create text node
div.appendChild(txt); // append text node to the DIV
div.setAttribute('class', style); // set DIV class attribute
div.setAttribute('className', style); // set DIV class attribute for IE (?!)
cell.appendChild(div); // append DIV to the table cell
}
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="member_table">
<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>
</table>
<button onclick="javascript:appendColumn()">Add column</button>

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>

Accessing table cells with jQuery using an object

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 ;
}
}) ;

Keep table header from hiding on search

Using the table sort on w3schools as a base, how can I keep my table header from disappearing on searching the table?
$(document).ready(function(){
$('#search-attorneys').on('keyup', function(){
var input, filter, table, tr, td, i;
input = $("#search-attorneys");
filter = $("#search-attorneys").val().toUpperCase();
table = $("#attorneys");
tr = $("tr");
for (i = 0; i < tr.length; i++) {
tds = tr[i].getElementsByTagName("td");
var found = false;
for (j = 0; j < tds.length; j++) {
td = tds[j];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
found = true;
break;
}
}
}
if (found) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
});
});
JSFIDDLE: LINK
You need to do change in first for loop:-
for (i = 1; i < tr.length; i++) { // not start with 0 start with 1.
Means leave table <thead><tr> and then start searching in rest <tr>.
Note:- check it and if you are facing any problem. I will create an example for you.
This can be easily achieved by putting the rows in a tbody, and changing the variabl;e tr selector.
$(document).ready(function(){
$('#search-attorneys').on('keyup', function(){
var input, filter, table, tr, td, i;
input = $("#search-attorneys");
filter = $("#search-attorneys").val().toUpperCase();
table = $("#attorneys");
tr = $("tbody tr"); // CHANGED
for (i = 0; i < tr.length; i++) {
tds = tr[i].getElementsByTagName("td");
var found = false;
for (j = 0; j < tds.length; j++) {
td = tds[j];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
found = true;
break;
}
}
}
if (found) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="search-attorneys" placeholder="Search for names.." title="Type in a name">
<table id="attorneys">
<thead class="cf">
<tr>
<th class="numeric">attorney</th>
<th class="numeric">location</th>
<th class="numeric">practice area</th>
<th class="numeric">email</th>
<th class="numeric">phone</th>
</tr>
</thead>
<tbody>
<tr>
<td data-title="location">Alfreds Futterkiste</td>
<td>Germany</td>
</tr>
<tr>
<td>Berglunds snabbkop</td>
<td>Sweden</td>
</tr>
<tr>
<td>Island Trading</td>
<td>UK</td>
</tr>
<tr>
<td>Koniglich Essen</td>
<td>Germany</td>
</tr>
<tr>
<td>Laughing Bacchus Winecellars</td>
<td>Canada</td>
</tr>
<tr>
<td>Magazzini Alimentari Riuniti</td>
<td>Italy</td>
</tr>
<tr>
<td>North/South</td>
<td>UK</td>
</tr>
<tr>
<td>Paris specialites</td>
<td>France</td>
</tr>
</tbody>
</table>

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