Selecting multiple rows of items in a table - javascript

EDIT: I didn't have enough time to ask the question properly. I am rewriting the question with an image.
So, I have a table (shown below):
The data on each row are dynamically filled out.
However, if users want to delete the data (which they can), they have to delete them individually.
How can I implement the "Select" checkbox and apply the "Delete" (for example) action to the "Checked" items?
Thanks! =)

Something like this?
function inputChanged(event) {
event.target.parentElement.parentElement.className =
event.target.checked ? 'selected' : '';
}
function printSelected() {
var textArea = document.getElementsByTagName('textarea')[0];
textArea.value = '';
var selectedRows = document.getElementsByClassName('selected');
for (var i = 0; i < selectedRows.length; ++i) {
textArea.value += selectedRows[i].textContent.trim() + '\n';
}
}
.selected {
background-color: yellow;
}
<table>
<tr>
<td>
<input type="checkbox" onchange="inputChanged(event)" />
</td>
<td>Row 1</td>
</tr>
<tr>
<td>
<input type="checkbox" onchange="inputChanged(event)" />
</td>
<td>Row 2</td>
</tr>
</table>
<button onclick="printSelected()">Print selected rows</button>
<textarea></textarea>

Related

Click elsewhere and checkbox is ticked/unticked [duplicate]

This question already has answers here:
What do querySelectorAll and getElementsBy* methods return?
(12 answers)
Closed 1 year ago.
So I have a piece of code to create a table with some data in it. The first column contains checkboxes, other columns are just regular data.
What I want is that when I click anywhere on a random row (except for header), that entire row's background is turning into yellow (initially white) and the checkbox in that row is ticked. If I click again, everything in the row back to its normal (white row and unticked checkbox).
When I click right at the checkbox, everything acts as expected. However, when I click elsewhere, only the background is changed. I have checked the checked attribute of the checkbox and it is changed whenever I click (which is like normal). I don't know why this happens. I have looked through many posts with similar issues but it is not helped. I am only a beginner at Javascript and HTML. Please help me with this. Thank you very much!
function changeColorRow(number) {
var elem = document.getElementsByTagName("tr")[number]
var curr_check = document.getElementsByClassName("checkbox").checked
if (!curr_check) {
elem.style.backgroundColor = "yellow"
document.getElementsByClassName("checkbox").checked = true
} else {
elem.style.backgroundColor = "white"
document.getElementsByClassName("checkbox").checked = false
}
}
<h1>List of companies</h1>
<table id="company">
<tr>
<th>Choose</th>
<th>ID</th>
<th>Company</th>
<th>Website</th>
</tr>
<tr onclick="changeColorRow(1)">
<td><input type="checkbox" class="checkbox"></td>
<td>1</td>
<td>ECOPRO Co., Ltd</td>
<td>http://www.ecoprovn.com</td>
</tr>
<tr onclick="changeColorRow(2)">
<td><input type="checkbox" class="checkbox"></td>
<td>2</td>
<td>WAVINA.COM</td>
<td>http://www.wavina.com</td>
</tr>
</table>
document.getElementsByClassName returns an array like structure, You have to use index to get that particular element at that index.
document.getElementsByClassName("checkbox")
You can get the index of the clicked row as
index = number - 1
const allCheckbox = document.getElementsByClassName("checkbox");
function changeColorRow(number) {
const index = number - 1;
var elem = document.getElementsByTagName("tr")[number]
var curr_check = document.getElementsByClassName("checkbox")[index].checked
if (!curr_check) elem.style.backgroundColor = "yellow"
else elem.style.backgroundColor = "white"
allCheckbox[index].checked = !allCheckbox[index].checked
}
[...allCheckbox].forEach(cb => {
cb.addEventListener("change", (e) => changeColorRow(parseInt(e.target.dataset.index)))
})
tr {
cursor: default;
user-select: none;
}
<h1>List of companies</h1>
<table id="company">
<tr>
<th>Choose</th>
<th>ID</th>
<th>Company</th>
<th>Website</th>
</tr>
<tr onclick="changeColorRow(1)">
<td><input type="checkbox" class="checkbox" data-index="1"></td>
<td>1</td>
<td>ECOPRO Co., Ltd</td>
<td>http://www.ecoprovn.com</td>
</tr>
<tr onclick="changeColorRow(2)">
<td><input type="checkbox" class="checkbox" data-index="2"></td>
<td>2</td>
<td>WAVINA.COM</td>
<td>http://www.wavina.com</td>
</tr>
</table>

