setting functions for dynamically generated table - javascript

I have a table with dynamically generated content. Each row comes with a button that is meant to serve that row. In my case I want my button's outerHTML to adopt the name of the name on its row.
I am having trouble assigning this to my onclick event. As is, clicking either button will only repeat the name on the first row. I am unsure of the exact proper syntax for getting the button to change to its appropriate row name.
var erray = ["Todd", "Bill", "Sam"];
var pname = document.querySelectorAll('.pname');
var adoptname = document.querySelectorAll('.adoptname');
for (var i = 0; i < erray.length; i++){
var adoptname = document.querySelectorAll('.adoptname');
pname[i].innerText = erray[i];
adoptname[i].onclick = adoption;
function adoption(){
for (var i = 0; i < pname.length; i++)
this.outerHTML = pname[i].innerHTML;
}
}
table { border: 1px solid black; }
<table>
<thead><tr>
<th>Name</th>
<th>Adopt</th>
</tr></thead>
<tbody>
<tr><td class="pname"></td><td><button class="adoptname">Adopt</button></td></tr>
<tr><td class="pname"></td><td><button class="adoptname">Adopt</button></td></tr>
</tbody>
</table>

Consider your html is like this;
<table>
<thead>
<th>Name</th>
<th>Adopt</th>
</thead>
<tbody id="table_body">
</tbody>
</table>
Now look at the js
var array=["Todd","Bill","Sam"];
var html="";
for(var i=0;i<array.length;i++)
{
html=html+"<tr><td>"+array[i]+"</td><td><button id=\"adopt-"+array[i]+"\">Adopt</button>";
}
$("#table_body").html(html);
Now look at the click event;
$("#table_body").on("click","[id^=adopt]",function(){
var id=$(this).attr("id");
var name=id.split("-")[1];
alert(name);
})

<table>
<thead><tr>
<th>Name</th>
<th>Adopt</th>
</tr></thead>
<tbody id="table_body">
<tr><td class="pname"></td><td><button class="adoptname">Adopt</button></td></tr>
<tr><td class="pname"></td><td><button class="adoptname">Adopt</button></td></tr>
</tbody>
</table>
<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
<script>
window.onload=function()
{
var array=["Todd","Bill","Sam"];
for(var i=0;i<array.length;i++)
{
$("#table_body tr:nth-child("+(i+1)+") .pname").html(array[i]);
$("#table_body tr:nth-child("+(i+1)+") .adoptname").attr("id","adopt-"+array[i]);
}
$("#table_body").on("click","[id^=adopt]",function(){
var id=$(this).attr("id");
var name=id.split("-")[1];
alert(name);
});
}
</script>

Related

In the below code I want to get the index value of rs using its Id and want to get its position

<table>
<tr>
<td id="1">Adi</td>
<td id="2">Aman</td>
</tr>
</table>
In the above code, I want to know the position of Aman using its id
You can try something like this:
html:
<table id="myTable">
<tr>
<td id="1">Adi</td>
<td id="2">Aman</td>
</tr>
</table>
js:
function getIdFromTable(searchValue)
{
var t = document.getElementById("myTable");
var trs = t.getElementsByTagName("tr");
var tds = null;
for (var i=0; i<trs.length; i++)
{
tds = trs[i].getElementsByTagName("td");
for (var n=0; n<tds.length;n++)
{
if (tds[n].innerText === searchValue) {
return tds[n].id;
}
}
}
}
getIdFromTable('Aman'); // will return 2
Easiest way to find position by id would be using prevAll().length. Something like this:
function findPositionById(id){
return $('#mytable').find('#'+id).prevAll().length
}
console.log('Adi Position', findPositionById(1));
console.log('Aman Position', findPositionById(2));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<table id="mytable">
<tr>
<td id="1">Adi</td>
<td id="2">Aman</td>
</tr>
</table>

Access text of an HTML element in an EventListener function

I have a table of about two dozen cells, each containing some text. I'd like to copy the text of a cell when it is clicked.
My <td> elements don't have IDs.
I have this js code that allows me to put an onClick() event to all of them, and they do prompt the "Hello" message :
var x = document.getElementsByTagName("td");
for (var i = 0; i < x.length; i++) {
x[i].addEventListener("click", function() {
alert("hello");
});
}
How do I access the text elements from within the EventListener's function ?
You can use Event.target and get its innerText.
Event.target: is the element on which the event is occurred.
var x = document.getElementsByTagName("td");
for (var i = 0; i < x.length; i++) {
x[i].addEventListener("click", function(e) {
alert(e.target.innerText);
});
}
You can refer the currently clicked td with this keyword. Then simply access innerText or textContent property on that like this.textContent:
x[i].addEventListener("click", function() {
alert(this.textContent);
});
Demo:
var x = document.getElementsByTagName("td");
for (var i = 0; i < x.length; i++) {
x[i].addEventListener("click", function() {
alert(this.textContent);
});
}
table, th, td {
border: 1px solid black;
}
<table style="width:100%">
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Age</th>
</tr>
<tr>
<td>Jill</td>
<td>Smith</td>
<td>50</td>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td>94</td>
</tr>
<tr>
<td>John</td>
<td>Doe</td>
<td>80</td>
</tr>
</table>
If you are using jquery you can do it this way:
table1 is class name of table
$(".table1 td").on("click", function(){
var thisCell = $(this).html();
alert(thisCell);
});

