javascript collapsible table without jquery - javascript

This is a simple question I can't seem to figure out and every google search returns a million ways to do this via jquery, but I'd prefer to use vanilla javascript because I am new to it and want to learn it well before using any libraries. What I am trying to do is have a button collapse part of a table when clicked and then show those hidden parts again when clicked again. Basically just toggling the display of a class of elements.
I have a button that calls the test() function
when clicked nothing on my table changes. Here is my javascript code. I am using collapse[0] because if I understand it correctly collapse is a nodeList and I always close and open all of these together so I only need to check the first element.
function test() {
var collapse = document.getElementsByClassName("catOne");
var i = 0;//Counter for loops
if(collapse[0].style.display === "table-row"){
for(i = 0; i < collapse.length; i += 1){
collapse[i].style.display = "none";
}
}
if(collapse[0].style.display === "none"){
for(i = 0; i < collapse.length; i += 1){
collapse[i].style.display = "table-row";
}
}
}
I've tested the function with this code:
function test() {
var collapse = document.getElementsByClassName("catOne");
var i = 0;//Counter for loops
for (i = 0; i < collapse.length; i += 1) {
collapse[i].style.display = "none";
}
which works fine on collapsing the elements so evidentally the issue is with my if statement, but my IDE, Netbeans, doesn't throw any errors and as far as I can tell it should be working.
Thanks for the help.
Link to html and javascript: https://jsfiddle.net/ozjbekjy/

I suspect there are a few problems working against you.
First, you need to make sure the test() function is defined earlier in the page than it's being used. With jQuery, that means using the $(function(){}) wrapper to apply event handlers on DOM ready. You can approximate the same thing yourself with something like this answer.
Otherwise, simply place the <script> tag somewhere before the table (probably in the <head>), and the onclick will work.
You also are using i += 1 where you could be using i++ - they accomplish the same behavior.
Secondly, instead of manipulating the style attribute, use the classList.toggle() function to simply add and remove a class that has the rule display: none, like so:
CSS
.hide-me {
display: none;
}
JavaScript
function test() {
var collapse = document.getElementsByClassName("catOne");
for (var i = 0; i < collapse.length; i++) {
collapse[i].classList.toggle("hide-me");
}
}
Your JSFiddle, with the suggested updates: https://jsfiddle.net/ozjbekjy/4/

Related

how to have div contain only the element from last (javascript) function call (if called multiple times)?

So I am creating a table through javascript,
Part of my assignment says: "the output div should only contain the table of the most recent call"
It is a class where we don't talk too much syntax and I am new to web development and javascript.
I have this function and it works:
<body>
<div id="output"></div>
<script type="text/javascript">
var functionCreate = function(strInput) {
var dividedArray = strInput.split("\n");
var dLength = dividedArray.length;
var myRow, myCell;
var myNewTable = document.createElement('table');
myNewTable.border = "1"
for(var i = 0; i< dLength; i++){
if(dividedArray[i].length >0){
myRow = myNewTable.insertRow(-1);//here
for(var j = 0; j<dividedArray[i].length;j++){
if(dividedArray[i][j] != ','){
myCell = myRow.insertCell(-1); //here
myCell.innerHTML = dividedArray[i][j]
}
}
}
}
document.getElementById("output").appendChild(myNewTable);
};
</script>
</body>
When its called one time, it does what it is supposed to do. When it is called twice, I get two tables, naturally(?)
However I have no idea how to only use the table from last call . I have no access to where it is being called. Can anyone direct me towards the right direction? What is the most basic and straight forward approach that I should take to implement this?
The reason why your code is adding new tables is due to the line of code here:
document.getElementById("output").appendChild(myNewTable);
The function appendChild appends (adds) a child (myNewTable) to the end of the element of id output.
So when u run the function multiple times, it just keeps adding a newly created myNewTable element to the output div.
To make sure it only appends the latest table, clear the output div with something like document.getElementById('output').innerHTML = ""; at the beginning of your function

jQuery, using for loops to manipulate elements? (adding/removing classes etc)

function roomGen(minimum, maximum, interv) {
for (var i = minimum; i < maximum; i += interv) {
room = "#room" + i;
$(room).addClass('currentRoom');
console.log(room);
}
}
roomGen(1,20,1);
Hey all. I am trying to dynamically add classes to multiple divs at the same time via specific ids . I have divs with the id #room.. from numbers 1-100.
I was expecting the function to be the equivalent of typing:
$('#room1').addClass('currentRoom');
$('#room2').addClass('currentRoom');
etc...
However it is not giving me what I had hoped for. The console.log method is returning what I was expecting (#room1, #room2) and I am not receiving any errors with JS/jQuery regarding syntax or the elem not being recognised. Basically, when I trigger the roomGen() function... quite literally nothing happens.
I have tried collocating quotation marks (room = "'"+"#room"+i+"'"), I have tried using i.toString() and I have also tried adding the rooms to an array and accessing them. None of which has worked for me.
Any idea if this is possible to do? It seems like it should be.
Your code is working, be sure to add your script inside $(document).ready() or add the script after the DOM elements targeted.
$(document).ready(function() {
function roomGen(minimum, maximum, interv) {
for (var i = minimum; i < maximum; i += interv) {
room = "#room" + i;
$(room).addClass('currentRoom');
console.log(room);
}
}
// generate stub data for test
for (var i = 0; i < 100; i += 1) {
$("#rooms").append('<div id="room'+i+'">room'+i+'</div>');
}
roomGen(1, 20, 2);
});
.currentRoom{
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="rooms"></div>
jQuery operates on sets of elements. Select and filter the right elements and you don't need loops at all.
$("*[id^=room]").filter(function () {
return 0 + this.id.replace("room", "") <= 100;
}).addClass('currentRoom');

JavaScript - Toggle function

Im trying to hide/show a JS function I have defined in a chrome extension.
What I have so far:
The span classes I am trying to hide are label:
dspan.className = "cExtension";
//Create toggle button:
function createToggleButton(){
var toggleButton = document.createElement("button");
toggleButton.innerHTML = "Toggle Overlay";
toggleButton.id = "Toggle"
var header = document.getElementById("header");
header.appendChild(toggleButton);
toggleExtension();
}
// find all spans and toggle display:
function toggleExtension(){
var spans = document.getElementsByTagName('span');
var toggle = function() {
for (var i = 0, l = spans.length; i < l; i++) {
if (spans[i].getAttribute('class') == 'cExtension')
if (spans[i].style.display == 'none') spans[i].style.display = '';
else spans[i].style.display = 'none';
}
}
document.getElementById('Toggle').onclick = toggle;
}
The button shows on the header, however it is unclickable. If I change document.getElementById('Toggle').onclick = toggle; to document.getElementById('Toggle').onclick = alert{"Hello"); the alert is triggered on page load on not onclick. I am trying to get this done in pure JS. Where am I going wrong?
First of all, document.getElementById("Toggle").onclick = alert("Hello"); will set the onclick event to whatever the alert function returns, not the alert function itself. So the alert function happens at page load so it can figure out what to return. So you could do this: document.getElementById("Toggle").onclick = function(){alert("Hello");}; and that might work.
Edit: Scratch everything that was here: I missed that toggle variable set to a function in toggleExtension.
I haven't tested all this so I can't guarantee that it'll all work in your specific case.
if visible is set remove it, otherwise add it
div.classList.toggle("visible");
add/remove visible, depending on test conditional, i less than 10
div.classList.toggle("visible", i < 10 );
Make sure browser support: http://caniuse.com/#feat=classlist
Why not use jQuery?
It will do all hard job for you.
http://api.jquery.com/toggle/
Cheers!

How to improve jQuery performance with appending icons?

I am building a spreadsheet editor with jQuery and I am encountering performance issues with big tables.
The table holds many data sets and when clicked on one, icons are added to the first cell of the other sets. The code looks like this:
$('.click_icon').remove();
for (var i = 0; i < datasets.length; i++) {
var first_cell = $('td.content[dataset="' + datasets[i].id + '"]').filter(':first');
if (in_group(datasets[i].id)) {
first_cell.append('<i class="icon-remove click_icon remove_group" style="float:right"></i>');
} else {
first_cell.append('<i class="icon-magnet click_icon add_group" style="float:right"></i>');
}
with 500+ datasets this takes about 5 seconds. in_group() is just a small function which checks if the set is in a group with the selected data set.
I was wondering if creating the icons prior to the click and using show() hide() would be faster? Any other ideas?
I am using Chromium on Ubuntu. (Version 28.0.1500.52 Ubuntu 12.04)
Build the table in memory and only change the DOM once :
$('.click_icon').remove();
var table = $('table');
var clone = table.clone(true);
for (var i = 0; i < datasets.length; i++) {
var _class = in_group(datasets[i].id) ?
'icon-remove click_icon remove_group' :
'icon-magnet click_icon add_group',
elem = $('<i />', {'class': _class, style:'float:right'});
$('td.content[dataset="' + datasets[i].id + '"]', clone).filter(':first')
.append(elem);
}
table.replaceWith(clone);
This is a general example, you may have to adjust this to make it work properly with your markup.
I'd normally use plain JS for performance, and documentFragments, but I think jQuery uses fragments internally when doing it this way.
In my experience, appending element by string is worst for performance than creating element by DOM.
So try anything like this:
if (in_group(datasets[i].id)) {
var i = document.createElement('i');
i.className = 'icon-remove click_icon remove_group';
i.style.float = 'right';
first_cell.appendChild(i);
}
If you expect the users to click, I think creating the icons prior to the click is a good idea.
Instead of show/hide which toggles the display property, you could use the visibility property. When the visibility changes from hidden to visible, the browser doesn't need to recalculate the layout.

How to change the color of the links with javascript?

I want to know how can I manipulate all the links on a page with javascript. I can get elements by id's with document.getElementById(id), but how can I get the links? And also how can I get all elements with a certain classname? I want to change the color of the link and class elements.
I mean these links:
This is a link
And an example for an element with a class:
<span class="link">This is an element with a class</span>
Please no jquery. I want javascript.
Simple and straightforward (in pure JS too!)
colorLinks("#00FF00");
function colorLinks(hex)
{
var links = document.getElementsByTagName("a");
for(var i=0;i<links.length;i++)
{
if(links[i].href)
{
links[i].style.color = hex;
}
}
}
If it's a class name you're looking for and you know the tag, just use this.
var elements = document.getElementsByTagName("span");
for(var j=0;j<elements.length;j++)
{
if(elements[j].className === "your class here")
{
//do something
}
}
You can also look at getElementsByClassName and querySelectorAll. Both have support in most new browsers.
The pure-JavaScript version isn't all that complicated:
var elements = document.getElementsByTagName('a');
for (var i = 0; i < elements.length; i++) {
if (elements.className.split(/\s+/).indexOf('red') !== -1) {
elements[i].style.color = 'red';
}
}
And for modern browsers:
var elements = document.querySelectorAll('a.red');
[].slice.call(elements).forEach(function(elem) {
elem.style.color = 'red';
});
Update: I still recommend using jQuery, but, if you want to learn how to do it without, I would recommend heading over to this site. This shows how to change link colors when you mouse over the link, but you can easily extrapolate for your specific situation: Javascript Change Link Text Color onmouseover
--
Ottomanlast has a good point about checking out jQuery to help you out with this task (although it can be done without the use of a library). However, just so you have an example of what he is talking about, here is how you could change link colors using jQuery.
$('.linkClass').click(function(){
$(this).css('color', 'green');
});
This example changes the color of a specific link when it is clicked.
$('a').css('color', 'green');
This example will change all the links to a green color.
$('.linkClass').click(function(){
$(this).removeClass('oldClass');
$(this).addClass('newClass');
});
This does the same thing as the first example, but this removes and adds CSS classes that you already have defined elsewhere. (I would recommend this method over just editing the CSS directly.)
Anyway, the point I'm trying to make is that jQuery makes it extremely easy to select and then make changes to the objects within your HTML document. You may want to take a look into it.
You can use document.getElementsByTagName("a"). This function returns an array of the <a> elements in the page. Loop over this array, and use .style.color = "#000000" in each element.
This is how I change all hyperlink colors (normal/hover):
function changeTextHyperlinkColours(inputColorNormal, inputColorHover) {
var sheets = document.styleSheets;
var slen = sheets.length;
for(var i=0; i<slen; i++) {
var rules = document.styleSheets[i].cssRules;
var rlen = rules.length;
for(var j=0; j<rlen; j++) {
if (rules[j].selectorText == 'a') {
rules[j].style['color'] = inputColorNormal;
}
if (rules[j].selectorText == 'a:hover') {
rules[j].style['color'] = inputColorHover;}
}
}
}
}
Also you can embed the link text in the span and change the color
<a href='www.mydomain.com'><span onclick='this.style.color="red"'>Visit Us</span></a>

Categories