I'm very new to JavaScript and HTML I and need some help!
I'm trying to write a table in JavaScript, that writes into the page HTML, and then importing that function to a HTML file to show the table.
I have this in a JavaScript file
function createTable()
{
var table = "<table>";
table += "<tr>";
table += "<th><center>Title</center></th>";
table += "</tr>";
table += "<tr>";
table += "<td><center> data </center></td>";
table += "</tr>";
table += "</table>";
document.write(table);
}
And then I specify the src and call the function in a html file like so:
<head>
<script scr = "source/file.js" type=text/javascript"></script>
</head>
<body>
<script>
createTable()
</script>
</body>
Although this works, I've heard that using document.write() is a very bad practice.
I have tried using table = document.getElementById('tablePrint').innerHTML; and then in the HTML file used <div id="tablePrint"></div> however my table doesn't show. I've also tried document.body.appendChild(table); but that doesn't work either.
Is using document.write() ok? Or is their a better way to write my table to the HTML on screen.
You are missing some double quotes in your example. I'd suggest you to use JQuery:
$(function() { // After the HTML content loads
var table = "<table>";
table += "<tr>";
table += "<th><center>Title</center></th>";
table += "</tr>";
table += "<tr>";
table += "<td><center> data </center></td>";
table += "</tr>";
table += "</table>";
$('body').append(table); // Appends HTML to an element
});
Here is the fiddle.
And here is why document.write() is not a good practice
The write() method is mostly used for testing: If it is used after an
HTML document is fully loaded, it will delete all existing HTML.
Hope it helped :)
The HTML <center> element is obsolete since 1999 when HTML 4 came out. It's abolutely amazing that people (amateurs?) are still trying to use it. Let me cite from the Mozilla article:
This tag has been deprecated in HTML 4 (and XHTML 1) in favor of the CSS text-align property, which can be applied to the <div> element or to an individual <p>. For centering blocks, use other CSS properties like margin-left and margin-right and set them to auto (or set margin to 0 auto).
Normally, we don't use document.write for creating HTML content since it does not allow to control where the content is inserted. Rather, we use suitable DOM attributes (such as innerHTML) and methods (such as appendChild).
The proper way of creating an HTML table and inserting it into the HTML body element is using the DOM methods insertRow and insertCell, as in the following code example:
function createTable() {
var i=0, rowEl=null,
tableEl = document.createElement("table");
// create 10 table rows, each with two cells
for (i=1; i <= 10; i++) {
rowEl = tableEl.insertRow(); // DOM method for creating table rows
rowEl.insertCell().textContent = "table cell "+ i +"-1" ;
rowEl.insertCell().textContent = "table cell "+ i +"-2" ;
}
document.body.appendChild( tableEl);
}
The document.write() method for this purpose is not preferred. The most preferred way to do this with pure JavaScript is to use the appendChild() method.
Try this :
var table = document.createElement("table"); //Creating the <table> element
var tr1 = document.createElement("tr"); //Creating the first <tr> element
var tr2 = document.createElement("tr"); //Creating the second <tr> element
var th = document.createElement("th"); //Creating a <th> element
var td = document.createElement("td"); //Creating a <td> element
var text1 = document.createTextNode("Title"); //Creating the content of <th>
var text2 = document.createTextNode("data"); //Creating the content of <Ttd element
document.body.appendChild(table); //The <body> is adopting the <table>
table.appendChild(tr1); //The <table> is adopting the first <tr>
tr1.appendChild(th); //The first <tr> is adopting the <th>
table.appendChild(tr2); //The <table> is adopting the second <tr>
tr2.appendChild(td); //The second <tr> is adopting the <td>
th.appendChild(text1); //<th> is adopting its content
td.appendChild(text2); //<td> is adopting its content
<center> tag is deprecated now, don't use it, use CSS instead.
Working demo
Have your function return the table as a string.
function createTable()
{
var table = "<table>";
table += "<tr>";
table += "<th><center>Title</center></th>";
table += "</tr>";
table += "<tr>";
table += "<td><center> data </center></td>";
table += "</tr>";
table += "</table>";
return table;
}
Assuming you don't want to overwrite the body completely create a div have it styled the way you want and just add the table content there.
<body>
<div id="table"></div>
<script>
var table=createTable();
document.getElementById("table").innerHTML=table;
</script>
</body>
Related
After looping the delete button, I've been trying to get the id so that I can use it with the onclick function but no luck yet.
var table = "";
res.data.forEach((value, key) => {
table += "<tr>";
table += "<td>"+value.post_held+"</td>";
table += "<td>"+value.established_officer+"</td>";
table += "<td>"+value.date_of_commencement+"</td>";
table += "<td>"+value.date_of_termination+"</td>";
table += "<td><button id=career"+value.id+" class='btn btn-danger'>Delete</button></td>";
table += "</tr>";
var career = document.querySelector("#career"+value.id);
career.addEventListener("click",()=>{
alert("done")
})
});
I think maybe you forgot to add table to DOM.
You just create a string value which contain html code, but you didn't add this html code into the DOM, so you can not find this DOM element by id.
You can use insertAdjacentHTML method to add this element which you want to DOM
I have a table body object stored as a string. I've tried setting an HTML table using javascript to be that string as follows (the {{}} are because I'm using Flask to get the string):
Way 1:
document.getElementsByTagName("tbody")[0].outerHTML= "{{tbody_string }}";
Way 2:
document.getElementsByTagName("table")[0].outerHTML = '<table>' + "{{tbody_string }}" + '</table>'
Way 3:
document.getElementsByTagName("table")[0].innerHTML = "{{tbody_string}}";
None of these is working. Instead, the table is created and is storing tbody_string as actual text content instead of treating it as html. I've used these sort of structures and flask variables with other HTML elements such as input and it works fine, but it's not seeming to work with table. Thoughts?
Extra Info:
The string looks like this:
'<tbody> <tr> <td>Name</td> <td> <input type="text" name="parameters_name" id="name" class="form-control"> </td> </tr> </tbody>'
The outer quotes are simply shown here to indicate it's a string.
Jinga2 is probably escaping your html when you render it with {{tbody_string}}. You can tell it not to do that with {{tbody_string|safe}}.
Ultimately you can get rid of your "javascript ways" entirely and just render it directly with Jinja2.
Also...please note that if there is any user editable data in your tbody_string, you'll want to take the necessary precautions to avoid creating a security loophole.
Here is javascript code for table
var body = document.getElementsByTagName("body")[0];
var ourTable = document.createElement("table");
var ourTableBody = document.createElement("tbody");
for (var i = 0; i < 4; i++) {
var row = document.createElement("tr");
for (var j = 0; j <2; j++) {
var cell = document.createElement("td");
var cellText = document.createTextNode("cell in row "+i+", column "+j);
cell.appendChild(cellText);
row.appendChild(cell);
}
ourTableBody.appendChild(row);
}
ourTable.appendChild(ourTableBody);
body.appendChild(ourTable);
ourTable.setAttribute("border", "2");
If your table body object stored as a string (aka tbody_string) is a string that goes something like tbody_string = "<table><tr><th>table</th></td></table>"
Way 3 should work fine
<html>
<body>
<table>
<tr>
<th>Replace this table</th>
</tr>
</table>
</body>
<script lang="javascript">
const tbody_string = `
<table>
<tr>
<th>Table</th>
</tr>
<tr>
<td>this is replaced table</td>
</tr>
</table>`;
document.getElementsByTagName('table')[0].innerHTML = tbody_string;
</script>
</html>
However, if your tbody_string isn't HTML markup text but something else.
you'll need to convert it to HTML as text somehow. if it's a DOM element object, the following code should work:
document.getElementsByTagName('table')[0].innerHTML = table_dom.innerHTML
What I'm trying to do:
Get every value from a spreadsheet (6 columns, ~10+ rows)
I can get the values. I will probably get each column individually with .getRange(row, column, sheet.getLastRow() - 1, 1).getValues();. Or I could get every single value with .getDataRange().getValues() and then put them in the table that way?
Or would it be better to just use a for loop? -- example at very bottom
Return those values [as Templated HTML?] surrounded by <table>, <tr>, <th>, <td> code -- example below
Display the table with the values on a web app when a name gets
clicked
Can the inserted <table> code start as style="display: none;", and then when the name gets clicked, have the table show? Or have it in a div that is invisible then visible once clicked?
Example of table:
<table>
<tr>
<th>header1</th>
<th>header2</th>
<th>header3</th>
<th>header4</th>
<th>header5</th>
<th>header6</th>
</tr>
<tr>
<td>value1</td>
<td>value2</td>
<td>value3</td>
<td>value4</td>
<td>value5</td>
<td>value6</td>
</tr>
//etc
</table>
I dont know if what I'm trying to do counts as Templated HTML or not, or if it would be better to do this using Templated Html...
The big thing I need help with is returning every value in a table and displaying it on the web app.
Example of for loop
If I do a for loop and return every value in a column or a row
column1[i]
column2[i]
etc
or
row1[i]
row2[i]
etc
How would I return those values as a table?
Would it be something like:
var x = "<tr>";
var y = row1[i];
var z = "</tr>";
return x + y + z
If so, how would I make a whole table out of all the row/column values?
Also, how would I style the table with css once it's fully built? I'm assuming I can still add an id to the table and style it from there.
I don't know the exact number of rows there will be in the spreadsheet, so making this dynamic would be best -- probably getting all the rows instead of columns and using a for loop for each row?
Any help would be appreciated. Thanks.
If I wanted to add another column to the table (not in the spreadsheet), how would I go about doing that? I'm trying to add an add row button to the header row, and a delete row button on the end of every row of table data.
Also, I know that you can set the <td> to <td contenteditable='true'>... but, how would I have it where the data is only editable on a newly added row AND the table cell cant be edited once a value is submitted? -- Would I need an event listener or some trigger that sees when a value is inputted and triggers that cell to contenteditable='false'?
Thanks again.
You can use a nested for loop.
var range = SpreadsheetApp.getActiveSpreadsheet().getDataRange().getValues();
var isHeader = true;
var html = "<table>\n";
for (var i = 0; i < range.length; i++) {
html += "<tr>\n";
for (var j = 0; j < range[i].length; j++) {
if (isHeader) {
html += "<th>" + range[i][j] + "</th>\n";
}
else {
html += "<td>" + range[i][j] + "</td>\n";
}
}
isHeader = false;
html += "</tr>\n";
}
html += "</table>";
I've taken a look at table and table body methods, and it does not mention how to insert a HTMLTableRowElement. Anyone know a nice way to insert a HTMLTableRowElement into the table body?
const tbody = document.getElementsByTagName('tbody')[0];
// Only inserts an empty row
// Want to insert a HTMLTableRowElement that I've parsed using jsdom
tbody.insertRow();
EDIT:
With guidance #frontend_dev, it looks like jsdom is not using native DOM elements. So the solution may look something like the follow:
let rows_rep = '';
jsdom.env(html_with_tr, function(err, w) {
rows_rep = w.document.getElementsByTagName('tr')[0].outerHTML;
}
const tbody = document.getElementsByTagName('tbody')[0];
const newRow = tbody.insertRow();
newRow.innerHTML = rows_rep;
Given an HTML string containing the row you want to add, you can get that row without jsdom and append it to a table in the current document:
// Sample HTML string:
var html = `<html>
<body>
<h1>my title</h1>
<table><tr><td>dynamicly added row</td></tr></table>
<p>other text in here</p>
</body>
</html>`;
// Create in-memory element and load HTML into it:
var span = document.createElement('span');
span.innerHTML = html;
// Get the row element out of it, and append it:
var tr = span.querySelector('tr');
var tbody = document.querySelector('tbody');
tbody.appendChild(tr);
<table border=1>
<tr><td>existing row</td></tr>
</table>
I am using websockets (socket.io) for real-time stuff, and it may be that a new item is added to a collection which I would like to then add to the screen. Is there a good way to add a row to an HTML table without re-rendering the whole view?
You can use insertRow on that table. Here is an example:
<table id="TableA">
<tr>
<td>Old top row</td>
</tr>
</table>
<script type="text/javascript">
function addRow(tableID) {
// Get a reference to the table
var tableRef = document.getElementById(tableID);
// Insert a row in the table at row index 0
var newRow = tableRef.insertRow(0);
// Insert a cell in the row at index 0
var newCell = newRow.insertCell(0);
// Append a text node to the cell
var newText = document.createTextNode('New top row');
newCell.appendChild(newText);
}
// Call addRow() with the ID of a table
addRow('TableA');
</script>
Example taken from the Mozilla page for insertRow.