Dynamically creating an html table with Javascript - javascript

I am trying to create a table based on user input (actually two or three tables depending on the user input..) using Javascript, I am very much native to PHP and have already got this working in PHP, however i would like the user to be able to see the table before the query it. I found a script on here that partially did what I wanted and have attempted to edit it (I found it surprisingly similar to PHP) Basically it calculates the total amount of cells (ports) splits it by rows and columns, the "super" column is used if the user would like it to be split into multiple tables, which align next to each other, hence the div tag. Here's my JS:
<html>
<head>
<script type="text/javascript">
function createTable()
{
var num_ports = document.getElementById('ports').value;
var num_super = document.getElementById('super').value;
var num_rows = document.getElementById('rows').value;
var num_cols = document.getElementById('cols').value;
var tbody = '';
var colStart = num_cols / num_super;
for( var i=0; i<num_super; i++){
var theader = '<div><table border="1">\n';
for(u=1; u<=num_row; u++){
tbody += '<tr>';
for( var j=0; j<colStart; j++)
{
tbody += '<td>';
tbody += 'Cell ' + i + ',' + j;
tbody += '</td>'
}
tbody += '</tr>\n';
}
var tfooter = '</table></div>';
document.getElementById('wrapper').innerHTML = theader + tbody + tfooter;
}
</script>
</head>
<body>
<form name="tablegen">
<label>Ports: <input type="text" name="ports" id="ports"/></label><br />
<label>Super Columns: <input type="text" name="super" id="super"/></label><br />
<label>Rows: <input type="text" name="rows" id="rows"/></label><br />
<label>Columns: <input type="text" name="cols" id="cols"/></label><br/>
<input name="generate" type="button" value="Create Table!" onclick='createTable();'/>
</form>
<div id="wrapper"></div>
</body>
</html>
Here is what the final output looks like after it has been processed by PHP (ports:24, col:6, rows:2, super:2):
Here is a js fiddle that I threw together:
http://jsfiddle.net/9SnLB/
Currently, when I click the button nothing happens, but, I suppose that is my first issue, but am I going about the setup correctly? Why wont the button run the function?

Two mistakes. One you didn't close the function bracket, ie a missing } at the end. The second is you used $row instead of the variable you created num_rows. For some reason it doesn't work in the fiddle, it does however work locally. The fiddle is saying the createTable function is undefined.
function createTable()
{
var num_ports = document.getElementById('ports').value;
var num_super = document.getElementById('super').value;
var num_rows = document.getElementById('rows').value;
var num_cols = document.getElementById('cols').value;
var tbody = '';
var colStart = num_cols / num_super;
for( var i=0; i<num_super; i++){
var theader = '<div><table border="1">\n';
for($u=1; $u<=num_rows; $u++){
tbody += '<tr>';
for( var j=0; j<colStart; j++)
{
tbody += '<td>';
tbody += 'Cell ' + i + ',' + j;
tbody += '</td>'
}
tbody += '</tr>\n';
}
var tfooter = '</table></div>';
document.getElementById('wrapper').innerHTML = theader + tbody + tfooter;
}
}

var table = [["a1","a2","a3"]["b1","b2","b3"]["c1","c2","c3"]];
for(x = table.length;x > 0;x--) {
document.write("<tr>");
for(y = table[x].length;y > 0;y--) {
document.write("<td>"+y+"</td>");
}
document.write("</tr>");
}
Sorry if the syntax is wrong. You get the idea.

You need to change your jsFiddle framework to "no wrap (head)" and correct errors in the javascript. "no wrap (head)" will allow access the function. The "for ($u=1" loop is missing the close brace and $row should be num_rows. The "for (j=0" loop is missing a semicolon at the last "tbody=".
here's the corrected js.
function createTable() {
var num_ports = document.getElementById('ports').value;
var num_super = document.getElementById('super').value;
var num_rows = document.getElementById('rows').value;
var num_cols = document.getElementById('cols').value;
var tbody = '';
var colStart = num_cols / num_super;
for (var i = 0; i < num_super; i++) {
var theader = '<div><table border="1">\n';
for ($u = 1; $u <= num_rows; $u++) {
tbody += '<tr>';
for (var j = 0; j < colStart; j++) {
tbody += '<td>';
tbody += 'Cell ' + i + ',' + j;
tbody += '</td>';
}
}
tbody += '</tr>\n';
}
var tfooter = '</table></div>';
document.getElementById('wrapper').innerHTML = theader + tbody + tfooter;
}

Related

Populating HTML table with Google Sheet data (rows & columns)

Having issues with what it might be a rather easy fix.
Context: My code is currently pulling data from Google Sheets, crafting some sort of table and sending it back to HTML where it repopulates an already existing table.
Issue: I am unable to make it so that it builds columns as well as rows. It pastes the data back all in one go (see image for context).
Files: GS & HTML. I believe the issue is on how I'm crafting the table. I know the current disposition of '' doesn't make sense, bu
HTML table with Gsheet values:
Original Gsheet table:
Google Script
function populateStratTb2(){
var tablerows = SpreadsheetApp.getActive().getSheetByName('supp_str').getRange(1, 5, 1000).getValue();
var tablevalues = SpreadsheetApp.getActive().getSheetByName('supp_str').getRange(4, 1, tablerows).getValues();
var tvlen = tablevalues.length
var active = SpreadsheetApp.getActive();
var sheet = active.getSheetByName("supp_str");
var myRange = sheet.getRange("d3:m" + tvlen);
var data = myRange.getValues();
var optionsHTML = "";
for ( var r = 0; r < 10; r+=1) {
for (var i = 0; i < data.length; i+=1) {
optionsHTML += '<tr><td>' + data[i][r] + '</td></tr>';
}};
return optionsHTML;
}
HTML Script
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(function(){
google.script.run
.withSuccessHandler(displayData)
.populateStratTb2();
});
function displayData(hl){
document.getElementById('strattable').innerHTML=hl;
}
console.log('MyCode');
</script>
PS. I have spent a good couple hours scrolling though the forum picking bits and improving my original code. I am sure this question (or similar) has been answered already but I can't manage to find it.
In your script, how about the following modifications?
Modification 1:
If your for loop is used, how about the following modification?
function populateStratTb2() {
var sheet = SpreadsheetApp.getActive().getSheetByName('supp_str');
var tablerows = sheet.getRange(1, 5, 1000).getValue();
var tablevalues = sheet.getRange(4, 1, tablerows).getValues();
var tvlen = tablevalues.length
var myRange = sheet.getRange("d3:m" + tvlen);
var data = myRange.getValues();
var optionsHTML = "";
for (var r = 0; r < 10; r += 1) {
var row = "";
for (var i = 0; i < data.length; i += 1) {
row += '<td>' + data[i][r] + '</td>';
}
optionsHTML += '<tr>' + row + '</tr>';
}
optionsHTML = '<table border="1" style="border-collapse: collapse">' + optionsHTML + "</table>";
return optionsHTML;
}
I'm worried that your for loop might not be your expected result. So, I would like to proposed one more modified script as "Modification 2".
Modification 2:
If your data is converted to the HTML table, how about the following modification?
function populateStratTb2() {
var sheet = SpreadsheetApp.getActive().getSheetByName('supp_str');
var tablerows = sheet.getRange(1, 5, 1000).getValue();
var tablevalues = sheet.getRange(4, 1, tablerows).getValues();
var tvlen = tablevalues.length
var myRange = sheet.getRange("d3:m" + tvlen);
var data = myRange.getValues();
var optionsHTML = '<table border="1" style="border-collapse: collapse">' + data.reduce((s, r) => s += "<tr>" + r.map(c => `<td>${c}</td>`).join("") + "</tr>", "") + "</table>";
return optionsHTML;
}
Note:
If you don't want to add the border, please modify <table border="1" style="border-collapse: collapse"> to <table>.
From your reply, I added 2 sample scripts for the script for obtaining the same result from reduce and for loop as follows.
reduce
var optionsHTML = '<table border="1" style="border-collapse: collapse">' + data.reduce((s, r) => s += "<tr>" + r.map(c => `<td>${c}</td>`).join("") + "</tr>", "") + "</table>";
for loop
var optionsHTML = "";
for (var r = 0; r < data.length; r++) {
var row = "";
for (var c = 0; c < data[r].length; c++) {
row += '<td>' + data[r][c] + '</td>';
}
optionsHTML += '<tr>' + row + '</tr>';
}
optionsHTML = '<table border="1" style="border-collapse: collapse">' + optionsHTML + "</table>";
Reference:
reduce()

Copy row from any table

I have an HTML page with 3 tables on it. I want to be able to copy specific cells in a table row to the clipboard. The row could come from any of the 3 tables.
Using the code below, I highlight and copy the row for a table with an ID of "final". How do I make this work for any of the 3 tables? I tried by getElementsByTagName and labeling them the same name but did not work - understandably so. Is there a way to designate the selected table? I am trying to avoid copying the whole row and might eventually add the formatted msg to a new page rather than copy to the clipboard.
function copy_highlight_row() {
var table = document.getElementById('final');
var cells = table.getElementsByTagName('td');
for (var i = 0; i < cells.length; i++) {
// Take each cell
var cell = cells[i];
// do something on onclick event for cell
cell.onclick = function () {
// Get the row id where the cell exists
var rowId = this.parentNode.rowIndex;
var rowsNotSelected = table.getElementsByTagName('tr');
for (var row = 0; row < rowsNotSelected.length; row++) {
rowsNotSelected[row].style.backgroundColor = "";
rowsNotSelected[row].classList.remove('selected');
}
var rowSelected = table.getElementsByTagName('tr')[rowId];
rowSelected.style.backgroundColor = "yellow";
rowSelected.className += " selected";
var cellId = this.cellIndex + 1
msg = 'Title: ' + rowSelected.cells[0].innerHTML;
msg += '\r\nDescription: ' + rowSelected.cells[1].innerHTML;
msg += '\n\nLink: ' + rowSelected.cells[2].innerHTML;
msg += '\nPublication Date: ' + rowSelected.cells[3].innerHTML;
//msg += '\nThe cell value is: ' + this.innerHTML copies cell selected
navigator.clipboard.writeText(msg);
}
}
};
Based on a couple of the suggestions I came up with the following:
function highlight_row() {
var cells = document.querySelectorAll('td')
for (var i = 0; i < cells.length; i++) {
// Take each cell
var cell = cells[i];
// do something on onclick event for cell
cell.onclick = function () {
// Get the row id where the cell exists
var rowId = this.parentNode.rowIndex;
var t_ID = this.closest('table').id
var table=document.getElementById(t_ID);
var rowsNotSelected = table.getElementsByTagName('tr');
for (var row = 0; row < rowsNotSelected.length; row++) {
rowsNotSelected[row].style.backgroundColor = "";
rowsNotSelected[row].classList.remove('selected');
}
var rowSelected = table.getElementsByTagName('tr')[rowId];
rowSelected.style.backgroundColor = "yellow";
rowSelected.className += " selected";
var cellId = this.cellIndex + 1
msg = 'Title: ' + rowSelected.cells[0].innerHTML;
msg += '\r\nDescription: ' + rowSelected.cells[1].innerHTML;
msg += '\n\nLink: ' + rowSelected.cells[2].innerHTML;
msg += '\nPublication Date: ' + rowSelected.cells[3].innerHTML;
navigator.clipboard.writeText(msg);
}
}
}
At the end of the html I call the function. The HTML contains 3 tables and this enabled me to click on any table, highlight the row, and copy the correct range of cells.

How do I apply code to a dynamically created element

The following code works only if the table is already present in the document upon page load. I however want it to apply on a dynamically created table.
Can this be done?
var colNumber=22
for (var i=0; i<colNumber; i++)
{
var thWidth=$("#tbl").find("th:eq("+i+")").width();
var tdWidth=$("#tbl").find("td:eq("+i+")").width();
if (thWidth<tdWidth)
$("#tbl").find("th:eq("+i+")").width(tdWidth);
else
$("#tbl").find("td:eq("+i+")").width(thWidth);
}
The table is created in the following way:
function loadFile(event){
alasql('SELECT * FROM FILE(?,{headers:false})',[event],function(data){
var keys = [];
for (var i = 0; i < data.length; i++) {
for (var categoryid in data[i]) {
var category = data[i][categoryid];
keys.push(categoryid);
}
}
keysConverted = keys.map(foo);
var vMin = Math.min.apply(null, keysConverted);
var vMax = Math.max.apply(null, keysConverted);
var start = vMin-1
var ColNeeded = vMax - vMin+1;
var arrExcel2Table = '<table id="tbl">';
for (var i = 0; i < data.length; i++){
arrExcel2Table = arrExcel2Table + '<tr>';
for (var j = 0; j < ColNeeded; j++){
cellValue = data[i][number2Letter(j+start)];
if (typeof cellValue === "undefined"){
cellValue = '';
}
arrExcel2Table = arrExcel2Table + '<td>' + cellValue + '</td>';
}
arrExcel2Table = arrExcel2Table + '</tr>';
}
arrExcel2Table = arrExcel2Table + '</table>';
document.getElementById('excel_table').innerHTML = arrExcel2Table;
});
}
Create a function you want to run and add an event from the dynamic element. For example
arrExcel2Table = arrExcel2Table + '<td>' + cellValue + '</td>';
can be replaced by
arrExcel2Table = arrExcel2Table + '<td onclick="myFunction();">' + cellValue + '</td>';
Above code will call the function you created
myFunction() {
alert();
}
Just create your table, then apply whatever code you want to it :
$('#excel_table').html(arrExcel2Table);
adjustWidth()
function adjustWidth(){
var $tbl = $("#tbl"); // And cache your jQuery objects!! Massive performance boost
for (var i=0; i<colNumber; i++)
{
var $th = $tbl.find("th:eq("+i+")"),
$td = $tbl.find("td:eq("+i+")"),
thWidth = $th.width(),
tdWidth = $td.width();
if (thWidth<tdWidth)
$th.width(tdWidth);
else
$td.width(thWidth);
}
}

Can't create 2 tables

I'm trying to dynamically create a table based on user input, and it's working perfectly, however, it is supposed to make a table based on the super input the user gives, so if super is 2, then it loops to create 2 tables. However it is doing everything but that, because if it was, then the tables would be next to each other, not one below each other as I have set the CSS that way. Any ideas?
<script type="text/javascript">
function createTable()
{
var num_ports = document.getElementById('ports').value;
var num_super = document.getElementById('super').value;
var num_rows = document.getElementById('rows').value;
var num_cols = document.getElementById('cols').value;
var tbody = '';
var colStart = num_cols / num_super;
var y = 1;
for( var i = 1; i <= num_super; i++){
var theader = '<div style="margin:0 auto;"><table border="1" style="border:1px solid black; float:left;">\n';
for(u = 1; u <= num_rows; u++){
tbody += '<tr>';
for( var j = 0; j < colStart; j++)
{
tbody += '<td style="width:80px; height:70px;">';
tbody += '<sub style="float:right; position:relative; top:24px; z-index:11; ">' + y + '</sub>';
tbody += '</td>';
y++;
}
tbody += '</tr>\n';
}
var tfooter = '</table></div>';
document.getElementById('wrapper').innerHTML = theader + tbody + tfooter;
}
}
</script>
<body>
<form name="tablegen">
<label>Ports: <input type="text" name="ports" id="ports"/></label><br />
<label>Super Columns: <input type="text" name="super" id="super"/></label><br />
<label>Rows: <input type="text" name="rows" id="rows"/></label><br />
<label>Columns: <input type="text" name="cols" id="cols"/></label><br/>
<input name="generate" type="button" value="Create Table!" onclick='createTable();'/>
</form>
<div id="wrapper"></div>
</body>
</html>
How it should look
It resets the table it created to the new table in current iteration in this line:
document.getElementById('wrapper').innerHTML = theader + tbody + tfooter;
You have to do something like this:
document.getElementById('wrapper').innerHTML += theader + tbody + tfooter;
In addition to your comment:
var colStart = num_cols / num_super;
Should mabe be:
var colStart = num_cols * num_super;

How to add header for dynamic table

Hello everybody I am drawing dynamic table and I want to add header for table how to add header to dynamic table here is my table code:
$.get('http://myDomain.com/RIA/topIndiaDetails.asp', function(data)
{
console.log("####"+data);
var up = new Image();
var down = new Image();
up.src = "../../jquery.mobile/images/up.png";
down.src = "../../jquery.mobile/images/down.png"
substr = data.split('$');
//alert(substr.length);
//var theader = '<table border="1">\n';
//<table id="auditOverview" border="1">
var theader = '<table border="1" id=\"tableId\">\n';
var tbody = '';
for (var out = 1;out<substr.length-1;out++)
{
//alert(substr[out]);
tbody += '<tr>';
var pra = substr[out].split('|^');
//alert('pra.length is: '+pra.length);
for (var i=0;i<pra.length-1;i++)
{
tbody += '<td>';
if (pra[i]=="Red")
{
pra[i].append("<img id='theImg' src='../../jquery.mobile/images/down.png'/>");
}
else if (pra[i]=="Green")
{
pra[i].append("<img id='theImg' src='../../jquery.mobile/images/up.png'/>");
}
tbody += pra[i];
tbody += '</td>'
}
tbody += '</tr>\n';
}
var tfooter = '</table>';
document.getElementById('wrapper').innerHTML = theader + tbody + tfooter;
});
Any help will be appreciated. Thanks in advance.
You can build your header:
var header = "<th>...</th>";
Then:
$("table").append(header);
if I could get your point correctly
DEMO: http://jsfiddle.net/75zFX/8/
var colheader = '<tr><th>Column1</th><th>Column2</th> .....</tr>\n';
var tbody = colheader ;// and replace with var tbody = '';
If u want to add Header Manually to a Table,use this code.
JSP
<th id="example"></th>
JavaScript
$("#example").html("Header Value");

Categories