How to perform operations on selected rows in checkbox in a table in HTML

I have a table and I want to perform some operations(suppose doing output of selected rows in alert) on the rows which the user have checked on.
Following is my approach which is failing miserably-
<html>
<head>
<title>Introduction</title>
<script>
function kro(){
var x = document.getElementsByName('checks');
for (var i = 0;i < x.length;i++){
if(x[i].checked == 1)
var selecteddata+=x[i].value+"\n";
}
alert(selecteddata)
}
</script>
</head>
<body>
<table>
<thead>
<tr>
<th>UserName</th>
<th>Post</th>
<th>Comments</th>
<th>Select</th>
</tr>
</thead>
<tbody>
<tr>
<td>Ram</td>
<td>Sahi hai</td>
<td>Ravan:No</td>
<td><input type = "checkbox" name = "checks" id='one'/> </td>
</tr>
<tr>
<td>Ravan</td>
<td>Kidnap done</td>
<td>Ram:I'll kill you</td>
<td><input type = "checkbox" name = "checks" id='two'/> </td>
</tbody>
<p id = "check" ></p>
<button onclick="kro()">
Result
</button>
</body>
</html>
Following is my table-
I want to perform further operations on the selected row ,in the code ,I just want to output the selected rows using alert.
How to do that?
Expected Output-
if first row is checked then
Ram Sahi hai Ravan:No
var selecteddata+=x[i].value+"\n"; line will throw an error, So declare the variable outside the for loop. Also you need to set a value to checkbox otherwise it will so on
To get the content from all the td get the parent of the checkbox and get the closest tr. Then get text from each of the td and add it in a local variable of the if block
function kro() {
var x = document.getElementsByName('checks');
var selecteddata = '';
for (var i = 0; i < x.length; i++) {
if (x[i].checked) {
let _tt = '';
x[i].closest('tr').querySelectorAll('td').forEach(function(item) {
_tt += item.textContent.trim();
})
selecteddata += _tt + "\n";
}
}
alert(selecteddata)
}
<table>
<thead>
<tr>
<th>UserName</th>
<th>Post</th>
<th>Comments</th>
<th>Select</th>
</tr>
</thead>
<tbody>
<tr>
<td>Ram</td>
<td>Sahi hai</td>
<td>Ravan:No</td>
<td><input type="checkbox" name="checks" id='one' value='test1' /> </td>
</tr>
<tr>
<td>Ravan</td>
<td>Kidnap done</td>
<td>Ram:I'll kill you</td>
<td><input type="checkbox" name="checks" id='two' value='test2' /> </td>
</tbody>
<p id="check"></p>
<button onclick="kro()">
Result
</button>
You define and concat to the variable wrong.
should be
var foo = ''; // declare outside of loop
for (var i=0; i<5; i++) {
foo += i + '\n' // concat to string
}
console.log(foo) //display it
Other way people would do it is with an array and joining it at the end
var foo = []; // declare outside of loop
for (var i=0; i<5; i++) {
foo.push(i) // add to array
}
console.log(foo.join('\n')) //display it by joining the array items

submit button not working when i combine my codes

