I'm creating an google chrome extension and trying to log data in html table. I am currently having trouble trying to get rows to append to my html table. I'm trying to get it to where everytime the user visits a new url another row is added to the table.
Picture of chrome extension
Below is my current code:
Manifest.json
{
//Required naming
"name" : "Activity logger",
"version": "1.0",
"manifest_version": 2,
"description": "This support includes the development of a Chrome Browser Activity Logger.",
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js", "popup.js"]
}
],
"browser_action": {
"default_icon": "act.png",
"default_title": "Activity",
"default_popup": "popup.html"
},
"background": {
"scripts": ["background.js"]
},
"permissions": ["tabs", "storage"]
}
popup.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>
Activity Logger
</title>
<style>
*{
color:#2b2b2b;
font-family: "Roboto Condensed";
}
table{ width:40%;}
th{ text-align:left; color:#4679bd}
tbody > tr:nth-of-type(even) { background-color:#daeaff;)
button( cursor:pointer; margin-top:1rem;)
</style>
</head>
<body>
<script src="popup.js" charset="utf-8"></script>
<h2>Activity Logger</h2>
<table id = "tableID" border="1">
<!--Example table header row with the user, url visited, and time they visited the url etc-->
<tr>
<!--categories-->
<th>Browser</th>
<th>Timestamp</th>
<th>URL</th>
<th>Protocol</th>
<th>Downloaded File Names</th>
<th>Description</th>
</tr>
<tr id='myRow'>
<!--1st row-->
<td>Google</td>
<td>000000</td>
<td>https://stackoverflow.com/questions/ask</td>
<td>example</td>
<td>example</td>
<td>example</td>
</tr>
<!--Goal is to append to this table-->
</table>
<!--when clicked it, ID uses function, exportTableToCSV to download file-->
<a id="click-this">
<u> Save as CSV </u>
</a>
</body>
</html>
popup.js
//loads element url on page--draft
document.addEventListener('DOMContentLoaded', function () {
const bg = chrome.extension.getBackgroundPage()
Object.keys(bg.bears).forEach(function (url) {
const div = document.createElement('div')
div.textContent = `${url}`
document.body.appendChild(div)
})
}, false)
// creates ID to export table to csv--works
document.addEventListener('DOMContentLoaded', function() {
document.getElementById("click-this").addEventListener("click", exportTableToCSV);
});
//--underwork--
document.addEventListener('DOMContentLoaded', function() {
document.getElementById("tableID").addEventListener("click", addRow);
});
//function to append row to HTML table --underwork--
function addRow() {
//perhaps need an for loop for every page visited
//get html table
// Append product to the table
var table = document.getElementByID("tableID");
// add new empty row to the table
// 1 = in the top (say you wanna have the most recent link visited at the top row after the header)
// table.rows.length = the end
// table.rows.length/2+1 = the center (probably not useful for you)
var newRow = table.insertRow(1);
// add cells to the row
var nameCell = newRow.insertCell(0);
var urlCell = newRow.insertCell(1);
var timeCell = newRow.insertCell(2);
// add the data to the cells
nameCell.innerHTML = USERNAME;
urlCell.innerHTML = URL_VISITED;
timeCell .innerHTML = TIMESTAM;
}
//perhaps add row using JQuery--underwork
/*function addRowUsingJquery() {
// Get a reference to your table
let table = document.querySelector('#tableID');
// Build the row
let template = `
<tr>
<td>${USERNAME}</td>
<td>${URL_VISITED}</td>
<td>${TIMESTAMP}</td>
</tr>`;
// Add the row to the end of the table
table.innerHTML += template;
}
*/
//function to for onClick function--works
function downloadCSV(csv, filename) {
var csvFile;
var downloadLink;
csvFile = new Blob([csv], {type:"text/csv"});
downloadLink = document.createElement("a");
downloadLink.download = filename;
downloadLink.href = window.URL.createObjectURL(csvFile);
downloadLink.style.display = "none";
downloadLink.setAttribute("download", "data.csv");
document.body.appendChild(downloadLink);
downloadLink.click();
}
//function to export HTML table to csv file--works
function exportTableToCSV(filename) {
var csv = [];
var rows = document.querySelectorAll("table tr");
for(var i = 0; i < rows.length; i++) {
var row = [], cols = rows[i].querySelectorAll("td, th");
for(var j=0; j < cols.length; j++)
row.push(cols[j].innerText);
csv.push(row.join(","));
}
//download csv file
downloadCSV(csv.join("\n"), filename);
}
I believe when you use insertRow, the html of the table needs to have a tbody
http://jsfiddle.net/4sR2G/
https://developer.mozilla.org/en-US/docs/Web/API/HTMLTableElement/insertRow
So the html table should be in the format of:
<table id="tableID">
<thead>
<tr>
<th>Browser</th>
<th>Timestamp</th>
<th>URL</th>
<th>Protocol</th>
<th>Downloaded File Names</th>
<th>Description</th>
</tr>
</thead>
<tbody id="tbodyID">
<tr>
<td>Google</td>
<td>000000</td>
<td>https://stackoverflow.com/questions/ask</td>
<td>example</td>
<td>example</td>
<td>example</td>
</tr>
</tbody>
</table>
You can then change the JS to reflect these changes:
//function to append row to HTML table --underwork--
function addRow() {
//perhaps need an for loop for every page visited
//get html table
// Append product to the table
var table = document.getElementById("tbodyID");
// add new empty row to the table
// 1 = in the top (say you wanna have the most recent link visited at the top row after the header)
// table.rows.length = the end
// table.rows.length/2+1 = the center (probably not useful for you)
// insertRow(0) as top of body (excludes head)
var newRow = table.insertRow(0);
// add cells to the row
var nameCell = newRow.insertCell(0);
var urlCell = newRow.insertCell(1);
var timeCell = newRow.insertCell(2);
// add the data to the cells
nameCell.innerHTML = USERNAME;
urlCell.innerHTML = URL_VISITED;
timeCell.innerHTML = TIMESTAM;
}
Related
Using javascript I'm able to create a table. But I wanted to add a header to this table by merging all cells in the top row
This is my existing code to convert HTML table to CSV. But here I am unable to create a header with 'some title' that spans to the entire column.
So the output should look something like this
function downloadCSV(csv, filename) {
var csvFile;
var downloadLink;
// CSV file
csvFile = new Blob([csv], {
type: "text/csv"
});
// Download link
downloadLink = document.createElement("a");
// File name
downloadLink.download = filename;
// Create a link to the file
downloadLink.href = window.URL.createObjectURL(csvFile);
// Hide download link
downloadLink.style.display = "none";
// Add the link to DOM
document.body.appendChild(downloadLink);
// Click download link
downloadLink.click();
}
function exportTableToCSV(filename) {
var csv = [];
var rows = document.querySelectorAll("table tr");
for (var i = 0; i < rows.length; i++) {
var row = [],
cols = rows[i].querySelectorAll("td, th");
for (var j = 0; j < cols.length; j++) {
row.push(cols[j].innerText);
}
csv.push(row.join(","));
}
// Download CSV file
downloadCSV(csv.join("\n"), filename);
}
<table>
<tr>
<th>Name</th>
<th>Email</th>
<th>Country</th>
</tr>
<tr>
<td>John Doe</td>
<td>john#gmail.com</td>
<td>USA</td>
</tr>
<tr>
<td>Stephen Thomas</td>
<td>stephen#gmail.com</td>
<td>UK</td>
</tr>
<tr>
<td>Natly Oath</td>
<td>natly#gmail.com</td>
<td>France</td>
</tr>
</table>
<button onclick="exportTableToCSV('ps_file.csv')">
Export HTML Table To CSV File
</button>
CSV does not support column widths.
They are Comma Separated Values which means each column is separated by a comma.
You can put the "Details List" in the "Center" by putting a comma before it in that row so that it goes to the second column, but it will not automatically center itself.
The file format you would need for that would be xlsx which is much more complicated.
Edit: also if you want to manipulate CSVs in the future. You can use papa parse.
I'm trying to use the insertcell method to add a column to my table but either I'm getting the syntax wrong or it isn't working. I wondered if anyone could explain where I am going wrong?
The table body in the html is populated dynamically with some other JavaScript but I don't think this is the problem as I've tested grabbing some content from that table with an alert box and it works (commented out below):
<!DOCTYPE html>
<script type="text/javascript" src="fullstationxyparser.js">
</script>
<html>
<body>
<table border=1>
<thead>
<tr>
<td>Element Name</td>
<td>x</td>
<td>y</td>
<td>testCol</td>
</tr>
</thead>
<tbody id="stationlist">
</tbody>
</table>
</body>
</html>
function addStationNames() {
var myTable = document.getElementById("stationlist");
var stationListRows = myTable.getElementsByTagName('tr');
for (var i = 1; i < stationListRows.length; i++) {
var cell = stationListRows[i].getElementsByTagName('td');
var stationName = cell[0].innerHTML; //get station id from element Name column
var currentRow = stationListRows[i];
var newCol = currentRow.insertcell(-1);
newCol.innerHTML = stationName;
//alert(stationName);
}
}
In Firefox developer tools, I get TypeError: "currentRow.insertcell is not a function". Perhaps I can't use the insertcell method on a row collection?
In general you can call the insertRow() method on a Table DOM element, followed by calls to the insertCell() method as shown below to dynamically add <td> tags to your table with JavaScript.
Be careful to call insertCell() (with capital C) rather than insertcell() as you are currently doing:
const table = document.querySelector('table');
/* Insert new row */
const row = table.insertRow();
/* Insert cells (td) for row */
const td0 = row.insertCell(0);
const td1 = row.insertCell(1);
const td2 = row.insertCell(2);
const td3 = row.insertCell(3);
/* Populate cells with data */
td0.innerText = 'Foo';
td1.innerText = '3';
td2.innerText = '6';
td3.innerText = 'success';
<table border="1">
<thead>
<tr>
<td>Element Name</td>
<td>x</td>
<td>y</td>
<td>testCol</td>
</tr>
</thead>
<tbody>
</tbody>
</table>
Specific to your code, some other changes to consider might be as listed in this code snippet:
function addStationNames() {
/* Condense table row access into single query */
const stationRows = document.querySelectorAll("#stationlist tr");
stationRows.forEach((stationRow, i) => {
/* Skip first row */
if(i === 0) { return; }
/* Get station name from text of first cell */
const stationName = stationRow.querySelector('td:first-child').innerText;
/* Insert last cell on row and assign station name */
stationRow.insertCell(-1).innerText = stationName;
});
/*
Old code:
for (let i = 1; i < stationListRows.length; i++) {
var cell = stationListRows[i].getElementsByTagName('td');
var stationName = cell[0].innerHTML;
var currentRow = stationListRows[i];
var newCol = currentRow.insertcell(-1);
newCol.innerHTML = stationName;
}
*/
}
addStationNames();
<!-- set table id to stationlist -->
<table border="1" id="stationlist">
<thead>
<tr>
<td>Element Name</td>
<td>x</td>
<td>y</td>
<td>testCol</td>
</tr>
<tr>
<td>90's pop</td>
<td>232</td>
<td>543</td>
</tr>
</thead>
<tbody>
<!-- Remove id from tbody -->
</tbody>
</table>
An alternative to the answer above (which is totally fine) is this method, which is also a more general method of creating any html element:
const table = document.getElementById('one');
const newRow = document.createElement("tr");
let newCell = document.createElement("td");
newCell.textContent = "first cell";
let newCell2 = document.createElement("td");
newCell2.textContent = "second cell";
newRow.appendChild(newCell);
newRow.appendChild(newCell2);
table.appendChild(newRow);
https://jsfiddle.net/zgaosdbv/
I am creating a program that connects to Firebase Realtime Database and displays the value in a table.
Her is my code:
var leadsRef = database.ref('leads/'+leadID);
var table = document.getElementById('remarksTable');
leadsRef.on('child_added', function(snapshot) {
var remark = snapshot.val().remark;
var timestamp = snapshot.val().timestamp;
var row = document.createElement('tr');
var rowData1 = document.createElement('td');
var rowData2 = document.createElement('td');
var rowData3 = document.createElement('td');
var rowDataText1 = document.createTextNode(remark);
var rowDataText2 = document.createTextNode(timestamp);
var rowDataText3 = document.createTextNode("Some text");
rowData1.appendChild(rowDataText1);
rowData2.appendChild(rowDataText2);
rowData3.appendChild(rowDataText3);
row.appendChild(rowData1);
row.appendChild(rowData2);
row.appendChild(rowData3);
table.appendChild(row);
});
leadID is an ID which I get from the current url, it contains the correct value so no issues there, path is also absolutely right.
Here is the table code:
<table class="table table-bordered" id="remarksTable">
<tr>
<th><strong>Created On</strong></th>
<th><strong>Timestamp 2</strong></th>
<th><strong>Remarks</strong></th>
</tr>
<tr>
<td>12312313231</td>
<td>12312312312</td>
<td>just a remark.</td>
</tr>
</table>
Now, when I run the page, it connects to the Firebase database and loads the required values, creates table row and table data, attaches text to it and then finally attaches the row to table with the id of remarksTable but it is not creating rows properly. Please note the table is creating using Bootstrap.
This is how it looks:
As you can see, the first row displays fine but the next 2 rows which were created by javascript looks a bit different.
The most likely reason is that you are appending the new row to the table element and not the tbody element inside it, which is interacting poorly with the stylesheet that you didn't include in the question.
Note that all tables have a tbody element. The start and end tags for it are optional so it will be inserted by HTML parsing rules if you don't provide one (or more) explicitly).
#Quentin is right, or you can simply add new rows this way:
var table = document.getElementById("remarksTable");
var row = table.insertRow();
var rowData1 = row.insertCell(0);
var rowData2 = row.insertCell(1);
var rowData2 = row.insertCell(2);
rowData1.innerHTML = remark;
rowData2.innerHTML = timestamp;
rowData3.innerHTML = "some text";
Here is a working demo
function addCells() {
var table = document.getElementById("remarksTable");
var row = table.insertRow();
var rowData1 = row.insertCell(0);
var rowData2 = row.insertCell(1);
var rowData3 = row.insertCell(2);
rowData1.innerHTML = "your remark";
rowData2.innerHTML = "your timestamp timestamp";
rowData3.innerHTML = "some text";
}
<table id="remarksTable" border=1>
<tr>
<td>first cell</td>
<td>2nd cell</td>
<td>3rd cell</td>
</tr>
</table>
<button onclick="addCells()">Add New</button>
I'm developing a web application.My App is using Javascript, PHP, HTML. I already done apply code to upload xlsx , attach it on screen .
Here's my Code
<script type="text/javascript" src="simple-excel.js"></script>
<table width=50% align="left" border=0 STYLE="border-collapse:collapse;">
<tr>
<td style="width:9.2%"><b>Load CSV file</b></td>
<td style="width:1%"><b>:</b></td>
<td style="width:15%"><input type="file" id="fileInputCSV" /></td>
</tr>
</table>
<table id="result"></table>
<script type="text/javascript">
// check browser support
// console.log(SimpleExcel.isSupportedBrowser);
var fileInputCSV = document.getElementById('fileInputCSV');
// when local file loaded
fileInputCSV.addEventListener('change', function (e) {
// parse as CSV
var file = e.target.files[0];
var csvParser = new SimpleExcel.Parser.CSV();
csvParser.setDelimiter(',');
csvParser.loadFile(file, function () {
// draw HTML table based on sheet data
var sheet = csvParser.getSheet();
var table = document.getElementById('result');
table.innerHTML = "";
sheet.forEach(function (el, i) {
var row = document.createElement('tr');
el.forEach(function (el, i) {
var cell = document.createElement('td');
cell.innerHTML = el.value;
row.appendChild(cell);
});
table.appendChild(row);
});
});
});
</script>
Here's my UI
How do i supposed to do for hide/erase the null cell(Red Mark)?
It seems your CSV has an empty line at the bottom. Even if it is empty, as far as "sheet" is concerned, it will have one field as long as a carriage return is there.
I'd check to see if the content of the "el" contains anything before executing your el.forEach()
Put some condition inside el.forEach
Like this
el.forEach(function (el, i) {
if(el.value!="")
{
var cell = document.createElement('td');
cell.innerHTML = el.value;
row.appendChild(cell);
}
});
I have a button as well as in a table row.When I click on button new row should be added in the table and button should be present in newly added row .refer the picture
Here's a quick solution to adding new rows with buttons that will also add new rows.
You didn't add any code, but this works.
https://jsfiddle.net/scheda/Lhsvmqoy/
var b = document.querySelector('.clicky')
var table = document.querySelector('table');
var insert_this = '<tr><td><input type="text" placeholder="Look ma!"/><button class="clicky">Add more stuff</button></td></tr>';
document.querySelector('body').addEventListener('click', function(e) {
if (e.target.className === 'clicky') {
table.innerHTML += insert_this;
}
});
This should work as you expect:
<!DOCTYPE html>
<head>
<style>
td,table{border:solid 1px;}
</style>
<title>Table sample </title>
</head>
<body>
<table id="myTable">
<tr>
<td>Row 1</td><td></td>
</tr>
<tr>
<td>Row 2</td><td><button id="newRow">New Row (original button)</button></td>
</tr>
</table>
</body>
<script>
function addRow() {
// Get a reference to the table
var tableRef = document.getElementById('myTable');
// Insert a row in the table at the end
var newRow = tableRef.insertRow(tableRef.rows.length);
// Insert a cell in the row at index 0
var newCell = newRow.insertCell(0);
newCell.innerHTML="Row " + tableRef.rows.length;
var newCell = newRow.insertCell(1);
// Append button node to the cell
var newButton = document.getElementById('newRow');
newCell.appendChild(newButton);
}
function addEvent(elem, event, fn) {
if (elem.addEventListener) {
elem.addEventListener(event, fn, false);
}else {
elem.attachEvent("on" + event, function() {
// set the this pointer same as addEventListener when fn is called
return(fn.call(elem, window.event));
});
}
}
var mybutton = document.getElementById("newRow");
addEvent(mybutton,"click",addRow);
</script>
</html>
Source/Credits:
The addEventListener function: adding event listener cross browser
Add row function (modified from):
https://developer.mozilla.org/en-US/docs/Web/API/HTMLTableElement/insertRow