How to find the value from a row of table depending on the row of a button I clicked

No jQuery involve pls. I am just started learning javascript.
I want to find the class='id' of the table when I clicked on the class='detail' button.
I manage to point to class='id' but I can't get the value out of it, why?
var button = document.getElementsByClassName("detail");
for (var i in button) {
button[i].onclick = function() {
var row = this.closest("tr");
var id = row.getElementsByClassName("id");
var value = id.innerText;
console.log(id);
console.log(value); //show undefined here
}
}
<table>
<tbody>
<tr>
<td class="id">123</td>
<td class="name">abc</td>
<td><button class="detail">detail</button></td>
</tr>
<tr>
<td class="id">456</td>
<td class="name">def</td>
<td><button class="detail">detail</button></td>
</tr>
</tbody>
</table>
where would need to change? I must use class here, as the table generated through javascript. thanks.
getElementsByClassName returns HTMLCollection containing multiple matching elements. Like an array, you can access the first element in the collection with [0]
var button = document.getElementsByClassName("detail");
for (var i in button) {
button[i].onclick = function () {
var row = this.closest("tr");
var id = row.getElementsByClassName("id");
var value = id[ 0 ].innerText;
console.log(id);
console.log(value);
}
}
<table>
<tbody>
<tr>
<td class="id">123</td>
<td class="name">abc</td>
<td><button class="detail">detail</button></td>
</tr>
<tr>
<td class="id">456</td>
<td class="name">def</td>
<td><button class="detail">detail</button></td>
</tr>
</tbody>
</table>

Javascript: Delete a specific table cell when it is clicked

I was working on a university project. They told us to make 2 arrays. The first will have 3 cells with 3 images, and the second will be empty with 1 row.
I need to remove the image from the cell clicked each time in the first table and copy it to the second table!
My problem is that deleteCell() function will only delete the first element each time. I don't know how to delete the CLICKED cells from my table row!
My JS:
var table1 = document.getElementById("myTable");
var table2 = document.getElementById("myTable2");
function DL1() {
var row = document.getElementById("myRow1");
row.deleteCell();
}
function CR2() {
var row = document.getElementById("myRow2");
}
My HTML:
<table id="myTable" class="auto-style1">
<tr id="myRow1">
<td onclick="DL1()"><img src="../../2.jpg" /></td>
<td onclick="DL1()"><img src="../../1.gif" /></td>
<td onclick="DL1()"><img src="../../3.png" /></td>
</tr>
</table>
<table id="my2Table">
<tr id="myRow2"></tr>
</table>
var table1=document.getElementById("myTable");
var table2=document.getElementById("myTable2");
function DL1(elem){
var row = document.getElementById("myRow1");
for(i=0;i<row.children.length;i++) {
if(row.children[i]==elem) {
row.deleteCell(i);
row2=document.getElementById("myRow2");
row2.appendChild(elem);
}
}
}
<td onclick="DL1(this)"><img src="http://placehold.it/100x100"/></td>
<td onclick="DL1(this)"><img src="http://placehold.it/150x100"/></td>
<td onclick="DL1(this)"><img src="http://placehold.it/200x100"/></td>
Demo: https://jsfiddle.net/Lt2cyw0g/2/
So, you need to get index of clicked element (pass it to the function, and check index, and use it in deleteCell() function), then add element to the second table row...
Just pass clicked element to the function:
var table1 = document.getElementById("myTable");
var table2 = document.getElementById("myTable2");
function DL1(td) {
td.parentNode.removeChild(td);
}
function CR2() {
var row = document.getElementById("myRow2");
}
<table id="myTable" class="auto-style1">
<tr id="myRow1">
<td onclick="DL1(this)">
<img src="../../2.jpg" />
</td>
<td onclick="DL1(this)">
<img src="../../1.gif" />
</td>
<td onclick="DL1(this)">
<img src="../../3.png" />
</td>
</tr>
</table>
<table id="my2Table">
<tr id="myRow2"></tr>
</table>
Hope it helps, no need ID:
var a = document.querySelectorAll("table tr");
for(var b in a){
var c = a[b];
if(typeof c == "object"){
c.onclick = function (){
this.offsetParent.deleteRow(this.rowIndex);
}
}
}
<table >
<tr><td>1</td><td>2</td><td>3</td></tr>
<tr><td>1a</td><td>2a</td><td>3a</td></tr>
<tr><td>1b</td><td>2b</td><td>b</td></tr>
</table>
<table>
<tr><td>a</td><td>aa</td><td>aa</td></tr>
<tr><td>b</td><td>bb</td><td>bb</td></tr>
<tr><td>c</td><td>cc</td><td>cc</td></tr>
</table>

