No jQuery.
I want to loop through unknown amount of table rows with the same class and add a click event that will change the class of hidden table row that is right bellow the one i clicked. All i managed to do is open all hidden rows on click..
Here is a fiddle with my current progres: jsfiddle.net
An my js code, that obviously doesn't work...
var x = document.querySelectorAll('.table');
var y = document.querySelectorAll(".content");
for (var i = 0; i < x.length; i++) {
x[i].addEventListener('click', function(event) {
for (var j = 0; j < y.length; j++) {
if (i === j) {
y[j].style.display = "block";
}
}
});
}
EDIT:
Also i saw that it is bad to make functions inside loops. Would appreciate some feedback on that as well...
Try with nextElementSibling function
Demo fiddle
var x = document.querySelectorAll('.table');
for (var i = 0; i < x.length; i++) {
x[i].addEventListener('click', function(event) {
this.nextElementSibling.style.display='block';
});
}
table tr td {
border: 2px solid #000;
}
table {
width: 500px;
height: 40px;
}
.content {
display: none;
width: 100px;
}
.table:hover {
background-color: red;
}
.content.visible {
display: table-cell;
}
<table>
<thead>
<tr>
<th>Tabela</th>
</tr>
</thead>
<tbody>
<tr class="table">
<td>Visible</td>
</tr>
<tr class="content">
<td>Hidden 1</td>
</tr>
<tr class="table">
<td>Visible</td>
</tr>
<tr class="content">
<td>Hidden 2</td>
</tr>
<tr class="table">
<td>Visible</td>
</tr>
<tr class="content">
<td>Hidden 3</td>
</tr>
<tr class="table">
<td>Visible</td>
</tr>
<tr class="content">
<td>Hidden 4</td>
</tr>
</tbody>
</table>
or If you need like toggle effect (reclick to hide) use this js code
var x = document.querySelectorAll('.table');
for (var i = 0; i < x.length; i++) {
x[i].addEventListener('click', function(event) {
var a = this.nextElementSibling.style.display;
this.nextElementSibling.style.display = (a == 'block') ? 'none': 'block';
});
}
Related
I would like to show more information when someone click on show more buttons. The complication is that there are several buttons and informations to toggle with same className.
What am I doing wrong??
var element = document.querySelectorAll("btn");
for (var i = 0; i < button_length ; i++) {
element[i].addEventListener("click", function() {
alert("Button Clicked " + i);
element[i].classList.toggle("extrainfo");
};
}
td{border:solid 1px black;}
.btn, #btn_id{color:blue; text-decoration:underline; cursor:pointer;}
.extrainfo{
display:none
}
<table>
<tbody>
<tr class="info_group">
<td>Title 1</td>
<td class="btn">show more</td>
</tr>
<tr>
<td class="extrainfo" colspan="2">More info 1</td>
</tr>
</tbody>
<tbody>
<tr class="info_group">
<td>Title 2</td>
<td class="btn">show more</td>
</tr>
<tr>
<td class="extrainfo" colspan="2">More info 2</td>
</tr>
</tbody>
<tbody>
<tr class="info_group">
<td>Title 3</td>
<td class="btn">show more</td>
</tr>
<tr>
<td class="extrainfo" colspan="2">More info 3</td>
</tr>
</tbody>
</table>
to work you javaScript
var element = document.querySelectorAll("btn"); // need to be (".btn")
// you want it to be i < element.length; ? or there's a variable called button_length?
for (var i = 0; i < button_length ; i++) {
element[i].addEventListener("click", function() {
alert("Button Clicked " + i);
element[i].classList.toggle("extrainfo");
}; // missing a Parenthesis need to be this }); not this };
}
I'm still not sure about the functionality, but see the code below if that's what you're looking for.
var element = document.querySelectorAll(".btn");
var extraInfo = document.querySelectorAll(".extrainfo");
for (let i = 0; i < element.length; i++) {
element[i].addEventListener("click" , function() {
extraInfo[i].classList.toggle("extrainfo");
});
}
hereJSFiddle you can play around with the code
I have a table with some values that I want to set the color based on the value they have. What I did was this:
window.onload = setColor();
function setColor() {
var elems = document.getElementsByTagName("td");
for (i = 0; i < elems.length; i++) {
if (elems[i].innerText === "Passed") {
elems[i].style.backgroundColor = "green";
} else if (elems[i].innerText === "Failed") {
elems[i].style.backgroundColor = "red";
}
}
}
<table id="myTable">
<tr>
<th style="width:50%;">SET</th>
<th style="width:50%;">TEST STATUS</th>
</tr>
<tr>
<td>Set</td>
<td>Passed</td>
</tr>
<tr>
<td>Set</td>
<td>Passed</td>
</tr>
</table>
But as you can see, I'm looping overall td elements to do that and I think that isn't good, is it?
So I have some questions in mind:
Is there a workaround to set up some kind of onload events for elements that do not support it so I could do something like magicevent=setColor(this)? I expect the table to be stable.
Is what I asked in last question a good practice? If not, what would you recommend?
How could I have achieved what I did in CSS? I don't understand the syntax of CSS within js.
Thank you in advance.
I try answer to your questions:
Your solution is stable and it works in all browsers. Another way to achieve it could be to render the td tags with a specific class and give to the class a css rule without using javascript.
Something like:
<style>
.failed{
background-color: red;
}
.passed{
background-color: green;
}
</style>
<table>
<tr><td class="failed">failed </td></tr>
<tr><td class="passed">passed </td></tr>
</table>
Your solution is stable. Keep in mind that it could be slow if your table has thousands of rows.
When you use elems[i].style.backgroundColor = "red"; you are setting the background-color of the element inside elems in position i. Inside elems[i] there is a specific td.
Another approach is adding a class to a td based on value of test (passed or failed).
However, I suggest the following solution:
<table id="myTable">
<tr>
<th style="width:50%;">SET</th>
<th style="width:50%;">TEST STATUS</th>
</tr>
<tr>
<td>Set</td>
<td>Passed</td>
</tr>
<tr>
<td>Set</td>
<td>Passed</td>
</tr>
</table>
<style>
.failed{
background-color: red;
}
.passed{
background-color: green;
}
</style>
<script>
window.onload = setColor();
function setColor(){
var elems = document.getElementsByTagName("td");
for (i = 0; i < elems.length; i++) {
if (elems[i].innerText === "Passed") {
elems[i].classList.add("passed");
}else if (elems[i].innerText === "Failed"){
elems[i].classList.add("failed");
}
}
}
</script>
Your script could be changed to something like this:
function setColor(){
var elems = document.querySelectorAll("#myTable td:last-child");
for (i = 0; i < elems.length; i++) {
if (elems[i].innerText === "Passed") {
elems[i].style.backgroundColor = "green";
}
else if (elems[i].innerText === "Failed")
{
elems[i].style.backgroundColor = "red";
}
}
}
document.addEventListener("DOMContentLoaded", setColor);
<table id="myTable">
<tr>
<th style="width:50%;">SET</th>
<th style="width:50%;">TEST STATUS</th>
</tr>
<tr>
<td>Set</td>
<td>Passed</td>
</tr>
<tr>
<td>Set</td>
<td>Passed</td>
</tr>
</table>
But it would be better to use CSS classes for coloring text:
if (elems[i].innerText === "Passed") {
elems[i].classList.add("passed");
}
else if (elems[i].innerText === "Failed")
{
elems[i].classList.add("failed");
}
In style.css:
.passed {
background-color: green;
}
.failed {
background-color: red;
}
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 can I make the left column in a table disappear using plain JS?
This is my approach:
<table id="tab" border="1">
<tr>
<td>abc</td>
<td>def</td>
</tr>
<tr>
<td>ghi</td>
<td>jkl</td>
</tr>
<tr>
<td>mno</td>
<td>pqr</td>
</tr>
</table>
<button onclick="inv()">invisible</button>
<button onclick="vis()">visible</button>
<script>
var tab, td;
window.onload = function() {
tab = document.getElementById("tab");
td = tab.getElementsByTagName("td");
}
function inv() {
for (i = 0; i < td.length; i++) {
td[i].style.display = "none";
i++;
}
}
function vis() {
for (i = 0; i < td.length; i++) {
td[i].style.display = "block";
i++;
}
}
</script>
It works, but I have to use "ugly" loops.
Maybe there is a more efficient way by just saying column[0].display = "none".
Here is the fiddle.
Take advantage of CSS hierarchy and nth-child selectors.
Use selector tr td:nth-child(1) to select all the first column td elements.
JSfiddle
var tab;
// Use DOMContentLoaded instead of load event
document.addEventListener('DOMContentLoaded', function() {
tab = document.getElementById('tab');
});
function inv() {
tab.classList.add('hide');
}
function vis() {
tab.classList.remove('hide');
}
.hide tr td:nth-child(1) {
display: none;
}
<table id="tab" border="1">
<tr>
<td>abc</td>
<td>def</td>
</tr>
<tr>
<td>ghi</td>
<td>jkl</td>
</tr>
<tr>
<td>mno</td>
<td>pqr</td>
</tr>
</table>
<button onclick="inv()">invisible</button>
<button onclick="vis()">visible</button>
Demo using toggle with single button.
function toggle() {
document.getElementById('tab').classList.toggle('hide');
}
.hide tr td:nth-child(1) {
display: none;
}
<table id="tab" border="1">
<tr>
<td>abc</td>
<td>def</td>
</tr>
<tr>
<td>ghi</td>
<td>jkl</td>
</tr>
<tr>
<td>mno</td>
<td>pqr</td>
</tr>
</table>
<button onclick="toggle()">Toggle</button>
By the use of some empty css classes and jQuery, you are able to achieve that in a one-liner:
<table id="tab" border="1">
<tr>
<td class="col1">abc</td>
<td class="col2">def</td>
</tr>
<tr>
<td class="col1">ghi</td>
<td class="col2">jkl</td>
</tr>
<tr >
<td class="col1">mno</td>
<td class="col2">pqr</td>
</tr>
</table>
now you can just do:
jQuery(".col1").hide();
(mind the selector with a dot before the class name)
The most efficient solution would be to inject and remove a stylesheet and let the browser do the work.
Fiddle: https://jsfiddle.net/4L4h7ea1/2/
var tab, td;
var hideFirstColumnCss = document.createElement('style');
hideFirstColumnCss.setAttribute('id', 'hideCssStyle');
hideFirstColumnCss.innerHTML = '#tab td:first-child { display: none; }';
window.onload = function () {
tab = document.getElementById("tab");
td = tab.getElementsByTagName("td");
}
function inv() {
document.head.appendChild(hideFirstColumnCss);
}
function vis() {
var style = document.getElementById('hideCssStyle');
style.parentNode.removeChild(style);
}
Use the row tags to get to your cells to hide/show them. That way you can specify an index for the row as all cells are direct children of their row.
var tab, td;
window.onload = function () {
tab = document.getElementById("tab");
tr = tab.getElementsByTagName("tr");
}
function inv() {
for (i = 0; i < td.length; i++) {
tr[i].children[0].style.display = "none";
}
}
function vis() {
for (i = 0; i < td.length; i++) {
tr[i].children[0].style.display = "block";
}
}
When I mouseover one TD in a row I want all the TDs to change background color at the same time, then reverse on mouseout.
How do I do this?
In CSS you could do
tr td { background-color: white }
tr:hover td { background-color: black };
or just
tr { background-color: white }
tr:hover { background-color: black };
if the tds don't have their own background color.
Both should make the row black on mouseover, and white otherwise.
You could also do it in Javascript of course, but that isn't necessary (except for IE6, which doesn't understand the :hover pseudo-class on anything but <a> tags)
var tds = document.getElementsByTagName("td");
for(var i = 0; i < tds.length; i++) {
tds[i].onmouseover = function() {
this.parentNode.style.backgroundColor = "#ff0000";
}
tds[i].onmouseout = function() {
this.parentNode.style.backgroundColor = "#fff";
}
}
This actually changes the background colour of the parent tr, not each td, but it could be easily modified to do so. You could also attach the events to the tr elements instead of the td elements, and then you wouldn't have to use parentNode, but I don't know whether you need to do other stuff in the event handler specifically related to the td.
<table border="1" cellpadding="5" cellspacing="0">
<tr>
<th></th>
<th>Water</th>
<th>Air</th>
<th>Fire</th>
<th>Earth</th>
</tr>
<tr onmouseover="ChangeBackgroundColor(this)" onmouseout="RestoreBackgroundColor(this)">
<td>Spring thunderclouds</td>
<td>Yes</td>
<td>Yes</td>
<td>No</td>
<td>No</td>
</tr>
<tr onmouseover="ChangeBackgroundColor(this)" onmouseout="RestoreBackgroundColor(this)">
<td>Roasting chestnuts</td>
<td>No</td>
<td>No</td>
<td>Yes</td>
<td>Yes</td>
</tr>
<tr onmouseover="ChangeBackgroundColor(this)" onmouseout="RestoreBackgroundColor(this)">
<td>Winter snowbanks</td>
<td>Yes</td>
<td>Yes</td>
<td>No</td>
<td>Yes</td>
</tr>
<tr onmouseover="ChangeBackgroundColor(this)" onmouseout="RestoreBackgroundColor(this)">
<td>Ice cream on a hot summer day</td>
<td>Yes</td>
<td>Yes</td>
<td>Yes</td>
<td>Yes</td>
</tr>
</table>
<script type="text/javascript">
// Specify the normal table row background color
// and the background color for when the mouse
// hovers over the table row.
var TableBackgroundNormalColor = "#ffffff";
var TableBackgroundMouseoverColor = "#9999ff";
// These two functions need no customization.
function ChangeBackgroundColor(row) {
row.style.backgroundColor = TableBackgroundMouseoverColor;
}
function RestoreBackgroundColor(row) {
row.style.backgroundColor = TableBackgroundNormalColor;
}
</script>
I don't know what your exact use-case is, but for such tasks I would stick to CSS only:
td {
background: #f00; }
tr:hover td {
background: #fc0; }
http://jsfiddle.net/feeela/53JBV/
<td onmouseover="changeColorTo(this.parentNode, put color here)" onmouseout="changeColorTo(this.parentNode, put color here)">
...
<script>
function changeColorTo(parent, color)
{
var i, tdArray = parent.getElementsByTagName('td');
for(i in tdArray)
{
tdArray[i].style.backgroundColor = color;
}
}
</script>
This is faster than using jQuery, also, not everybody uses jQuery.
This jsFiddle I created shows you how to do it with jQuery.
I am using jQuery's hover event to handle what you are trying to do.
If you want a framework-agnostic solution, you can try this:
function highlightCells(tableRow) {
for (var index = 0; index < tableRow.childNodes.length; index++) {
var row = tableRow.childNodes[index];
if (row.style) {
row.style.backgroundColor = "red";
}
}
}
function unhighlightCells(tableRow) {
for (var index = 0; index < tableRow.childNodes.length; index++) {
var row = tableRow.childNodes[index];
if (row.style) {
row.style.backgroundColor = "white";
}
}
}
Example: http://jsfiddle.net/9nh9a/
Though practically speaking, wouldn't it be simpler to just bind your listener to the <tr> elements instead of the <td> elements? Is there some reason you want to listen only on the <td> elements?
<style type="text/css">
.table1 tr:hover td{
background-color:#ccc;
}
</style>
<table class="table1">
<tr>
<td>cell 1-1</td>
<td>cell 1-2</td>
<td>cell 1-3</td>
<td>cell 1-4</td>
</tr>
<tr>
<td>cell 2-1</td>
<td>cell 2-2</td>
<td>cell 2-3</td>
<td>cell 2-4</td>
</tr>
<tr>
<td>cell 2-1</td>
<td>cell 2-2</td>
<td>cell 2-3</td>
<td>cell 2-4</td>
</tr>
</table>
$(selector).mouseenter(handlerIn).mouseleave(handlerOut);
You can use code like this:
HTML
<table>
<tr>
<td>cell1,1</td>
<td>cell1,2</td>
<td>cell1,3</td>
</tr>
<tr>
<td>cell2,1</td>
<td>cell2,2</td>
<td>cell2,3</td>
</tr>
</table>
Style sheet
.hover {
background-color: silver;
}
JavaScript
$("td").hover(
function () {
$(this).parent("tr").addClass("hover");
},
function () {
$(this).parent("tr").removeClass("hover");
}
);
The .hover class obviously can be styled as you like.
Regards and happy coding!
In jQuery:
$('td').mouseover(function( obj ) {
$(obj).parent().children().css("background-color","green");
});
$('td').mouseout(function( obj ) {
$(obj).parent().children().css("background-color","red");
});
Or in Javascript:
var tds = document.getElementsByTagName( "td" );
for( var i = 0; i < tds.length; i++ ) {
tds[i].addEventListener("mouseover",function(){
var children = this.parentNode.getElementsByTagName("td");
for( var j = 0; j < children.length; j++ )
children[j].style.background-color = "green";
});
tds[i].addEventListener("mouseout",function(){
var children = this.parentNode.getElementsByTagName("td");
for( var j = 0; j < children.length; j++ )
children[j].style.background-color = "red";
});
}
When I did it in all java script I did it like this
<!DOCTYPE html>
<html>
<head>
<title>Chapter 11 Problem 1</title>
<script>
function blueText()
{
var paragraphObject = document.
getElementById("Paragraph");
paragraphObject.style.color = 'blue',
paragraphObject.style.background= 'white';
}
function whiteText()
{
var paragraphObject = document.
getElementById("Paragraph");
paragraphObject.style.color = 'white',
paragraphObject.style.background = 'blue';
}
</script>
</head>
<body>
<p id="Paragraph" style = "color:white; background-color:blue";
onmouseover="blueText()" onmouseout="whiteText()">
Paragraph Text
</p>
</body>
</html>
I really hope this doesn't garble it all up