How to select thead element from dynamically built table? - javascript

I have dynamically built table in JavaScript/JQUERY. After table is built I need to select thead element. Here is example of my code:
$(document).ready(function(){
buildTbl();
});
function buildTbl() {
var tbl = '<table id="myTbl"><thead><tr><th>Column 1</th></tr></thead><tr><td>Cell 1</td></tr><tbody></tbody></table>';
$('#tblContainer').empty().append(tbl);
var test = $('#myTbl').find('thead');
console.log(test);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='tblContainer'></div>
As you can see in example in console length is 0. The element is not selected. I'm wondering how I can access dynamically built elements in JavaScript? I need to prevent headers from scrolling so that's why I need to select thead element int he table.

In your case I suggest you another way of creating your element. As you are using jquery you can use jquery to create your html node as follow so that you can access to your jquery element before appending it into the dom:
$(document).ready(function(){
buildTbl();
});
function buildTbl() {
var $tbl = $("table").attr("id", "myTbl");
var $thead = $("thead");
// TODO: Here you can add your table rows into your thead
$tbl.append($thead);
// now you can access to your thead element without searching the dom.
console.log($thead);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

You need to append it to the dom before you want to retrieve it using selector
$(document).ready(function() {
buildTbl();
});
function buildTbl() {
var tbl = '<table id="myTbl"><thead><tr><th>Column 1</th></tr></thead><tr><td>Cell 1</td></tr><tbody></tbody></table>';
$('#tableContainer').append(tbl)
var test = $('#myTbl').find('thead');
console.log(test);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='tableContainer'></div>

Try This and call buildTbl before $(document).ready()
function buildTbl() {
var tbl = '<table id="myTbl"><thead><tr><th>Column 1</th></tr></thead><tr><td>Cell 1</td></tr><tbody></tbody></table>';
$('#tableContainer').html(tbl)
}
$(document).ready(function(){
buildTbl();
var test = $(document).find('#myTbl > thead');
console.log(test);
});
And call the div with id tableContainer
Hope this will help you

Related

Is there a way to get the value of TD in a table generated in javascript with vanilla JS?

I have a the following code, it generate a HTML table using a javascript array:
<HTML lang='en'>
<head>
<style>
table {
border-collapse: collapse;
}
table tr td {
border: 1px solid #000;
padding: 10px;
}
table tr td:hover {
color: red;
}
</style>
</head>
<body>
<div id="container"></div>
<script>
window.addEventListener("load", function(){
var data = ["doge", "cate", "birb", "doggo", "moon", "awkward", "coool", "epic"];
var perrow = 3,
html = "<table><tr>";
for (var i=0; i<data.length; i++) {
html += "<td class=\".cell\" >" + data[i] + "</td>";
var next = i+1;
if (next%perrow==0 && next!=data.length) {
html += "</tr><tr>";
}
}
html += "</tr></table>";
document.getElementById("container").innerHTML = html;
});
</script>
</body>
</HTML>
That works fine. What I would like is for the user to be able to hover over any item in the table and have it log the value of the item of the table to the console.
I have searched for solutions and have only found one which kind of works:
$(document).ready(function(){
$('tr').mouseover(function(){
var valueOfTd = $(this).find('td:first-child').text();
console.log(valueOfTd);
});
});
I have two problems with this solution:
It doesn't work, it only seems to output the contents of the cell to the far left of the row
It is in jQuery, I am planning to use this for an electron app so it would be much appreciated if a solution in vanilla JS could be found, however if I need to I can use jQuery, just would prefer not to.
So basically, I would like the user to be able to hover over an item in the table and have the contents output to the console, would like the answer in vanilla JS.
Thanks in advance... :)
Here's one approach. Run this code after you create the table (it can go right after document.getElementById("container").innerHTML = html;).
var rows = document.getElementsByTagName('tr');
Array.from(rows).forEach(function(tr) {
tr.addEventListener('mouseover', function(event) {
console.log(event.target.textContent);
});
});
Explanation:
getElementsByTagName() returns a collection of <TR>s in the document. (For this, you could also use document.querySelectorAll('tr'), which lets you use jQuery-like CSS selectors to find elements.)
Array.from turns the collection returned by the previous call into a regular JS Array, allowing us to call forEach on it.
We use addEventListener to attach a callback function that fires when a <TR> is hovered over. This is vanilla JS event binding.
The event parameter inside the callback contains information about the mouseover event.
The immediate element being targeted by the user's cursor is event.target. This gives us the <TD> that the user's cursor is over. This part is a bit subtle, but basically, you can attach listeners to a parent element (the <TR>s), and the listener will get called when a child element (the <TD>) is moused over. You don't have to actually add listeners to every cell individually. Search "event bubbling" for a full explanation of how this works.)
textContent property of the <TD> gives the text inside the cell. This is a standard property of the DOM Node API.
the problem probably is because when the event handler is bind the table doesn't exists.
You should use a delegated event handler
with jQuery:
$('#container').on('mouseover', 'tr', function(){
var valueOfTd = $(this).find('td:first-child').text();
console.log(valueOfTd);
});
with plain javascript:
var container = document.getElementById('container');
container.addEventListener('mouseover', function(event) {
var target = event.target.closest('tr');
if (! target) return;
var valueOfTd = target.querySelector('td:first-child').innerText;
console.log(valueOfTd);
});
Try this.
$(document).ready(function() {
$("#container table").on('mouseenter', 'tr', function () {
var tdVal = $(this).children('td').text();
console.log(tdVal);
}
});
You could use the following method
function setListeners() {
let tds = document.querySelectorAll('td');
tds.forEach((td) => {
td.addEventListener('mouseover', (e) => {
console.log(e.target.innerHTML);
});
})
}
and would call this method after setting container's innerHTML
document.getElementById("container").innerHTML = html;
setListeners();

jQuery .click() not working?

I generate the set of buttons within html table as follows and then I want to call to function when it click.
$.each(childData, function(key, item) {
var packPath = key.replace(/_/g, "/"); //Replace underscore with slash
div.innerHTML = div.innerHTML + '<td>'+key+'</td>'
+ '<td><button type="button" data-id="'+key+'" class="download btn btn-success btn-xs">Originals</li></td></div>';
})
This is how I call the function but it's not working.
$(".download").click(function(){
alert();
});
Where is the wrong in above code?
Try this:
$(document).on('click', '.download', function(){
// Your Code
});
Delegate the event to static parent:
$(div).on("click", ".download", function(){
Here div can be the static parent which was available when page was loaded at first load. Although document or body can also be used in place of div.
As you have not presented how you create div element but one thing has to be noticed that you are generating an invalid markup. As a td element can't be a child of div but table's tr.
You need to use event delegation.
If your table has an id of "button-table", you can create an event handler like so:
$("#button-table").on("click",function(e){
var target = e.target;
console.log($(target).attr("data-id"));
});
Do you want it this way? I have given code for adding an entire table.Check this out
function generate_table() {
// get the reference for the body
var body = document.getElementsByTagName("body")[0];
// creates a <table> element and a <tbody> element
var tbl = document.createElement("table");
var tblBody = document.createElement("tbody");
// creating all cells
for (var i = 0; i < 2; i++) {
// creates a table row
var row = document.createElement("tr");
for (var j = 0; j < 2; j++) {
// Create a <td> element and a text node, make the text
// node the contents of the <td>, and put the <td> at
// the end of the table row
var cell = document.createElement("td");
var cellText = document.createTextNode("cell in row "+i+", column "+j);
cell.appendChild(cellText);
row.appendChild(cell);
}
// add the row to the end of the table body
tblBody.appendChild(row);
}
// put the <tbody> in the <table>
tbl.appendChild(tblBody);
// appends <table> into <body>
body.appendChild(tbl);
// sets the border attribute of tbl to 2;
tbl.setAttribute("border", "2");
}
<input type="button" value="Generate a table." onclick="generate_table()">
$(document).ready(function() {
$(".download").click(function(){
alert();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="downlaod">Download</button>

How to get the data inside a html table cell when clicked on it?

I created a html table and filled it dynamically. So I want to alert the data inside a cell of the table when i clicked it. Here is the code for the table
JSP
<table id="load-opt"></table>
I'm filling the data inside dynamically like this
var fillTable = function($element, data) {
var t_head = $("<tr></tr>");
for(var ind=0; ind<data.length; ind++) {
//name is the name and desc is the description for each option
var $option = $("<tr></tr>");
$option.html("<td>"+name+"</td><td>"+desc+"</td>");
}
};
I tried this but it's not working, it's giving "undefined".
var choice = $('table#load-opt tr td');
choice.click(function(){
alert(choice); // also tried alerting choice.textContent, choice.innerHTML and choice.firstChild
});
you are actually trying to alert the 'td' object not value of from that object so you can use following to solve the query.Here i am using on instead of direct click function because of dynamically added data.
var choice = $('table#load-opt tr td');
choice.on('click', function(){
alert($(this).text());
});
You can use $(this).text() to fetch the data in table cell.
This is a link.

Add class name to appended child elements with jquery

I have a table like this.
<table id='table1'>
</table>
and in this table i am dynamically adding rows to the table using jquery like below.
var tbl = $("#table1");
tbl.append('<tr></tr><tr></tr><tr></tr>');
I can add class to the appended rows using 2 methods like below
case 1
tbl.find('tr').eq(0).addClass("test");
tbl.find('tr').eq(1).addClass("test");
or case 2
for (var i=0;i<tbl.find('tr').length;i++) {
tbl.find('tr').eq(i).addClass("test")
}
and my question is there any way i can add same classname to the dynamically appended rows. Answers expecting in jquery. Thanks in advance.
Once an element is added to the DOM, you have no way of telling if it was dynamically added or not unless you have custom code that does such. I would suggest changing .append to .appendTo so you have access to the rows you're adding and can call .addClass:
var tbl = $("#table1");
$('<tr></tr><tr></tr><tr></tr>').appendTo(tbl).addClass("test")
You could also put the class in the string then append it or modify it (add a class) prior to appending it. Note how I only have one tr in my string but append it multiple times (optionally adding a class as noted)
var tbl = $("#table1");
var tr = '<tr class="test"></tr>';
var td = '<td class="test">new data</td>';
//var addedrow = $(tr).append(td).addClass("newclass");//adds class to the row
var addedrow = $(tr).append(td);//create new row object
addedrow.find('td').addClass("newclass"); //adds class to the td in the new row
var ar2 = $(tr).append(td);
var ar3 = $(tr).append(td);
tbl.append(addedrow, [ar2, ar3]); // appends the new rows
tbl.find('tr').last(td).addClass("newclass");//add class to last rows td
see it in action here: http://jsfiddle.net/MarkSchultheiss/0osLfef3/

jQuery Populate content inside a new element before appending it

I'm trying to populate featured with data then append it to #wrapper. This isn't working for me. What am i doing wrong?
var featured = '<div id="featured"></div>';
$('#imageTable tbody tr td img').each(function(){
$(featured).append($(this).attr('src'));
});
$(featured).appendTo('#wrapper');
var $featured = $('<div id="featured"></div>');
$('#imageTable tbody tr td img').each(function(){
$featured.append($(this).attr('src')).append('<br />');
});
$featured.appendTo('#wrapper');
Explaination:
When you do this inside the loop $(featured), it creates a NEW div for each selected element, so only the last div will be appended to your #wrapper. You need to create the jQuery object outside of the each loop.
It's because you have the $(featured) call inside the loop. You only want to call it once.
Try this:
var $featured = $('<div id="featured"></div>');
$('#imageTable tbody tr td img').each(function(){
$featured.append($(this).attr('src'));
});
$featured.appendTo('#wrapper');
Very Similar to Bryan Ross's, just creating the div in a more efficient manner. It may not be as straight forward, but I believe it is more performant.
var $f = $('<div>',{id:'featured'});
$('img,#imageTable > td').each(function(i){
$f.append($(this).attr('src');
})
$f.appendTo('#wrapper');

Categories

Resources