I want to manipulate (add/delete rows) for two tables in html using JavaScript. With one it works, but if I add the second one I get this error:
Uncaught TypeError: Cannot set property 'innerHTML' of null
More precisely: I want to have two tables each with different content based on which button is clicked.
With one table it worked. The first function deleted table content -> added new content. Second function the same, deleted content from first table -> added its new content.
But I want to do this with two tables. Please let me know how it should be done.
function First(tableID, tableID2) {
let table = document.getElementById(tableID)
table.innerHTML = ""; // here is the mentioned error.
// I would like to have something like..
// let table2 = document.getElementById(tableID2)
// table2.innerHTML = "";
}
<p>Click the button to add a new row at the first position of the table and then add cells and content</p>
<table id="myTable">
<TR>
</TR>
</table>
<table id="myTable2">
<TR>
</TR>
</table>
<br>
<button type="button" id="first" onclick="First(myTable, myTable2)">First</button>
<button type="button" id="second" onclick="Second(myTable, myTable2)">Second</button>
If you don't wrap myTable and myTable2 in quotations, JavaScript assumes it is an object. Since you didn't define myTable nor myTable2, they are null. You can't modify the innerHTML of null, and thus you get the error "Cannot set property 'innerHTML' of null".
In the example below, the names are wrapped in quotations which makes it a String:
function First(tableID, tableID2) {
let table = document.getElementById(tableID)
table.innerHTML = "<tr>first</tr>"; // here is the mentioned error.
let table2 = document.getElementById(tableID2)
table2.innerHTML = "<tr>first again</tr>";
}
function Second(tableID, tableID2) {
let table = document.getElementById(tableID)
table.innerHTML = "<tr>second</tr>"; // here is the mentioned error.
let table2 = document.getElementById(tableID2)
table2.innerHTML = "<tr>second again</tr>";
}
<p>Click the button to add a new row at the first position of the table and then add cells and content</p>
<table id="myTable">
<TR>
</TR>
</table>
<table id="myTable2">
<TR>
</TR>
</table>
<br>
<button type="button" id="first" onclick="First('myTable', 'myTable2')">First</button>
<button type="button" id="second" onclick="Second('myTable', 'myTable2')">Second</button>
Alternatively, you could define the two variables before they are referenced:
function First(tableID, tableID2) {
let table = document.getElementById(tableID)
table.innerHTML = "<tr>first</tr>"; // here is the mentioned error.
let table2 = document.getElementById(tableID2)
table2.innerHTML = "<tr>first again</tr>";
}
function Second(tableID, tableID2) {
let table = document.getElementById(tableID)
table.innerHTML = "<tr>second</tr>"; // here is the mentioned error.
let table2 = document.getElementById(tableID2)
table2.innerHTML = "<tr>second again</tr>";
}
<p>Click the button to add a new row at the first position of the table and then add cells and content</p>
<table id="myTable">
<TR>
</TR>
</table>
<table id="myTable2">
<TR>
</TR>
</table>
<br>
<script>
var myTable = 'myTable';
var myTable2 = 'myTable2';
</script>
<button type="button" id="first" onclick="First(myTable, myTable2)">First</button>
<button type="button" id="second" onclick="Second(myTable, myTable2)">Second</button>
just add some quotation mark on your args when calling your function. Otherwise, javascript think "myTable" is a variable, which doesn't exists.
<button type="button" id="first" onclick="First('myTable', 'myTable2')">First</button>
Were you trying to use just one function to edit both tables? Here's a version of that. Just pass in the ID of the table with a string.
function eTable(tableID) {
let table = document.getElementById(tableID)
let row = table.insertRow(0);
let cell = row.insertCell(0);
cell.innerHTML = "New cell for " + tableID;
}
<p>Click the button to add a new row at the first position of the table and then add cells and content</p>
Table 1:
<table id="myTable">
<TR>
</TR>
</table>
Table 2:
<table id="myTable2">
<TR>
</TR>
</table>
<br>
<button type="button" id="first" onclick="eTable('myTable')">First</button>
<button type="button" id="second" onclick="eTable('myTable2')">Second</button>
Related
I'm trying to get two buttons to switch between 2 tables with javascript, but whenever i test, both of the tables appear instead of just one
var table1 = document.getElementById("table1");
var table2 = document.getElementById("table2");
var btnTab1 = document.getElementById("showTable1");
var btnTab2 = document.getElementById("showTable2");
btnTab1.onclick = function() {
table1.style.display = "table";
table2.style.display = "none";
}
btnTab2.onclick = function() {
table1.style.display = "none";
table2.style.display = "table";
}
<table id=table1>
<table id=table2>
<input type="button" id="showTable1" value="Table 1">
<input type="button" id="showTable2" value="Table 2">
I expect 1 table to be showing at a time and the button to switch between them, but instead they both show at the same time and the buttons dont do anything
var table1 = document.getElementById("table1");
var table2 = document.getElementById("table2");
var btnTab1 = document.getElementById("showTable1");
var btnTab2 = document.getElementById("showTable2");
btnTab1.onclick = function() {
table1.style.display = "table";
table2.style.display = "none";
}
btnTab2.onclick = function() {
table1.style.display = "none";
table2.style.display = "table";
}
#table2 {
display: none;
}
<table id="table1">
<tr>
<td>Table1</td>
</tr>
</table>
<table id="table2">
<tr>
<td>Table2</td>
</tr>
</table>
<input type="button" id="showTable1" value="Table 1">
<input type="button" id="showTable2" value="Table 2">
Your code is right but you just forgot to initialize the display on your tables and to close the table tags :
(I added some content so we see which table is visible)
var table1 = document.getElementById("table1");
var table2 = document.getElementById("table2");
var btnTab1 = document.getElementById("showTable1");
var btnTab2 = document.getElementById("showTable2");
btnTab1.onclick = function() {
table1.style.display = "table";
table2.style.display = "none";
}
btnTab2.onclick = function() {
table1.style.display = "none";
table2.style.display = "table";
}
<table id=table1 style="display: table">
<thead>
<tr>
<th colspan="2">The table header 1</th>
</tr>
</thead>
</table>
<table id=table2 style="display: none">
<thead>
<tr>
<th colspan="2">The table header 2</th>
</tr>
</thead>
</table>
<input type="button" id="showTable1" value="Table 1">
<input type="button" id="showTable2" value="Table 2">
I'm replacing your tables with divs, because it's easier to show the thought behind the code with less clutter.
You can add listeners directly onto the buttons, and by doing that, it's easier to send in parameters. I made something a little bit more dynamic, where it's possible to add any number of tables with ease without having to change the code. All you need to do is change the parameter in showTable('table2') to showTable('table3') in the button.
This solutions wont demand as many variables, and it's not dependent on whether the page has loaded or not. Like #brianfit said, you're probably having your javascript code in the head element which means that the document doesn't exist when the code runs, and you can't therefor find any elements on the page.
I also think it's better to use classes to style elements, rather changing the style in code. The semantics looks better, and you get IMHO a better understanding of why some tables are hidden.
function showTable(tableIdToShow) {
hideAllTables();
let tableElement = document.getElementById(tableIdToShow);
tableElement.classList.add('show');
}
function hideAllTables() {
let allTableElements = document.querySelectorAll('.table');
for (tableElement of allTableElements) {
tableElement.classList.remove('show')
}
}
.table {
display: none;
}
.table.show {
display: block;
}
<div id="table1" class="show table">TABLE 1</div>
<div id="table2" class="table">TABLE 2</div>
<input type="button" onclick="showTable('table1')" value="Table 1">
<input type="button" onclick="showTable('table2')" value="Table 2">
If your code block is in the header, try moving it down to just before the closing body tag. I just ran it both ways, and it doesn't work in the header, does work in body.
The reason: the script is loaded in the header before the html, so the getelementbyid call returns null. By placing the script after the html, the div populates the id and the script loads it properly.
If you load your file in Chrome and turn on the Javascript console, you would have seen an error message similar to the following:
(index):12 Uncaught TypeError: Cannot set property 'onclick' of null
at (index):12
Your script is correct and is working. The problem was with the <table>. it was empty and not closed. So you were not able to notice the change in table display. try the below sample.
var table1 = document.getElementById("table1");
var table2 = document.getElementById("table2");
var btnTab1 = document.getElementById("showTable1");
var btnTab2 = document.getElementById("showTable2");
btnTab1.onclick = function () {
table1.style.display = "block";
table2.style.display = "none";
}
btnTab2.onclick = function () {
table1.style.display = "none";
table2.style.display = "block";
}
<table id=table1>
<tr>
<td>table 01</td>
</tr>
</table>
<table id=table2>
<tr>
<td>table 02</td>
</tr>
</table>
<input type="button" id="showTable1" value="Table 1">
<input type="button" id="showTable2" value="Table 2">
This question already has answers here:
How to append one jQuery element already in the DOM to another element?
(5 answers)
Closed 3 months ago.
I want get row of table 2 add to table 1, this is my js code:
$('#btnAdd').click(function () {
var table = $('#table1');
var tr =$("#table2 tr");
table.append(tr);
return false;
});
This is html code :
<div style="display: none;" id="rowitem">
<table id="table2">
<tr>
<td>No1</td>
<td>No2</td>
<td>No3</td>
</tr>
</table>
</div>
<div>
<table id="table1">
<tr>
<td>No1</td>
<td>No2</td>
<td>No3</td>
</tr>
</table>
<input id="btnAdd" type="button" value="+"/>
</div>
At first time, it get tr and add row ok.
But if i click add again, tr =undefined
Why can't get row of table, if click next time?
try
$('#btnAdd').click(function () {
var table = $('#table1');
var tr =$("#table2 tr").clone();
table.append(tr);
return false;
});
Instead of copying the tr's you are moving it
The issue is by appending, you are moving the whole tr element that causes the tr unavailable after first click. You should append the cloned table with .clone():
$('#btnAdd').click(function () {
var table = $('#table1');
var tr = $("#table2 tr").clone();
table.append(tr);
return false;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div style="display: none;" id="rowitem">
<table id="table2">
<tr>
<td>No1</td>
<td>No2</td>
<td>No3</td>
</tr>
</table>
</div>
<div>
<table id="table1">
<tr>
<td>No1</td>
<td>No2</td>
<td>No3</td>
</tr>
</table>
<input id="btnAdd" type="button" value="+"/>
</div>
I have a button:
<button id="external-list-row">Test</button>
in which I would like to change with a row from an external table on click. The external table is structured like this;
<table id="table_id">
<thead>
<tr>
<th>X</th>
<th>Y</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<p>Row 1</p>
</td>
</tr>
<tr>
<td>
<p>Row 2</p>
</td>
</tr>
<tr>
<td>
<p>Row 3</p>
</td>
</tr>
</tbody>
</table>
So my question is this; how can I replace "Test" in the button with the content of Row 1 with javascript?
As for the javascript, I'm not sure how I can get the content from row 1, and replace the button with it.
<script>
var rows = document.getElementById('table_id').getElementsByTagName("tr");
for (var i=0; i<rows.length; i++) {
$('#external-list-row').onclick = function() {
}};
</script>
Post comments:
I can access table data from other tables within the same html file, but I still don't know how to access data from tables in other html files. For example, if I try to access a videos liquid file from another liquid file, like photos, nothing happens when I press the button.
Fiddle of current code. It can replace the content of a list with the content of another, but the lists need to be on the same html file.
https://jsfiddle.net/hgnymydL/
Well, the first thing you should understand, is that a table element has a rows property, so getting the first row is trivial.
var table = document.getElementById("table_id");
var firstRow = table.rows[0];
From there, you can use textContent to get the text content of the row. I believe that's what you were looking for.
You can also select the first row of a table with a CSS selector like so:
var firstRow = document.querySelector("#table_id tbody tr");
$('#external-list-row').on('click', function() {
$(this).text($('#table_id tbody tr:first').text());
});
If you want to replace the button text with contents of the First Row ONLY then:
$('#external-list-row').html($('tr:first-child').html);
Of course you could wrap this in any event, so for example, on clicking the button:
$('#external-list-row').on('click', function() {
$(this).html($('tr:first-child').text());
});
BUT, based on the code you have given, I'm assuming you want to change the text after each click in which case you could do this:
var clickNumber = -1;
$('#external-list-row').on('click', function(event) {
clickNumber = clickNumber + 1;
//console.log('\n\nclickNUmber' + clickNumber);
$('tbody tr').each(function(index, el) {
//console.log('index: ' + index);
var block = $(el).find('td p');
if(index == clickNumber) {
//console.log('entered if')
//console.log(block.text());
//console.log('----clickNUmber' + clickNumber);
//console.log('index: ' + index);
//console.log(el);
$('#external-list-row').html(block.text());
}
});
});
jsFiddle: https://jsfiddle.net/zmb2b37t/
Hope that helps!
If you are wanting to replace the visible text "Test" in the button with the content of the cell clicked:
var tbl = document.getElementById('table_id');
var btn = document.getElementById('external-list-row');
tbl.onclick = function(ev){
var trgt = ev.target;
if(trgt.tagName === 'P' ||trgt.tagName === 'TD'){
btn.textContent = trgt.textContent;
}
};
Only one event handler is attached in this scenario.
Via event delegation we determine if it was a TD or P element that was clicked. If the rows are modified the function will still work.
Here is jquery code of do this
$('#table_id tr td').on('click', function(){
$('#external-list-row').html($(this).html());
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="external-list-row">Test</button>
<table id="table_id">
<thead>
<tr>
<th>X</th>
<th>Y</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<p>Row 1</p>
</td>
</tr>
<tr>
<td>
<p>Row 2</p>
</td>
</tr>
<tr>
<td>
<p>Row 3</p>
</td>
</tr>
</tbody>
</table>
For some reason the following piece of code does not work to insert an extra table into my html document. The text is just randomly sitting at the top of the table instead of IN the table. Any ideas why it doesn't work?
<!DOCTYPE html>
<head>
<script type = "text/javascript">
function insertTable() {
var table = document.getElementById("houseListingTable").innerHTML;
table = table + "<tr><td>58,500</td><td>Montreal</td></tr>";
}
</script>
</head>
<body>
<table>
<tr>
<th>Price</th>
<th>Location</th>
</tr>
<div id = "houseListingTable">
</div>
</table>
<button onclick = "insertTable()">Insert Table<\button>
</body>
</html>
Why doesn't the table row add itself to my table when I click on the Insert Table button? Any help is appreciated!!
There are two problems here:
Having a <div> element directly inside a <table> is invalid HTML.
Your table variable here is just a string. Overwriting it has no effect on the DOM.
To fix it:
Remove the <div> and give the <table> an ID:
<table id="houseListingTable">
<tr>
<th>Price<\th>
<th>Location<\th>
</tr>
</table>
Use this JavaScript:
var table = document.getElementById("houseListingTable");
table.innerHTML += "<tr><td>58,500</td><td>Montreal</td></tr>";
Note how I am actually overwriting the table's .innerHTML property. This is an important distinction from what you have there.
Just a couple of comments before the answer. Please note that you are missing the html tag at the begging, and that you are using the incorrect bar "\" to close tags in table headers (it should be < /th>) and in the button tag (< /button>).
Also, the div inside the table is not correct.
The code does nothing because the function just gets the innerHTML. For your purpose, the function should get what's inside the table, add a row and then paste it back on the table
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript">
function insertTable() {
var table = document.getElementById("houseListingTable").innerHTML;
table = table + "<tr><td>58,500</td><td>Montreal</td></tr>";
document.getElementById("houseListingTable").innerHTML = table;
}
</script>
</head>
<body>
<table id="houseListingTable">
<tr>
<th>Price</th>
<th>Location</th>
</tr>
</table>
<button onclick = "insertTable()">Insert Table</button>
</body>
</html>
Your HTML is broken. The ending tags are wrong.
<table id="houseListingTable">
<tr>
<th>Price</th>
<th>Location</th>
</tr>
</table>
You can use the insertRow of DOM method to add rows to table by getting the table first by Id
function insertTable() {
// Find a <table> element with id="houseListingTable":
var table = document.getElementById("houseListingTable");
// Create an empty <tr> element and add it to the table:
var row = table.insertRow(table.rows.length);
// Insert new cells (<td> elements) at the 1st and 2nd position of the "new" <tr> element:
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
// Append a text node to the cell1
var price = document.createTextNode('58,500')
cell1.appendChild(price);
// Append a text node to the cell2
var location = document.createTextNode('Montreal')
cell2.appendChild(location);
}
Note: this is meant to be a community wiki post
The following code using simple dom methods fails to add rows to the table. What's the issue?
<html>
<head>
<title>Javascript Test</title>
<script>
function addRow() {
var mytable = document.getElementById('mytable');
var row = document.createElement('tr');
var cell = document.createElement('td');
var text = document.createTextNode('This is a row');
cell.appendChild(text);
row.appendChild(cell);
mytable.appendChild(row);
}
</script>
</head>
<body>
<form action="#">
<table id="mytable">
<tr>
<td>This is a row</td>
</tr>
</table>
<input type="button" onclick="addRow()" value="Add A Row"/>
</form>
</body>
</html>
The issue at hand here is that the <table> element's correct structure is not present. When dealing with tables, the basic structure is:
<table>
<thead>
<tr>
<th>Heading for the table</th>
</tr>
</thead>
<tbody>
<tr>
<td>A row of data</td>
</tr>
</tbody>
</table>
The logic is that when dealing with tables, you want to keep the labels of the columns, and the actual data separate. Because most browsers fill in the <tbody> as part of the process of fixing broken HTML, few people realize this. When the browser sees you adding a <tr>, it doesn't know if you're trying to add it to the <thead> or the <tbody>, so it fails.
The following shows the correct method for adding the rows:
<html>
<head>
<title>Javascript Test</title>
<script>
function addRow() {
var mytbody = document.getElementById('mytbody');
var row = document.createElement('tr');
var cell = document.createElement('td');
var text = document.createTextNode('This is a row');
cell.appendChild(text);
row.appendChild(cell);
mytbody.appendChild(row);
}
</script>
</head>
<body>
<form action="#">
<table id="mytable">
<tbody id="mytbody">
<tr>
<td>This is a row</td>
</tr>
</tbody>
</table>
<input type="button" onclick="addRow()" value="Add A Row"/>
</form>
</body>
</html>
Any additional row needs to be added then take the first child of tableID and then use appendChild() method:
var tbl=document.getElementById("tbl");
var row=document.createElement("tr");
var cel=document.createElement("td");
cel.innerHTML='sometext';
row.appendChild(cel);
tbl.children[0].appendChild(row);