Adding/removing class dynamically - javascript

Hello I have a menu and I would like to remove the class active an add it to the element that I click....that was my idea but it is not working so well...
<div id="header2">
<div class="menu">
<ul>
<li id="menu_1" onclick="abrirPag('home.html')">Home</li>
<li id="menu_2" onclick="abrirPag('calendario_2014.html')">Calendário</li>
<li id="menu_3" onclick="abrirPag('classificacao_2014.html')">Classificação</li>
<li id="menu_4" onclick="abrirPag('equipes_2014.html')">Equipes</li>
<li id="menu_5" onclick="abrirPag('recordes.html')">Recordes</li>
<li id="menu_6" onclick="abrirPag('regulamento_2014.html')">Regulamento</li>
</ul>
</div>
</div>
Onload function to add the class active to the first item:
window.onload=function() {
var containermenu = document.getElementById("header2");
var navitemmenu = containermenu.querySelector(".menu ul li");
var identmenu = navitemmenu.id.split("_")[1];
navitemmenu.parentNode.setAttribute("data-current",identmenu);
navitemmenu.setAttribute("class","active");
Function to change the class:
function abrirPag(valor){
var currentmenu = this.parentNode.getAttribute("data-current");
document.getElementById("menu_" + currentmenu).removeAttribute("class");
var identmenu = this.id.split("_")[1];
this.setAttribute("class","tabActiveHeader");
this.parentNode.setAttribute("data-current",identmenu);
I get the following error when I click any of the elements: "Uncaught TypeError: Cannot call method 'getAttribute' of undefined "
Can someone help me?

You can use the dom classList to add remove classes
var element = document.getElementById("someId");
//Use add to add a class
element.classList.add("active");
//use remove to remove a class
element.classList.remove("active");
You will need a polyfill to use it on IE < 10 and some of the older versions of browsers.
To remove from all other menu and add to current do as cookie monster suggest and also pass the element to your function
function abrirPag(ele,valor){
var current = document.getElementsByClassName("tabActiveHeader");
if(current[0]){
current[0].classList.remove("tabActiveHeader");
}
ele.classList.add("tabActiveHeader");
}

The this value in an inline handler will be the window object instead of the element. You need to pass this to get it to the function.
<li id="menu_1" onclick="abrirPag(this, 'home.html')">Home</li>
Then reference it as the first element.
function abrirPag(elem, valor){
var currentmenu = elem.parentNode.getAttribute("data-current");
document.getElementById("menu_" + currentmenu).className = "";
var identmenu = elem.id.split("_")[1];
elem.className = "tabActiveHeader";
elem.parentNode.setAttribute("data-current",identmenu);
}
I also changed it to use the .className property instead of .get/setAttribute() for getting and setting the class.

Here it's a tip: use jQuery, you'll have a much easier life:
$("#header2 .menu li a").on("click", function(e) {
e.preventDefault();
var index = $("#header2 .menu li a").index(this);
$("#header2 .menu li a").removeClass("active").parent().parent().data("current", index);
$(this).addClass("active");
$(".content").text($(this).attr("href"));
});
Take a look at this Fiddle I've created!

Related

.text() not returning value

I'm using this code to create a <ul><li> of the classes attached to the div .lista-produtos.
$(document).ready(function(){
var alts = {};
$('.lista-produtos').each(function(){
var classes2 = $(this).attr('class').split(' ');
for (var i = 0; i < classes2.length; i++) {
var matches2 = /^tipo\-(.+)/.exec(classes2[i]);
if (matches2 != null) {
var produto = matches2[1];
}
}
if(!alts[classes2]){
alts[classes2] = true;
$('ul.filters').append('<li class="filter-produto">'+ produto +'</li>');
}
});
});
The code above generates <li>s inside of the <ul class="filters">. So the code is something like this:
<ul class="filters">
<li class="filter-produto active">Produto 1<li>
<li class="filter-produto">Produto 2<li>
<li class="filter-produto">Produto 3<li>
<li class="filter-produto">Produto 4<li>
</ul>
As you can see, one of the <li>s will have an additional class named "active", and the problem is I need to get the text inside of it (Produto 1) to use on another code but it's not working:
var produto2 = $('li.filter-produto.active').text();
I tested alert(produto2); to see if the code worked but it only returns a blank value and not the text inside the <li>.
Sadly I don't have rep to comment, but can you show us the order of the stuff happening?
Perhaps you are asking for the value before the active class it attached to the li. Something like this:
// Function to create the ul and lis
var produto2 = $('li.filter-produto.active').text();
// Function that adds the active class
So maybe the li.filter-produto.active doesn't exist when you ask for it's value?

JavaScript Not able to set focus to first li element within ul

I have below code:
<ul id='someId'>
<li class='someClass'>
</li>
</ul>
I want to set focus on first li element within ul based on some condition.
My first attempt is like this:
var ul = document.getElementById('someId');
var child = ul.childNodes[0];
child.focus();
My second attempt is like this :
var y = document.getElementsByClassName('someClass');
var aNode = y[0];
aNode.focus();
But none of the above works
Any ideas?
The problem is that you can't focus a non input element without setting tabIndex.
<li tabIndex="-1">...</li>
You can Try this fiddle: jsfiddle
An 'li' can't have focus, however an 'input' can, so you write yourself the following script:
function installLI(obj){
var ul = document.createElement('ul');
obj.appendChild(ul);
var li = document.createElement('li');
var txt = document.createElement('input');
li.appendChild(txt);
ul.appendChild(li);
txt.focus();
li.removeChild(txt);
}
Where 'obj' is the object (like an editable div) that you're appending your list to.

jQuery DOM - Inserting multiple nodes in li (menu)

I know there are dozens of similar topics but I am so dumb I can't learn anything from it.
Other words: My code is just mean and doesn't work with any fixes published online. ;)
My HTML:
<ul id="main_menu">
<li class="menu-item">Link 1</li>
<li class="menu-item">Link 2</li>
<li class="menu-item">Link 3</li>
<li class="menu-item">Link 4</li>
</ul>
and how the LI should look after JS does its magic:
...
<span data-title="Link 1">Link 1</span>
...
JS/JQ mission:
add class="roll-link" to every A
add SPAN right after A tag
add data-title="xxx" attribute to SPAN with A value (text exactly the same as the A)
close SPAN tag before A closing tag
My JS try:
var menuLis = document.querySelectorAll("ul.main_menu li"); //It's an Array right?
for(var i=0; i<menuLis.length; i++) {
this.nextChild.setAttribute('class', 'rollink');
var span = document.createElement('span');
this.nextChild.nextSibling.insertBefore(span); //Auto-closing </span> may be an issue...
span.setAttribute('data-title', hrefvalue[i]); //but how to get value?
}
It may be total crap but I have completely no experience in JS/JQ, only had few hours of basic training online...
Thanks for reading and even bigger thanks for trying to help.
Greets!
it should be as simple using jQuery(because you tagged it with jQuery)
jQuery(function ($) {
$('#main_menu li a').addClass('roll-link').wrapInner(function () {
return $('<span />', {
'data-title': $.trim($(this).html())
});
})
})
Demo: Fiddle
See
selectors
addClass()
wrapInner()
dom ready
To make your code work, first the main_menu is an id, not a class so you need to use id selector, then try
var as = document.querySelectorAll("#main_menu li a");
for (var i = 0; i < as.length; i++) {
as[i].className = 'rollink';
var span = document.createElement('span');
span.setAttribute('data-title', as[i].innerHTML);
span.appendChild(as[i].firstChild);
as[i].appendChild(span)
}
Demo: Fiddle
$('#main_menu > li > a').each(function () {
var text = $(this).addClass('roll-link').contents().first();
text.wrap($('<span>').attr('data-title', text.text()));
});
DEMO: http://jsfiddle.net/Bw723/
Here is your solution with pure Javascript.
//get the li elements
var menuLis = document.getElementById("main_menu").getElementsByTagName('li');
for(var i=0; i<menuLis.length; i++) {
menuLis[i].firstChild.setAttribute('class', 'rollink');
var span = document.createElement('span');
span.setAttribute('data-title', menuLis[i].innerHTML);
//If you want to get href of a then use this one.
//span.setAttribute('data-title', menuLis[i].href);
//appending the span into a
menuLis[i].firstChild.appendChild(span);
}
DEMO

Using an eventlistener instead of onclick

I have a ul that when each li is clicked, the text in its nested span gets sent to an input. I was advised to replace my (many) onclicks- one on each li in the list with an eventlistener on the ul. could use advice on how to do this neatly with same functionality.
html:
<ul>
<li onclick="myfunction(this)"><img src="img1"><span>Some text</span></li>
<li onclick="myfunction(this)"><img src="img2"><span>Some other text</span></li>
</ul>
<input id="field_jd6brw">
Javascript:
function myfunction(li){
document.getElementById("field_jd6brw").value = li.childNodes[1].textContent;
}
simply use jquery :
$("ul li").click(function (){
$("#field_jd6brw").val($(this).text());
});
If you need to stick to plain-vanilla JavaScript, you can use something like this:
function myfunction(){
document.getElementById("field_jd6brw").value = this.children[1].innerHTML;
}
var aLi = document.querySelectorAll('ul li');
for (var i=0, len = aLi.length; i<len; i++) {
aLi[i].addEventListener('click', myfunction, false);
}
Demo: http://jsfiddle.net/Q6Tm5/
This code selects all LI within a UL (use more specific selectors, like ID of UL if needed) and then loops thru each LI element adding the event listener.
Note that this code won't work in old versions of IE - you either need to add IE-specific code or switch to jQuery

How to find number of <ul> inside each div

I have a large file of this form [similar div's throughout]. I want to be able to select a div, find the number of ul's in it and traverse through each of them to get value of each li in it.
<div class="experiment">
<div class="experiment-number">5</div>
<ul class="data-values">
<li><div></div> 14</li>
<li><div></div> 15</li>
</ul>
<ul class="data-values">
<li><div></div> 16</li>
</ul>
</div>
I have tried looping through all experiment divs, then select the uls, but it selects all the ul in the page, not only the ones under current div.
$('experiment ul').eq('$i');
Your HTML is currently incorrect, since you're simply starting new <div> and <ul> elements rather than closing the existing ones. Ignoring that because it's trivial to fix, we'll move on to the real issue.
You need to select all of the <div class="experiment"> elements, then iterate through them. To do that you can use the .each() function. It might look something like this:
var experiments = $('.experiment'); // all of them
experiments.each(function(i, val) { // will iterate over that list, one at a time
var experiment = $(this); // this will be the specific div for this iteration
console.log("Experiment: " + experiment.find('.experiment-number').text());
// outputs the experiment number
console.log("Experiment ULs: " + experiment.find('ul').length);
// number of <ul> elements in this <div>
var total = 0;
experiment.find('ul.data-values li').each(function() {
total += parseInt($(this).text(), 10);
});
console.log("Experiment total: " + total);
// outputs the total of the <li> elements text values
});
Take a look at this jsFiddle demo.
to get all the ul inside div.experiment
var ul = $('.experiment').find('ul');
and to get all li elements inside each ul found above
ul.each(function(list) {
var li = $(list).find('li');
});
$('.experiment').each(function() {
var cnt = $(this).children('ul').length;
$(this).find('.experiment-number').text(cnt);
});
First of all you need to work out the correct selector for each DIV.
The selector you want is:
".experiment"
Notice the . to denote a class selector.
This will allow you access to each DIV element. If you then want to loop though each of these, you can do so like this:
$(".experiment").each(function(){
var div = $(this);
var elementsInThisDiv = div.find("ul");
//you now have a list of all UL elements in the current DIV only
var numberOfElements = elementsInThisDiv.length;
//you now have a count of UL elements belonging to this DIV only
//you can loop the UL elements here
$(elementsInThisDiv).each(function(){
var ul = $(this);
//do something with the UL element
//like get the LI elements...
var liElements = ul.find("li");
});
});
IMPORTANT: There is also an error with your HTML, you need to close your <ul> elements correctly using </ul>

Categories

Resources