it was working on when i split them into two but when i combine them the save button isnt working i tried changing the document.getElementById to document.getElementByClassName but it stops the function of both here is the code
<html>
<head>
<body>
<div class="container">
<table class="table table-hover table-bordered" id = "table1">
<thead>
<tr>
<th><center>Item Name</center> </th>
<th><center>Brand</center> </th>
<th><center>Selling Price</center> </th>
<th><center>Quantity</center> </th>
</tr>
</thead>
<tbody id = tbody1>
<tr>
<td>Cake</td>
<td>Pastry</td>
<td>100</td>
<td>5</td>
</tr>
<tr>
<td>Wat</td>
<td>But</td>
<td>100</td>
<td>5</td>
</tr>
</tbody>
</table>
</div>
<div class="container">
<table class="table table-hover table-bordered" id = "table2">
<thead>
<tr>
<th><center>Item Name</center> </th>
<th><center>Brand</center> </th>
<th><center>Selling Price</center> </th>
<th><center>Quantity</center> </th>
</tr>
</thead>
<tbody id = "myNewTableBody" class = "tbody2">
<tr class = "tr2">
</tr>
</tbody>
</table>
</div>
<input type = "submit" value = "save" name = "btnsave" onclick = "myFunction()" style = "position : absolute; top : 550px; left : 20px; font-size: 20px;"/></input>
</body>
<script>
var table = document.getElementsByTagName("table")[0];
var tbody = table.getElementsByTagName("tbody")[0];
tbody.onclick = function (e) {
e = e || window.event;
var data = [];
var target = e.srcElement || e.target;
while (target && target.nodeName !== "TR") {
target = target.parentNode;
}
if (target) {
var cells = target.getElementsByTagName("td");
for (var i = 0; i < cells.length; i++) {
data.push(cells[i].innerHTML);
}
}
var trnode = document.createElement("tr");
for(var i = 0; i < data.length; i++){
var tdnode = document.createElement("td");
var textnode = document.createTextNode(data[i]);
tdnode.appendChild(textnode);
trnode.appendChild(tdnode);
}
document.getElementById("myNewTableBody").appendChild(trnode);
};
function myFunction() {
var rows = document.getElementById("table2")
.getElementsByClassName("tbody2")
[0].getElementsByClassName("tr2").length;
var a = 1;
var b = 1;
for(var i = 0; i < rows; i++){
var x =
document.getElementById("table2").rows[a].cells.item(0).innerHTML
var y =
document.getElementById("table2").rows[a].cells.item(4).innerHTML
var a = a + 1;
var b = b + 1;
alert(x);
alert(y);
}
}
</script>
<html>
<head>
heres the seperate code of the save button that's working
<html>
<head>
<body>
<div class="container">
<table id = "table1">
<thead>
<tr>
<th><center>ID</center> </th>
<th><center>Item Name</center> </th>
<th><center>Category</center> </th>
<th><center>Selling Price</center> </th>
<th><center>Quantity</center> </th>
</tr>
</thead>
<tbody class = "tbody2">
<tr class = "tr2">
<td>1</td>
<td>Cake</td>
<td>Pastry</td>
<td>100</td>
<td>5</td>
</tr>
<tr class = "tr2">
<td>2</td>
<td>Bread</td>
<td>Pastry</td>
<td>5</td>
<td>100</td>
</tr>
</tbody>
</table>
</div>
<input type = "submit" value = "save" name = "btnsave"
onclick = "myFunction()" /></input>
</body>
<script>
function myFunction() {
var rows = document.getElementById("table1")
.getElementsByClassName("tbody2")[0]
.getElementsByClassName("tr2").length;
var a = 1;
var b = 1;
for(var i = 0; i < rows; i++){
var x = document.getElementById("table1").rows[a].cells.item(0).innerHTML
var y = document.getElementById("table1").rows[a].cells.item(4).innerHTML
var a = a + 1;
var b = b + 1;
alert(x);
alert(y);
}
}
</script>
</html>
In this code, second table, table with id table2 is empty. When you take, first column, in it's second row(table body), you get a null. Then you trying to access innerHTML property on a null element. Add some content to table2 and run check it again.
Again same problem comes when you say, document.getElementById("table2").rows[a].cells.item(4).innerHTML. Here you are trying to access 5th cell of a row, which contains only 4 cells.

How can I get the corresponding table column (td) from a table header (th)?

