I am writing a chrome extension where I working on a webpage which lists some things. So, basically, I am reading that table and doing some calculation in the javascript and showing them. Now, there is a filter option on the webpage. After filtering, it doesn't show some things on the list according to the filter selected. And it does so, by making the display as none. It makes the display as none by doing something like below:
[data-assignee]:not([data-aggr-assignees*="|xyz|"]) {
display: none;
}
So, when I am trying to find the elements whose display is not none to see the filtered items, it is giving all items since looks like it is not changing the CSS property of the items. I checked the style.display values of all the elements and it is coming '' for all. Can someone help me in how can I get the elements whose display is block in this kind of case?
You can query selector the whole document with * and go through each element with a for loop to check if its inline display property is set to none. Of course, this will only handle cases when the element is hidden with inline CSS.
<div style="display: block;">
DIV
</div>
<span style="display: none;"></span>
<script>
var allElems = document.querySelectorAll("*");
var visibleElems = [];
var hiddenElems = [];
for(let i = 0; i < allElems.length; i++){
if(allElems[i].style.display != "none"){
visibleElems.push(allElems[i]);
} else {
hiddenElems.push(allElems[i]);
}
}
console.log("Visible elements: "+visibleElems);
console.log("Hidden elements: "+hiddenElems);
</script>
If you want to check the display property of the elements from the CSS stylesheet, you will need to use window.getComputedStyle.
.hidden{
display: none;
}
<div style="display: block;">
DIV
</div>
<textarea class="hidden"></textarea>
<span style="display: none;"></span>
<style>
</style>
<div class="hidden">
</div>
<select class="hidden"></select>
<script>
var allElems = document.querySelectorAll("*");
var visibleElems = [];
var hiddenElems = [];
for(let i = 0; i < allElems.length; i++){
if(allElems[i].style.display == "none"||window.getComputedStyle(allElems[i], null).getPropertyValue("display")=="none"){
hiddenElems.push(allElems[i]);
} else {
visibleElems.push(allElems[i]);
}
}
console.log("Visible elements: "+visibleElems);
console.log("Hidden elements: "+hiddenElems);
</script>
I am trying to click on each cell on the table so that the selected cells I click on change the background color from white to gray. I am also trying to make it like a toggle so if I click on the cell again the background changes from gray to white, but it is not doing anything. I found a similar question, but the answer was advanced coding. I want to create a simpler code. I checked Firebug, but I do not see any errors. I would appreciate any suggestions. I am new to Javascript.
http://jsfiddle.net/RE006/nyzswnx2/1/
HTML5:
<table class="bingo">
<tr>
<td id="square0"></td>
<td id="square1"></td>
<td id="square2"></td>
</tr>
<tr>
<td id="square3"></td>
<td id="square4"></td>
<td id="square5"></td>
</tr>
<tr>
<td id="square6"></td>
<td id="square7"></td>
<td id="square8"></td>
</tr>
</table>
JS:
var toggleHighlight = function () {
document.td.style.backgroundColor = "#cecece;"
}
window.onload = function () {
getElementsByTagName("td").onclick = toggleHighlight ();
}
First of all: document.getElementsByTagName('td') returns a NodeList and not a single node, so you have to cycle on it to attach the event listener:
JS:
window.onload = function () {
var tds = document.getElementsByTagName("td");
for (var i = 0; i < tds.length; i++)
tds[i].onclick = toggleHighlight;
}
Please note that in the row tds[i].onclick = toggleHighlight;, toggleHighlight doesn't have ( and ) because it is a reference to a function and not a call to a function.
If you want to do things the web dev way, you should use classes instead of setting the color explicitly, so you can have:
JS:
function toggleHighlight() {
var td = this;
if (td.className == 'highlight')
td.className = '';
else
td.className = 'highlight';
}
CSS:
.highlight {
background-color: #cecece;
}
You can see the working example here: http://jsfiddle.net/nyzswnx2/40/
Please note that in order to make window.onload work I selected No wrap - in <body> instead of onLoad in the top left dropdown.
Note that
document.getElementsByTagName returns an array.
when you set onclick, you're going to need a function (function() {}), not the return value of that function (which is undefined in your example of onclick = toggleHighlight ();)
As per your JavaScript, you might want to try something like
var toggleHighlight = function (e) {
var bg = e.target.style.backgroundColor;
if (bg == 'red') {
e.target.style.backgroundColor = '';
} else {
e.target.style.backgroundColor = 'red';
}
}
var prepareTable = function () {
var cells = document.getElementsByTagName("td");
for (var i = 0 ; i < cells.length ; i++) {
cells[i].onclick = function(event) {
toggleHighlight(event);
}
}
}
document.onload = prepareTable();
Fiddle: http://jsfiddle.net/nyzswnx2/47/
you can use jQuery it's more simple.
add a class css :
.gray {
background-color:#efefef;
}
and change your code js with :
$(document).ready(function(){
$('td').on('click',function(){
$(this).toggleClass('gray');
});
});
Demo :
http://jsfiddle.net/nyzswnx2/51/
getElementsByTagName("td").onclick = toggleHighlight ();
First, this line is wrong, since getElementsByTagName() returns a list one is in need for a loop.
var tL = getElementsByTagName("td");
for(var i=0, j=tL.length; i<j; i++) tL[i].onclick = function(){this.style.backgroundColor = "#cecece"}
There is another possibility. Instead of defining an onclick() event for each cell in the table one could use onclick() event on the table and later on use the function document.elementFromPoint() to get the td. Yet the way used in the post (onclick() event on td) is pretty much standard.
To toggle the colors one needs to check whether colors are set yet or not (cecece in this case).
Example
<html>
<head>
<script>
function Init(){
document.querySelector('table').onclick = function(event){colorCell(event)}
}
function colorCell(event){
var tE = document.elementFromPoint(event.clientX, event.clientY);
if (tE.tagName === 'TD') tE.style.backgroundColor = (tE.style.backgroundColor === '') ? '#cecece' : ''
}
</script>
</head>
<body onload = 'Init()'>
<table>
<tr>
<td>0.0</td>
<td>0.1</td>
<td>0.2</td>
</tr>
<tr>
<td>1.0</td>
<td>1.1</td>
<td>1.2</td>
</tr>
<tr>
<td>1.0</td>
<td>1.1</td>
<td>1.2</td>
</tr>
</table>
</body>
</html>
First things first: your fiddle is already set to run the code on window.onload, so you have no need to repeat it. You can just write the code and it will automatically be executed upon load.
Now, for your question: you are attempting to assign an event listener to a Node Collection, while you really want to assign the event listener to each element of said collection. There are many ways to go about it, but you can safely do it like this:
var cells = document.getElementsByTagName('td');
for (var i = 0; i < cells.length; i++) {
cells[i].addEventListener('click', toggleHighlight);
}
Please note two things:
I've used addEventListener instead of assigning the function to the onclick event. I encourage you to look up both ways of assigning events.
When assigning a function to an event or, generally speaking, referring to a function as a variable, you should NOT call the function, but simply refer to it by its name. In this example, I have passed the toggleHighlight function to the addEventListener function as its second parameter just by passing it the name of the function, not by calling it. If you were to call the function, the second parameter passed to the addEventListener function would be the return value of the toggleHighlight function, not a reference to the function itself. I encourage you to look up the differences between calling a function in JavaScript and passing a function as a reference.
Let's take a look to the toggleHighlight function now: this function is somehow special, because it responds to an event. As such, its first parameter is a reference to an event itself, and the function should therefore be written like this:
function toggleHighlight(event) {
var cell = event.target;
cell.style.backgroundColor = '#cecece';
}
See what I did there? I used the event object to get the target of the event, and I've set the style on the target itself. Every time a cell is clicked, the target of the event will refer to the cell on which the event was triggered.
Toggling the color requires your code to be stateful: it must somehow save the state of each cell, and use it to decide which color should be used for the background of the cell. Sure, we could use the color of the cell as a state, but that's not really acceptable so we're going to do some more work to get things working. The first thing you want to do is define the states that will be available, and store the initial state of each cell somewhere. We could updated our code like so:
const SQUARE_OFF = 0;
const SQUARE_ON = 1;
var cells = document.getElementsByTagName('td');
var cellStates = {};
for (var i = 0; i < cells.length; i++) {
cells[i].addEventListener('click', toggleHighlight);
cellStates[cells[i].id] = SQUARE_OFF;
}
Let's look at what I did:
I declared two constants, one for each state, and assigned an arbitrary value to each of them. This is NOT the only way to do it, it's just one way;
I declared the cellStates variable as an empty object. We'll use this to store the states of each cell;
While looping through the cells, I used the current cell's id as the key to be used to store the cell's state within the cellStates object. Initially, all cells are going to be off. At the end of the loop, your cellStates will have a key for each cell with the cell's state stored within.
Now that we have saved the state, we want to update it every time we click on a cell, and change the color of the cell accordingly. Let's update our toggleHighlight function:
function toggleHighlight(event) {
var cell = event.target;
var cellState = (cellStates[cell.id] === SQUARE_OFF) ? SQUARE_ON : SQUARE_OFF;
cellStates[cell.id] = cellState;
cell.style.backgroundColor = (cellState === SQUARE_OFF) ? '#fff' : '#cecece';
}
And, just like that, you can now toggle the color of each cell upon clicking. I encourage you to experiment and understand what's going on here very carefully before moving on to other topics. Have fun and happy learning!
Complete fiddle: http://jsfiddle.net/nyzswnx2/29/
I like to delegate
Vanilla JS
window.addEventListener('load', function(e) {
document.getElementById('tb').addEventListener('click', function(e) {
const tgt = e.target.closest('td');
if (tgt) tgt.classList.toggle('selected')
})
})
table,
th,
td {
border: 1px solid #000;
border-collapse: collapse;
font-size: 1.0rem;
margin: 25px auto 0px auto;
text-align: center;
}
th,
td {
padding: 5px 10px;
}
/* bingo table */
.bingo td {
color: #000;
padding: 20px;
}
.bingo .selected {
background-color: red;
}
<table class="bingo">
<tbody id="tb">
<tr>
<td id="square0"></td>
<td id="square1"></td>
<td id="square2"></td>
</tr>
<tr>
<td id="square3"></td>
<td id="square4"></td>
<td id="square5"></td>
</tr>
<tr>
<td id="square6"></td>
<td id="square7"></td>
<td id="square8"></td>
</tr>
<tbody>
</table>
jQuery
$(function() {
$('#tb tbody').on('click', 'td', function(e) {
$(this).toggleClass('selected')
})
})
table,
th,
td {
border: 1px solid #000;
border-collapse: collapse;
font-size: 1.0rem;
margin: 25px auto 0px auto;
text-align: center;
}
th,
td {
padding: 5px 10px;
}
/* bingo table */
.bingo td {
color: #000;
padding: 20px;
}
.bingo .selected {
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<table class="bingo" id="tb">
<tbody>
<tr>
<td id="square0"></td>
<td id="square1"></td>
<td id="square2"></td>
</tr>
<tr>
<td id="square3"></td>
<td id="square4"></td>
<td id="square5"></td>
</tr>
<tr>
<td id="square6"></td>
<td id="square7"></td>
<td id="square8"></td>
</tr>
<tbody>
</table>
I'm working on making a pixel art painter, and this is beyond puzzling.
As of right now, I have a table that is being dynamically generated based on user specified amounts for "Rows" and "Columns" This works perfectly fine (Although it doesn't seem to work in JSFiddle, but I can assure you that it does indeed work on a webpage as you can see here on my test site ).
What I'm trying to accomplish now can be seen in this fiddle
Pretty straight forward, trying to change "TD" tag's css onclick.
I can't seem to get that functionality working with a dynamically generated table.
Here is what I am currently trying (JSFiddle)
HTML:
Row Count:<input type="text" id="rowcount" />
Column Count:<input type="text" id="columncount" />
<input type="button" onclick="createTable();" value="Create Table" />
<div id="box"></div>
CSS:
table{
width:500px;
height:500px;
}
td{
padding:10px;
margin:10px;
border:1px solid #ccc;
}
.active {
background-color:#aaa;
}
JS/jQuery:
function createTable() {
mytable = $('<table></table>').attr({
id: "basicTable"
});
var rows = new Number($("#rowcount").val());
var cols = new Number($("#columncount").val());
var tr = [];
for (var i = 0; i < rows; i++) {
var row = $('<tr></tr>').attr({
class: ["class1", "class2", "class3"].join(' ')
}).appendTo(mytable);
for (var j = 0; j < cols; j++) {
$('<td></td>').text("text1").appendTo(row);
}
}
console.log("TTTTT:" + mytable.html());
mytable.appendTo("#box");
}
$(function () {
$('td').click(function () {
$(this).toggleClass('active');
});
});
Any help or suggestions are greatly appreciated.
Yes it won't work. Since the entire table are created dynamically they are not getting attached to the document (ie., The problem with dynamically created elements, is that they aren't born with the same event handlers as the existing elements. ).
So you have to go for event delegation attached to document.
$(function () {
$(document).on('click', 'td', function () {
$(this).toggleClass('active');
});
});
JSFiddle
Hope you understood.
You are binding click on 'td' before 'td' is created. Bind click inside createTable() method after 'td's have been added to the DOM.
function createTable()
{
// your code
$('td').click(function ()
{
$(this).toggleClass('active');
});
}
Adding jsfiddle link.
http://jsfiddle.net/y94K8/4/
I have a table with four rows, each one with an "id", and inside each one link with a text.
I want to change the innerHTML of the clicked link with the next one link innerHTML.
So if I have this:
ONE
TWO
THREE
FOUR
and I click on TWO for example, the result must be:
ONE
THREE
TWO
FOUR
As follows my code, which already change the order of the two first links, but it does the same if I click another link.
<html>
<head>
<script type="text/javascript">
function change()
{
var link = document.getElementsByTagName("a");
var i = 0;
var aux = link[i].innerHTML;
link[i].innerHTML = link[i+1].innerHTML;
link[i+1].innerHTML = aux;
}
</script>
</head>
<body>
<table border="1">
<tr id="1"><td>ONE</td></tr>
<tr id="2"><td>TWO</td></tr>
<tr id="3"><td>THREE</td></tr>
<tr id="4"><td>FOUR</td></tr>
</table>
</body>
</html>
I've been working on this all day and I can't see what else can I do. I'm starting with both Java and Javascript, so the use of arrays and the DOM and Javascript functions is new to me.
How does the code know which link was clicked? If you don't tell it, it can't deduce it magically.
First off, remove all those id attributes. They serve no purpose here and will only lead to confusion.
Next, pass this as the first argument of change: onclick="change(this);" and function change(link) {...}.
Now, rewrite your change function to find the right link to change link with, and do the swap as you are now.
Good luck.
You seem to want to do something like:
<style type="text/css">
.shifter {
color: blue;
text-decoration: underline;
cursor: pointer;
}
</style>
<script>
function shiftRows(e) {
var el = e.target || e.srcElement;
var row, tbody;
if (el.tagName.toLowerCase() == 'span' && el.className == 'shifter') {
row = el.parentNode.parentNode;
tbody = row.parentNode;
if (row.rowIndex > 0) {
tbody.insertBefore(row, tbody.rows[row.rowIndex - 1]);
}
}
}
</script>
<table id="t0" onclick="shiftRows(event);">
<tr><td><span class="shifter">0</span>
<tr><td><span class="shifter">1</span>
<tr><td><span class="shifter">2</span>
<tr><td><span class="shifter">3</span>
</table>
I have the following example http://jsfiddle.net/zidski/MxqRu/1/
When you click on 2010 I need valuation to disappear with the list items.
Here is the code which I am using to do this:
$("#yearfilter a").live("click", function(e) {
e.preventDefault();
//var v = $(this).val();
var v = $(this).attr("data-value");
if(v.length > 0) {
$('tr.reports').show();
$('tr.reports ul').hide();
$('tr.reports ul.year-'+v).show();
$('tr.reports').each(function() {
if($('ul:visible', this).size() == 0) {
$(this).hide();
}
});
} else {
$('tr.reports').show();
$('tr.reports ul').show();
}
});
I have done it in my project something like this:
function toggleRow(row_id) {
row_selector = "#row_" + row_id;
$(row_selector).toggleClass("shown hidden")
}
Then in the CSS:
.hidden {display:none;}
.shown {}
Then in the HTML I have alternating table rows, where the odd rows act as headings for the content in the even rows. Clicking an odd row toggles the visibility of the corresponding even row.
...
<tr onclick="toggleRow(17)">...</tr>
<tr class="hidden" id="row_17">...</tr>
...
Give each tr an ID something like id="row_2010" then look for that and hide the whole entire row at once.
UPDATE
I would strongly suggest not using so many tables and use more classes to classify your data structure. It would help your javascript be much more clean, concise and function easier.
UPDATE
I adjusted all your javacsript and some of your html. Here is a fully working example jsFiddle Demo