I've created dynamic table rows using javascript for loop and I want to fire a click event
on row in a way that whenever user clicks on any row it should be visible in console log.
<tbody>
<script>
for(var i=0;i<data.length;i++){
document.write("<tr>");
document.write("<td>"+data[i]['col1']+"</td>");
document.write("<td>"+data[i]['col2']+"</td>");
document.write("<td>"+data[i]['col3']+"</td>");
document.write("<td>"+data[i]['col4']+"</td>");
document.write("<td>"+data[i]['col5']+"</td>");
}
</tbody>
</script>
I know there are many answers for this but I tried and none helping me and some prints as
undefined.
Here is what I tried:
var table = document.getElementById("tableID");
if (table) {
for (var i = 0; i < table.rows.length; i++) {
table.rows[i].onclick = function() {
tableText(this);
};
}
}
Your javascript code looks correct to me but I think you're not placing it at correct place.
Try this:
<script>
for(var i=0;i<data.length;i++){
document.write("<tr>");
document.write("<td>"+data[i]['col1']+"</td>");
document.write("<td>"+data[i]['col2']+"</td>");
document.write("<td>"+data[i]['col3']+"</td>");
document.write("<td>"+data[i]['col4']+"</td>");
document.write("<td>"+data[i]['col5']+"</td>");
}
function tableText(tableRow) {
var name = tableRow.childNodes[1].innerHTML;
var age = tableRow.childNodes[3].innerHTML;
var obj = {'name': name, 'age': age};
console.log(obj);
}
let tableData = document.getElementById('tableID').getElementsByTagName('tbody')[0];
for (let i = 0; i < tableData.rows.length; i++)
{
tableData.rows[i].onclick = function()
{
tableClicked(this);
};
}
function tableClicked(rowData) {
let msg = rowData.cells[0].innerHTML+'*'+rowData.cells[1].innerHTML+'*'+rowData.cells[2].innerHTML+'*'+rowData.cells[3].innerHTML+'*'+rowData.cells[4].innerHTML;
console.log(msg,data);
};
</script>
Your Javascript code looks correct to me, and assuming tableText = console.log printed the correct row for me when I used it on a table.
Although I noticed in your table creation code that you are not closing your table row with </tr>.
for(var i=0;i<data.length;i++){
document.write("<tr>");
document.write("<td>"+data[i]['col1']+"</td>");
document.write("<td>"+data[i]['col2']+"</td>");
document.write("<td>"+data[i]['col3']+"</td>");
document.write("<td>"+data[i]['col4']+"</td>");
document.write("<td>"+data[i]['col5']+"</td>");
document.write("</tr>");
}
Related
I'm appending some rows to my table and when I click on one row different rows should open, I'm using slideToggle and hide show, but it doesn't work.. the click does work(I added console.log to check)- if I'm writing the rows inside the html it does work.
this is the function:
$('#table').on('click','.good_light_tags_reg',function(){
console.log("hey");
if ($('.good_light_sub_tag_reg').is(":visible")){
$('.good_light_sub_tag_reg').hide();
}
else{
$('.good_light_sub_tag_reg').show();
}
});
the insert part..
var identified_correctly = {};
var rows = "";
for (var i=1 ; i<(table.rows.length -1) ; i++){
if (table.rows[i].className.includes('_tags_reg')){
if (table.rows[i].className != table.rows[i+1].className) {
val = table.rows[i].cells[6].innerHTML;
var pos = val.indexOf("<br>");
var res = parseFloat(val.substring(0, pos));
identified_correctly[table.rows[i].className]=parseFloat(res);
}
}
}
var items = Object.keys(identified_correctly).map(function(key) {
return [key, identified_correctly[key]];
});
items.sort(function(first, second) {
return first[1] - second[1];
});
for (var i=0;i<items.length;i++){
var class_name = items[i][0];
var tags_rows = document.getElementsByClassName(class_name);
var sub_tags_rows = document.getElementsByClassName(class_name.replace("_tags_","_sub_tag_"));
for (var tag=0;tag<tags_rows.length;tag++){
rows += tags_rows[tag].outerHTML;
for (var sub_tag=0;sub_tag<sub_tags_rows;sub_tag++){
rows += sub_tags_rows[sub_tag].outerHTML;
}
}
}
for (var i=0;i<items.length;i++){
$("#table").find("."+items[i][0]).remove();
$("#table").find("."+items[i][0].replace("_tags_","_sub_tag_")).remove();
}
$(rows).insertAfter($(".tag_list_reg").last());
try this using $(document)
$(document).on('click','.good_light_tags_reg',function(){
$('.good_light_sub_tag_reg').toggle();
});
and if the element to show or hide is inside new row, try this
$(document).on('click','.good_light_tags_reg',function(){
$(this).find('.good_light_sub_tag_reg').toggle();
});
How do I use the below code to pull certain details like country name and capital only into a table with drop down headers? Or can you suggest any plain English Youtube videos where I can learn how to do this or example courses where I can teach myself.
<script>
$(document).ready(function () {
//for example details in url below
var url = 'https://restcountries.eu/rest/v1/all';
$.getJSON(url, function (data) {
console.log(data)
// var arrItems = []; // THE ARRAY TO STORE JSON ITEMS.
// $.each(data, function (index, value) {
// arrItems.push(value); // PUSH THE VALUES INSIDE THE ARRAY.
// });
console.log(arrItems)
// EXTRACT VALUE FOR TABLE HEADER.
var col = [];
var arrItems = data.countries;
console.log(arrItems)
var firstCountry = arrItems[0]
console.log(firstCountry)
for (var i = 0; i < arrItems.length; i++) {
for (var key in arrItems[i]) {
if (col.indexOf(key) === -1) {
col.push(key);
}
}
}
// CREATE DYNAMIC TABLE.
var table = document.createElement("table");
// CREATE HTML TABLE HEADER ROW USING THE EXTRACTED HEADERS ABOVE.
var tr = table.insertRow(-1); // TABLE ROW.
for (var i = 0; i < col.length; i++) {
var th = document.createElement("th"); // TABLE HEADER.
th.innerHTML = col[i];
tr.appendChild(th);
}
// ADD JSON DATA TO THE TABLE AS ROWS.
for (var i = 0; i < arrItems.length; i++) {
tr = table.insertRow(-1);
for (var j = 0; j < col.length; j++) {
var tabCell = tr.insertCell(-1);
tabCell.innerHTML = arrItems[i][col[j]];
}
}
// FINALLY ADD THE NEWLY CREATED TABLE WITH JSON DATA TO A CONTAINER.
var divContainer = document.getElementById("showData");
divContainer.innerHTML = "";
divContainer.appendChild(table);
});
});
There's a lot of looping inside of looping, which can increase the time and space complexity - meaning, the more data, the slower this solution will become as well as in general this looks like it will be difficult to maintain.
I would first put as much of the html that you can in the static html and just append the dynamic html to the <tbody>.
You can use the Array.reduce static method to generate a string from your data. One thing you can do to make this easier to understand is stick with either mostly appending DOM nodes or using innerHTML. If you stick with innerHTML, you can create template strings for the cells and the rows.
This will make the code more declarative in nature and functional as well as composeable.
$(document).ready(function() {
//for example details in url below
var url = 'https://restcountries.eu/rest/v1/all';
$.getJSON(url, function(data) {
const html = buildHTML(data);
const tbody = document.querySelector('#showData tbody');
tbody.innerHTML = html;
});
});
const tableCellTemplate = (val) => {
return `<td>${val}</td>`;
};
const tableRowTemplate = (val) => {
return `<tr>${val}</tr>`;
};
function buildHTML(data) {
return data.reduce((prev, next) => {
const nameCell = tableCellTemplate(next.name);
const codeCell = tableCellTemplate(next.alpha2Code);
return prev + tableRowTemplate(nameCell + codeCell);
}, '');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="showData">
<table>
<thead>
<tr>
<th>Name</th>
<th>alpha2Code</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
I created a table and populated values from an array, so I have 5x5 table, where each td will be filled with a word. The word come from array memo and all the code below works fine.
var myTableDiv = document.getElementById("results")
var table = document.createElement('TABLE')
var tableBody = document.createElement('TBODY')
table.border = '1'
table.appendChild(tableBody);
//TABLE ROWS
for (i = 0; i < this.memo.length; i++) {
var tr = document.createElement('TR');
for (j = 0; j < this.memo[i].length; j++) {
var td = document.createElement('TD');
td.onclick = function () {
check();
}
td.appendChild(document.createTextNode(this.memo[i][j]));
tr.appendChild(td)
}
tableBody.appendChild(tr);
}
myTableDiv.appendChild(table);
I have one question : I would like to click on the cell and get the word, which belongs to the cell.
For this purpose I tried onclick as I created td element
td.onclick = function () {
check();
}
The function check should print the innerHTML of the cell, which was clicked
function check() {
var a = td.innerHTML;
console.log(a);
}
But it gives me always wrong text - the last one in the array, which was populated.
How could I solve it?..
You always get the last td in the array because the last value that was set to td was of the last cell. You need to add the a parameter, say event, to onclick's callback function, and then your clicked element will be referenced in event.target. Then you would be able to get it's innerHTML.
Here's why it's always giving you the first element: after the for (j = 0; ... loop is finished, the variable td will hold the value of the last element in the list. Then, when check is called, it accesses that same td variable pointing to the last element.
To solve this, you can add an argument to the function to accept a specific element and log that.
td.onclick = function () {
check(td);
};
// later...
function check(element) {
var html = element.innerHTML;
console.log(html);
}
I would pass the innerHTML in the click itself - please see working example below, with some mock data for memo.
var myTableDiv = document.getElementById("results")
var table = document.createElement('TABLE')
var tableBody = document.createElement('TBODY')
var memo = [
['joe', 'tom', 'pete'],
['sara','lily', 'julia'],
['cody','timmy', 'john']
]
table.border = '1'
table.appendChild(tableBody);
//TABLE ROWS
for (i = 0; i < this.memo.length; i++) {
var tr = document.createElement('TR');
for (j = 0; j < this.memo[i].length; j++) {
var td = document.createElement('TD');
td.onclick = function () {
check(this.innerHTML);
}
td.appendChild(document.createTextNode(this.memo[i][j]));
tr.appendChild(td)
}
tableBody.appendChild(tr);
}
myTableDiv.appendChild(table);
function check(a) {
console.log(a);
}
<div id="results">
</div>
you can try..
td.onclick = function () {
check();
}
to
td.onclick = function (evt) {
var html = evt.target.innerHTML;
console.log(html);
check(html); //to do something..
}
I'm developing an android app with phonegap. I'm making an HTML table with some that with a for loop from localStorage. I need, for each row, to store the index i of the for to use it for retrieving an item from localStorage that has the name like the index. I have some code but the variable that i defined for that effect gets overwritten by the loop (of course). Here's the code:
<script language="javascript">
if(len != 0) {
var table = document.getElementById('hor-minimalist-b'); // get the table element
var tableBody = table.childNodes[1]; // get the table body
var tableHead = table.childNodes[0]; // get the table head
var thead = document.createElement('th');
var row2 = document.createElement('tr'); // create a new row
var headText = document.createTextNode('Dados');
thead.scope = "col";
thead.appendChild(headText);
row2.appendChild(thead);
tableHead.appendChild(row2);
for (var i=0; i<len; i++) {
var row = document.createElement('tr'); // create a new row
var cell = document.createElement('td'); // create a new cell
var a = document.createElement('a');
var cellText = document.createTextNode(localStorage.getItem('key' + i));
var xyz = "key" + i;
a.href = "alterar.html";
a.onclick = function() { doLocalStorage(xyz) };
a.appendChild(cellText);
cell.appendChild(a); // append input to the new cell
row.appendChild(cell); // append the new cell to the new row
tableBody.appendChild(row); // append the row to table body
}}
</script>
</table>
Maybe i'm not explaining myself too well. If you need any more info please ask. Thanks in advance. Eva
try to put the key name in to a closure:
function wrapper(i) {
return function() {
doLocalStorage("key" + i)
}}
a.onclick = wrapper(i);
Not sure if I got your question right, but if you want to bind usage of a variable asynchronously when doing for loop then you should wrap it in a closure:
for(i = 1, c = arr.length; i < c; i++){
(function(i){
// i wont change inside this closure so bound events will retain i
$('#id'+i).click(function(){
alert(i); // Will alert the corresponding i
})
})(i);
}
I am using the following method to read header names in a table and put in excel. Could anyone let me know how to modify this to support multiple tables with header info and data.
i.e. how to modify to pass table id. "headers" is the id for "th" tag in code.
function write_headers_to_excel()
{
str="";
var myTableHead = document.getElementById('headers');
var rowCount = myTableHead.rows.length;
var colCount = myTableHead.getElementsByTagName("tr")[0].getElementsByTagName("th").length;
var ExcelApp = new ActiveXObject("Excel.Application");
var ExcelSheet = new ActiveXObject("Excel.Sheet");
ExcelSheet.Application.Visible = true;
for(var i=0; i<rowCount; i++)
{
for(var j=0; j<colCount; j++)
{
str= myTableHead.getElementsByTagName("tr")[i].getElementsByTagName("th") [j].innerHTML;
ExcelSheet.ActiveSheet.Cells(i+1,j+1).Value = str;
}
}
Your question is a bit vague, so I'm guessing at what you want. Assuming your current function works as is, you can just take out the hard-coding of the table's ID and pass it in as a parameter:
function write_headers_to_excel(tableID) {
var myTableHead = document.getElementById(tableID);
// rest of your function as is
}
Then call it once for each table, though that will create a new ExcelSheet for each table.
If the idea is for all of the tables to be added to the same ExcelSheet you can pass an array of table IDs to the function something like the following. I've kept the basic structure of your function but moved the variable declarations out of the loops (since that what JavaScript does behind the scenes anyway), deleted your ExcellApp variable since it wasn't used, and moved the getElementsByTagName call out of the inner loop.
write_headers_to_excel(["headers1","headers3","headers7","etc"]);
function write_headers_to_excel(tableIDs) {
var myTableHead,
rowCount,
cols,
t,
i,
j,
rowOffset = 1,
ExcelSheet = new ActiveXObject("Excel.Sheet");
ExcelSheet.Application.Visible = true;
for (t=0; t < tableIDs.length; t++) {
myTableHead = document.getElementById(tableIDs[t]);
rowCount = myTableHead.rows.length;
for(i=0; i<rowCount; i++) {
cols = myTableHead.rows[i].getElementsByTagName("th");
for(j=0; j < cols.length; j++) {
ExcelSheet.ActiveSheet.Cells(i+rowOffset,j+1).Value = cols[j].innerHTML;
}
}
rowOffset += rowCount;
}
}
(No, I haven't tested it.)
You can get all tr elements by tag name
var rows = document.getElementsByTagName('tr');// get all rows of all tables
var table=0, TableRow=0;
for (i = 0; i < rows.length; i++) {
row = rows[i];
if (row.parentNode.tagName != 'THEAD' && row.parentNode.tagName != 'thead') {
table=table+1;
// do something here for headers
} else if (row.parentNode.tagName != 'TBODY' && row.parentNode.tagName != 'tbody')
{
TableRow=TableRow+1;
//do something here for rows
}
}