Reputation: 127
I'm trying to add rows in the table id="main-table-body"
by addRow()
function call faced the problem that document.getElementById()
retrieved undefined
.
Browsing Stackoverflow I found a couple of similar questions but the suggested solutions don't work out in my case. I suppose the problem is that at the moment of function execution the html document is not created yet. But even if I put script below the body-tags nothing happens. I would appreciate a lot if you give me an idea what to do.
HTML:
<html>
<head>
<meta http-equiv="content-type" content="text/html" charset="utf-8">
<title>Billing system</title>
<link rel="stylesheet" href="css/style.css" type="text/css">
<script src="scripts.js"></script>
</head>
<body>
<div id="header">
<table id="contractor-info">
<tbody>
<tr><td>Contractor</td><td></td></tr>
<tr><td>Contract No</td><td></td></tr>
<tr><td>Balance</td><td></td></tr>
<tr><td>Orders in progress</td><td></td></tr>
</tbody>
</table>
</div>
<div id="sidebar">
<div id="sidebar-buttons">
<input type="button" id="add-contractor" value="Add contractor"><br>
<input type="button" id="remove-contractor" value="Remove contractor"><br>
<input type="button" id="edit-contractor" value="Edit contractor"><br>
</div>
<div id="sidebar-list">
<form>
<select size="50">
<option>Contractor #1</option>
<option>Contractor #2</option>
<option>Contractor #3</option>
</select>
</form>
</div>
</div>
<div id="content">
<input type="button" name="add-order" value="Add order">
<input type="submit" name="submit-order" value="Submit changes">
<input type="button" name="add-payment" value="Add payment">
<input type="submit" name="submit-payment" value="Submit changes">
<table id="main-table" contenteditable="true">
<thead>
<tr>
<th>Contract No</th>
<th>Order No</th>
<th>Order date</th>
<th>Order Amount</th>
<th>Invoice No</th>
<th>Invoice date</th>
<th>Invoice amount</th>
<th>Cleared</th>
</tr>
</thead>
<tbody id="main-table-body">
<tr>
</tr>
</tbody>
</table>
<table id="payments-table">
<thead>
<tr>
<th>Amount</th>
<th>Date of payment</th>
<th>Details</th>
</tr>
</thead>
<tbody id="payments-table-body">
</tbody>
</table>
</div>
</body>
<script>
addRow();
</script>
</html>
JS:
var contentButtons = document.getElementById('content');
var parentElementMainTable = document.getElementById('main-table-body');
contentButtons.onclick = function(event) {
var event = event || window.event;
var target = event.target || event.srcElement;
if(target.getAttribute('name') == 'add-order') {
addRow();
}
}
function addRow() {
var tr = document.createElement('TR');
tr.innerHTML = '<tr> \
<td></td> \
<td></td> \
<td></td> \
<td></td> \
<td></td> \
<td></td> \
<td></td> \
<td></td> \
</tr>';
parentElementMainTable.appendChild(tr);
}
Upvotes: 5
Views: 44407
Reputation: 188
I think you must assign your values in the onload function to be sure that the elements are already loaded. I also modify a bit your HTML to add ID on button and the final / before closing the tag (if one day you add an XHTML doctype) :
<input type="button" name="add-order" value="Add order" />
And the JS code :
// List of global variables
var parentElementMainTable = null;
var addOrderBtn = null
// Equivalent to <body onload="yourFunction();">
window.onload = function(){
// Init globals
parentElementMainTable = document.getElementById('main-table-body');
addOrderBtn = document.getElementById("add-order");
// Add the onclick function to add rows in table
addOrderBtn.onclick = function(){
addRow();
}
}
// Add a row in table
function addRow() {
var tr = document.createElement('TR');
tr.innerHTML = '<td></td> \
<td /> \
<td /> \
<td /> \
<td /> \
<td /> \
<td /> \
<td />';
parentElementMainTable.appendChild(tr);
}
Dont forget : innerHTML means all tag inside the one you're writing. You're appending TD in your TR. No need to write your TR inside your innerHTML.
EDIT : If you want to continue playing with the DOM, try this addRow function instead of the other one (you start with the DOM createElement, try to continue with it) :
// Add a row in table
function addRow() {
// Create the row element
var tr = document.createElement("tr");
// Loops on the number of columns in your thead
// Then creates and append new cell in row
for (var i = 0; i < parentElementMainTable.offsetParent.tHead.rows[0].cells.length; i++) {
var td = document.createElement("td");
tr.appendChild(td);
}
// Append the final row to the table
parentElementMainTable.appendChild(tr);
}
Upvotes: 3
Reputation: 23396
Assuming your code was originally structured like below (near which it was before the edit, I've moved it back within body
and added the script
tags though.):
<script>
addRow();
</script>
<script>
var contentButtons = document.getElementById('content');
var parentElementMainTable = document.getElementById('main-table-body');
contentButtons.onclick = function(event) {...};
function addRow() {...};
</script>
</body>
</html>
Inline scripts are executed in order of appearance. When you have addRow()
call within it's own script
tag, the said function is invoked before it exists, hence the error.
Actually the error message tells you that "addRow is undefined.
" (depending on the browser also could be "addRow is not a function.
")
The simplest fix is to remove the ending-starting script tag pair after addRow()
, this way function and variable declarations will be hoisted, and the call works even from a "wrong" place.
However, it's better to remove the first script
totally, and move addRow()
to the end of the code.
Please notice also what I've said about innerHTML
of tr
s in my comment in the thread below your question.
Upvotes: 0
Reputation: 477
I'd be willing to bet that when you create parentElementMainTable, the DOM isn't ready yet, so parentElementMainTable is undefined when you try to call "addRows".
Can you try removing this variable from where you have it, and add it to your "onclick" method?
var parentElementMainTable = document.getElementById('main-table-body');
Then your addRow function would do this:
function addRow() {
var tr = document.createElement('TR');
tr.innerHTML = '<tr> \
<td></td> \
<td></td> \
<td></td> \
<td></td> \
<td></td> \
<td></td> \
<td></td> \
<td></td> \
</tr>';
document.getElementById('main-table-body').appendChild(tr);
}
Upvotes: 0