I want to get the entire column of a table header.
For example, I want to select the table header "Address" to hide the address column, and select the "Phone" header to show the correspondent column.
<table>
<thead>
<tr>
<th id="name">Name</th>
<th id="address">Address</th>
<th id="address" class='hidden'>Address</th>
</tr>
</thead>
<tbody>
<tr>
<td>Freddy</td>
<td>Nightmare Street</td>
<td class='hidden'>123</td>
</tr>
<tr>
<td>Luis</td>
<td>Lost Street</td>
<td class='hidden'>3456</td>
</tr>
</tbody>
I want to do something like http://www.google.com/finance?q=apl (see the related companies table) (click the "add or remove columns" link)
Something like this would work -
$('th').click(function() {
var index = $(this).index()+1;
$('table td:nth-child(' + index + '),table th:nth-child(' + index + ')').hide()
});
The code above will hide the relevant column if you click on the header, the logic could be changed to suit your requirements though.
Demo - http://jsfiddle.net/LUDWQ/
With a couple simple modifications to your HTML, I'd do something like the following (framework-less JS):
HTML:
<input class="chk" type="checkbox" checked="checked" data-index="0">Name</input>
<input class="chk" type="checkbox" checked="checked" data-index="1">Address</input>
<input class="chk" type="checkbox" checked="checked" data-index="2">Phone</input>
<table id="tbl">
<thead>
<tr>
<th>Name</th>
<th>Address</th>
<th>Phone</th>
</tr>
</thead>
<tbody>
<tr>
<td>Freddy</td>
<td>Nightmare Street</td>
<td>123</td>
</tr>
<tr>
<td>Luis</td>
<td>Lost Street</td>
<td>3456</td>
</tr>
</tbody>
Javascript:
var cb = document.getElementsByClassName("chk");
var cbsz = cb.length;
for(var n = 0; n < cbsz ; ++n) {
cb[n].onclick = function(e) {
var idx = e.target.getAttribute("data-index");
toggleColumn(idx);
}
}
function toggleColumn(idx) {
var tbl = document.getElementById("tbl");
var rows = tbl.getElementsByTagName("tr");
var sz = rows.length;
for(var n = 0; n < sz; ++n) {
var el = n == 0 ? rows[n].getElementsByTagName("th")[idx] : rows[n].getElementsByTagName("td")[idx];
el.style.display = el.style.display === "none" ? "table-cell" : "none";
}
}
http://jsfiddle.net/dbrecht/YqUNz/1/
I added the checkboxes as it doesn't make sense to bind the click to the column headers as you won't be able to toggle the visibility, only hide them.
You can do something with CSS, like:
<html>
<head>
<style>
.c1 .c1, .c2 .c2, .c3 .c3{
display:none;
}
</style>
</head>
<body>
<table class="c2 c3">
<thead>
<tr>
<th id="name" class="c1">Name</th>
<th id="address" class="c2">Address</th>
<th id="phone" class="c3">Phone</th>
</tr>
</thead>
<tbody>
<tr>
<td class="c1">Freddy</td>
<td class="c2">Nightmare Street</td>
<td class="c3">123</td>
</tr>
<tr>
<td class="c1">Luis</td>
<td class="c2">Lost Street</td>
<td class="c3">3456</td>
</tr>
</tbody>
</table>
</body>
</html>
To hide a column, you add with Javascript the corresponding class to the table. Here c2 and c3 are hidden.
You could add dynamically the .c1, .c2,... in a style tag, or define a maximum number.
The easiest way to do this would be to add a class to each td that matches the class of the header. When you click the , it checks the class, then hides every td with that class. Since only the s in that column would hide that class, it would effectively hide the column.
<table>
<thead>
<th>Name</th>
<th>Address</th>
</thead>
<tbody>
<tr>
<td class="Name">Joe</td>
<td class="Address">123 Main St.
</tbody>
</table>
And the script something like:
$('th').click( function() {
var col = $(this).html(); // Get the content of the <th>
$('.'+col).hide(); // Hide everything with a class that matches the col value.
});
Something like that, anyway. That's probably more verbose than it needs to be, but it should demonstrate the principle.
Another way would be to simply count how many columns over the in question is, and then loop through each row and hide the td that is also that many columns over. For instance, if you want to hide the Address column and it is column #3 (index 2), then you would loop through each row and hide the third (index 2).
Good luck..
Simulating the Google Finance show/hide columns functionality:
http://jsfiddle.net/b9chris/HvA4s/
$('#edit').click(function() {
var headers = $('#table th').map(function() {
var th = $(this);
return {
text: th.text(),
shown: th.css('display') != 'none'
};
});
var h = ['<div id=tableEditor><button id=done>Done</button><table><thead><tr>'];
$.each(headers, function() {
h.push('<th><input type=checkbox',
(this.shown ? ' checked ' : ' '),
'/> ',
this.text,
'</th>');
});
h.push('</tr></thead></table></div>');
$('body').append(h.join(''));
$('#done').click(function() {
var showHeaders = $('#tableEditor input').map(function() { return this.checked; });
$.each(showHeaders, function(i, show) {
var cssIndex = i + 1;
var tags = $('#table th:nth-child(' + cssIndex + '), #table td:nth-child(' + cssIndex + ')');
if (show)
tags.show();
else
tags.hide();
});
$('#tableEditor').remove();
return false;
});
return false;
});
jQuery('thead td').click( function () {
var th_index = jQuery(this).index();
jQuery('#my_table tbody tr').each(
function(index) {
jQuery(this).children('td:eq(' + th_index + ');').each(
function(index) {
// do stuff here
}
);
}
);
});
here's a working fiddle of this behaviour:
http://jsfiddle.net/tycRW/
of course, hiding the column with out hiding the header for it will have some strange results.

Categories