What I am trying to do is on button press I will add 4 text elements, each text element in its own cell; beneath its corresponding column. Eg. "Name" column will have the name of the product beneath it. Refer to picture attached below.
My problem is - On button press my 4 elements are created but only one cell is created and it has all 4 of my elements in it. If someone could help me find the solution that would be amazing!
Relevant code attached below.
<div id="inventory">
<!--Here is where we shall store our data-->
<table class="table">
<tr class="head-row">
<th class="table-head">Name</th>
<th class="table-head">Price</th>
<th class="table-head">ID</th>
<th class="table-head">Quantity</th>
</tr>
<div>
Javascript:
//Items
let items = [
["chips",25,3163,1],
["Pork", 25 , 316 , 1],
["Crackers",5,400,1]
];
addButton.addEventListener('click', addItem);
function addItem(){
let table = document.querySelector(".table");
let row = document.createElement('tr');
row.classList.add("row");
let cell = document.createElement('td');
cell.classList.add('item-properties')
//Create our table item
items[1].forEach(itemProperty =>{
let textNode = document.createTextNode(itemProperty);
cell.appendChild(textNode);
row.appendChild(cell);
});
table.appendChild(row);
}
You need a td element for each value.
//Items
let items = [
["chips", 25, 3163, 1],
["Pork", 25, 316, 1],
["Crackers", 5, 400, 1]
];
document.getElementById('add').addEventListener('click', addItem);
function addItem() {
let table = document.querySelector(".table");
let row = document.createElement('tr');
row.classList.add("row");
let cell = document.createElement('td');
cell.classList.add('item-properties')
//Create our table item
items[1].forEach(itemProperty => {
let td = document.createElement('td');
let textNode = document.createTextNode(itemProperty);
td.appendChild(textNode);
row.appendChild(td);
});
table.appendChild(row);
}
<button id="add">Add</button>
<div id="inventory">
<!--Here is where we shall store our data-->
<table class="table">
<tr class="head-row">
<th class="table-head">Name</th>
<th class="table-head">Price</th>
<th class="table-head">ID</th>
<th class="table-head">Quantity</th>
</tr>
</table>
</div>
I got the problem all solved!
Just had to create the cell variable inside the forEach loop, so now it will loop through and create a cell each time- then add my textNode to that cell. If anyone has any pointers or alternate solutions more than happy to hear!
function addItem(){
let table = document.querySelector(".table");
let row = document.createElement('tr');
row.classList.add("row");
//Create our table item
items[1].forEach(itemProperty =>{
let textNode = document.createTextNode(itemProperty);
cell = document.createElement('td'); //ADDED THIS
cell.appendChild(textNode);
row.appendChild(cell);
console.log(itemProperty);
});
table.appendChild(row);
}
Related
I am trying to insert another row into a table with footer.
Here is my code:
function submit(){
/* Some code here with declarations & value assignings*/
let tble = document.getElementById("tabl");
let newEl = document.createElement("tr");
newEl.innerHTML="<td>"+nowSr+"</td> <td>"+taskForm+"</td> <td>"+tagForm+"</td> <td>Rs. "+amountForm+"</td>";
tble.appendChild(newEl, tble.lastElementChild.previousSibling.lastElementChild);
}
My function gives me below result:
As you can see (IN INSPECT ELEMENTS WINDOW) the new row is inserted after the footer. How to add it properly
after the last row in the table?
Don't insert the element directly to the <table> element, but select the <tbody> instead.
You can do that like that:
function submit(){
let tble = document.getElementById("tabl");
let newEl = document.createElement("tr");
newEl.innerHTML="<td>"+nowSr+"</td> <td>"+taskForm+"</td> <td>"+tagForm+"</td> <td>Rs. "+amountForm+"</td>";
tble.querySelector('tbody').appendChild(newEl, tble.lastElementChild.previousSibling.lastElementChild);
}
But you shouldn't use innerHTML to create the row (it could create an XSS vulnerability), use innerText or textContent instead. But that means that you have to create the <td>s differently:
function submit(){
let tble = document.getElementById("tabl");
let newEl = document.createElement("tr");
appendTD(newEl, nowSr);
appendTD(newEl, taskForm);
appendTD(newEl, tagForm);
appendTD(newEl, "Rs. "+amountForm);
tble.querySelector('tbody').appendChild(newEl, tble.lastElementChild.previousSibling.lastElementChild);
}
function appendTD(tr, text){
const td = document.createElement('td')
td.innerText = text
tr.appendChild(td)
}
Try puhsing to the tbody intead of the table directly
function addTableRow(){
const tbody = document.querySelector('#myTable tbody')
const newRow = document.createElement('tr')
newRow.innerHTML = `<td>Foo</td><td>Bar</td>`
tbody.appendChild(newRow)
}
<table id="myTable">
<thead>
<tr>
<th>Helo</th>
<th>World</th>
</tr>
</thead>
<tbody>
<tr>
<td>Foo</td>
<td>bar</td>
</tr>
</tbody>
</table>
<button onclick="addTableRow()">Add row</button>
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/
This is the code I have done so far. I want to hyperlink the websites so that when the array is outputted as a table in HTML, the websites will be clickable and link to their respective webpages. For some reason, the code in type="text/javascript" is different from the code in language="JavaScript" and I have no idea why. If someone could provide the code for language="JavaScript" that would be greatly appreciated!
HTML:
<table id="table">
<tr id="tbody">
<th>Mattress Type</th>
<th>Link</th>
</tr>
</table>
JAVASCRIPT:
<script language="JavaScript">
var table = document.getElementById("table");
var body = document.createElement("tbody");
var beds = new Array(3);
beds[0] = ["Spring Mattress", "King Size", "http://factorymattresstexas.com/specials/spring-air/"];
beds[1] = ["Rest Lumbar Support", "Queen Size", "http://factorymattresstexas.com/specials/beautyrest-lumbar-support"];
beds[2] = ["Beauty Rest", "Twin Size", "http://factorymattresstexas.com/specials/simmons-beautyrest/"];
table.appendChild(tbody);
beds.forEach(function(items) {
var row = document.createElement("tr");
items.forEach(function(item) {
var cell = document.createElement("td");
cell.textContent = item;
row.appendChild(cell);
});
table.appendChild(row);
});
</script>
You're almost there. You just need to continue adding child elements:
var table = document.getElementById("table");
var body = document.createElement("tbody");
// initialize an empty array
var beds = [];
// add bed objects to the array
beds.push({
type: "Spring Mattress",
size: "King Size",
link: "http://factorymattresstexas.com/specials/spring-air/"
});
beds.push({
type: "Rest Lumbar Support",
size: "Queen Size",
link: "http://factorymattresstexas.com/specials/beautyrest-lumbar-support"
});
beds.push({
type: "Beauty Rest",
size: "Twin Size",
link: "http://factorymattresstexas.com/specials/simmons-beautyrest/"
});
table.appendChild(tbody);
beds.forEach(function(item) {
var row = document.createElement("tr");
// You were previously just dumping the whole array contents in a cell. Most likely you want to have separate cells for each type of information.
var type = document.createElement("td");
type.textContent = item.type;
var size = document.createElement("td");
size.textContent = item.size;
// Create the containing cell to hold the link
var link_td = document.createElement("td");
// Create the ... element
var link = document.createElement("a");
link.textContent = item.link;
link.href = item.link
// Add the link to the cell
link_td.appendChild(link);
// Add the cells to the row in the order you'd like to see them in
row.appendChild(type);
row.appendChild(size);
row.appendChild(link);
table.appendChild(row);
});
<table id="table">
<tr id="tbody">
<th>Mattress Type</th>
<th>Size</th>
<th>Link</th>
</tr>
</table>
Update:
Your beds array was an array of array of strings. I switched this to use an array of bed objects. This allows you to define properties and reference those properties by name instead of by index (ie item.size vs item[1]). This is cleaner and will scale better as your codebase grows. You can extend the bed object with additional properties that you want to display.
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 am using Javascript to dynamically create a table, and want to make a header-style cell at the beginning of each row. So my question is how I can do this, seeing as insertCell creates only a normal <td> element and not a <th>.
Some things I've tried (via the Tryit editor at w3schools; I have no reason to suspect that any other usage will behave differently) and didn't work:
I've seen a suggestion to create the <th> element independently and then add it to the <tr> element as a child. When I do this, however, it is not added as a table cell, i.e. it is not affected by the table border, does not count toward the array of cells (i.e. if you do insertCell(1), it inserts after the first cell not counting the <th>), and does not get the special bold/center format for a <th> cell.
I've attempted to use insertCell to make a dummy cell and then replaceChild with an independently created cell; this had the same result as above.
I've tried to make a <td> cell via insertCell and simply bold and center it manually, but myCell.style.fontWeight="bold" and myCell.align="center" don't seem to work (they just end the function, as bad commands do in JavaScript), and likewise trying to use CSS doesn't work. So maybe I just have bad syntax or something, but I've got no clue what to do. Any help would be appreciated.
Attempt 1:
<!DOCTYPE html>
<html>
<body>
<p>Click the button to insert new cell(s) at the end of the table row.</p>
<table border="1">
<th>1</th>
<td>2</td>
</tr>
<tr id="myRow">
</tr>
<tr>
</table><br>
<button onclick="myFunction()">Try it</button>
<script>
function myFunction()
{
var newRow = document.getElementById("myRow");
var header=document.createElement("th").appendChild(document.createTextNode("a"));
newRow.appendChild(header);
var enablesLoc=newRow.insertCell(0).appendChild(document.createTextNode("b"));
}
</script>
</body>
</html>
Result: "1" is bolded with a border, "2" and "b" are unbolded with a border (as they should be), "a" is unbolded with no border.
Attempt 2:
<!DOCTYPE html>
<html>
<body>
<p>Click the button to insert new cell(s) at the end of the table row.</p>
<table border="1">
<th>1</th>
<td>2</td>
</tr>
<tr id="myRow">
</tr>
<tr>
</table><br>
<button onclick="myFunction()">Try it</button>
<script>
function myFunction()
{
var newRow = document.getElementById("myRow");
var header=newRow.insertCell(0).appendChild(document.createTextNode("a"));
header.style.fontWeight="bold";
var enablesLoc=newRow.insertCell(1).appendChild(document.createTextNode("b"));
}
</script>
</body>
</html>
Result: The button adds cell "a" unbolded but not cell "b".
The following code shows everything that should get you going:
function addTable(){
var table = document.createElement("table");
var tr = document.createElement("tr");
var th = document.createElement("th");
var td = document.createElement("td");
td.innerText = "im a td";
th.innerText = "im a th";
tr.appendChild(th);
tr.appendChild(td);
table.appendChild(tr);
var out = document.getElementById("out");
out.appendChild(table);
}
You have to call the function and an div with id out <div id=out>...</div> must be in the document. Disclaimer: i only tested this code in chrome
Update to address your points
You wrote I've seen a suggestion to create the <th> element independently and then add it to the <tr> element as a child. When I do this
it is not added as a table cell what do you mean by that and what command are you using,
is not affected by the table border the reason could be because it contains not text,
does not count toward the array of cells (i.e. if you do insertCell(1) i do not understand this either. According to the specs on insertCell it insert an empty td and returns a reference. So insertCell has no array, If you try var table = document.getElementById("myTable") and then table.rows[0].cells.length it returns the number of cells including the th-cell.
it inserts after the first cell not counting the th according on my tests at least in chrome this is not the case; it depends on how you call the method: table.rows[1].insertCell(-1); adds a cell at the second row (zero based array) at the end and table.rows[2].insertCell(1); adds in the third row a cell on position 2 (again zero based) if you use table.rows[3].insertCell(0); the cell is inserted into the 4th. row at the beginning,
and does not get the special bold/center format for a th cell this was not the case for me as well
Disclaimer: i only tested this code in chrome
The html
<button onclick="addRow()">add rows</button><br />
<button onclick="addColumn()">add column</button>
<table border="1" id="myTable">
<tr>
<th>1</th>
<td>2</td>
</tr>
</table>
And the javascript
function addRow()
{
var table = document.getElementById("myTable");
var tr = document.createElement("tr");
var th = document.createElement("th");
var td = document.createElement("td");
td.innerText = "im a td";
th.innerText = "im a th";
tr.appendChild(th);
tr.appendChild(td);
table.appendChild(tr);
}
function addColumn(){
var table = document.getElementById("myTable");
var rows = table.rows;
console.log("rows", rows);
for (var i = 0; i < rows.length; ++i) {
// td = rows[i].cells;
var td = document.createElement("td");
td.innerText = i;
rows[i].appendChild(td);
}
}
Based on DOM Level 2 HTML you can not use insertCell since it Insert[s] an empty TD cell into this row. But you want to add a th
According to DOM Level 3 Core you can use appendChild since it adds the node newChild to the end of the list of children of this node. If the newChild is already in the tree, it is first removed.
So therefore you have to create the elements in the right order: create the row, add the first cell as th then add other cells as td by using append child.
You may take a look at a demo of the above code
The .appendChild() method returns the element being appended. Which means on this line:
var header=document.createElement("th").appendChild(document.createTextNode("a"));
...your header variable is actually the text node, not the th element - so then newRow.appendChild(header); appends just the text node to the row, not the new th.
Try something like this instead:
var newRow = document.getElementById("myRow");
var header = document.createElement("th");
header.appendChild(document.createTextNode("a"));
newRow.appendChild(header);
Demo: http://jsfiddle.net/PtzRL/
Note that if you actually want to append new rows then your newRow variable should not be getting a reference to an existing row in the table, you should give an id to the table:
<table id="myTable">
...and then create a new row and add that to the table:
var table = document.getElementById("myTable");
var newRow = document.createElement("tr");
table.appendChild(newRow);
Demo: http://jsfiddle.net/PtzRL/1/
(Note also that the starting html you show has an error: you're missing the first <tr> just after the <table> tag, and you have an extra <tr> just before the closing </table> tag.)
Is this what you were trying to do?
function myFunction = function() {
var newRow, newHeader, newCell;
newRow = document.getElementById("myRow");
newHeader = document.createElement("th");
newHeader.innerText = "a";
newRow.appendChild(newHeader);
newCell = document.createElement("td");
newCell.innerText = "b";
newRow.appendChild(newCell);
}
If you want the button to add new rows rather than filling in a blank row you put there already, try something like this:
HTML:
<body>
<table id="myTable" border="1">
<tr>
<th>1</th>
<td>2</td>
</tr>
</table>
<button onclick="myFunction()">Try it</button>
</body>
JavaScript:
function myFunction = function() {
var myTable, newRow, newHeader, newCell;
myTable = document.getElementById("myTable");
newRow = document.createElement("tr");
newHeader = document.createElement("th");
newHeader.innerText = "a";
newRow.appendChild(newHeader);
newCell = document.createElement("td");
newCell.innerText = "b";
newRow.appendChild(newCell);
myTable.appendChild(newRow);
}
The function need to altered like this I believe...
function myFunction()
{
var newRow = document.getElementById("myRow");
var header=document.createElement("th");
header.appendChild(document.createTextNode("a"));
newRow.appendChild(header);
var enablesLoc=newRow.insertCell(0);
enables.appendChild(document.createTextNode("b"));
}