javascript validation of dynamic checkbox

Name and id of checkboxes are appearing dynamically. And we are not sure of number of checkboxes. A map is iterated to generate checkboxes contained in a table. So, each table will have a checkbox with 2-3 options depending on map entries. Javascript should validate that at least one entry of checkbox in a table should be checked.
HashMap<ServerGroup, ArrayList<String>> serversMap = (HashMap<ServerGroup, ArrayList<String>>) session.getAttribute("userServersMap");
Iterator itr = serversMap.entrySet().iterator();
while (itr.hasNext()) {
Map.Entry<ServerGroup, ArrayList<String>> entry = (Map.Entry<ServerGroup, ArrayList<String>>)itr.next();
<table border='1' align="center">
<tr>
<th>Select Server</th>
<th>Servers</th>
</tr>
<%
for (String server : entry.getValue()) {
%>
<tr>
<td><input type="checkbox" name="<%= entry.getKey().getName().toString() %>" value="<%=server%>"></td>
<td><%=server%></td>
</tr>
<%
}
%>
</table>
Try this with JS:
function checkOneCheckbox(){
var checkboxes=document.getElementsByName("your_checkbox_name"); //all should be same
var is_checked=false;
for(var i=0;i<checkboxes.length;i++)
{
if(checkboxs[i].checked)
{
is_checked=true;
}
}
if(is_checked){
//at least one is checked;
}else {
//...
}
}
More easy with jQuery:
// onready method...binding
var is_checked = false;
$('input[type="checkbox"]').each(function() {
if ($(this).is(":checked")) {
is_checked = true;
}
});
The following solution should hopefully work in this case.
Let's assume that your JSP generated the following html page
(say two html tables, it can generate any number of tables though for your case):
<table border='1' align="center">
<tr>
<th>Select Server</th>
<th>Servers</th>
</tr>
<tr>
<td><input type="checkbox" name="serverX" value="TestServer1"></td>
<td>TestServer1</td>
</tr>
<tr>
<td><input type="checkbox" name="serverY" value="TestServer2"></td>
<td>TestServer2</td>
</tr>
</table>
<table border='1' align="center">
<tr>
<th>Select Server</th>
<th>Servers</th>
</tr>
<tr>
<td><input type="checkbox" name="serverM" value="TestServer3"></td>
<td>TestServer3</td>
</tr>
<tr>
<td><input type="checkbox" name="serverN" value="TestServer4"></td>
<td>TestServer4</td>
</tr>
<tr>
<td><input type="checkbox" name="serverO" value="TestServer5"></td>
<td>TestServer5</td>
</tr>
</table>
Then on form submit you can call a Validate function which will iterate through all the tables on your page and if it finds a table without any checked checkbox it will return false and simply focus on the first checkbox of the table.
The Validate function will be :
function Validate()
{
var table = document.getElementsByTagName('table'); // get all the tables on the page
for(var i=0; i<table.length;i++) //loop through each table
{
var flag = false;
for( var j=1; j<table[i].rows.length;j++) // start checking from 2nd row of the table
{
var currentRow = table[i].rows[j];
var cell = currentRow.cells[0];
var elem = cell.getElementsByTagName("input");
if (elem[0].type == "checkbox")
{
if(elem[0].checked)
{
flag=true;
break; // stop checking this table as one checked found
}
}
}
if(j==table[i].rows.length && flag == false)
{
alert("Please select at least one checkbox!");
table[i].rows[1].cells[0].getElementsByTagName("input")[0].focus();//focus on the first checkbox in the table
return false;
}
}
}
Hope it helps!
Working Demo:
http://jsfiddle.net/6cyf4skd/

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