Using an eventlistener instead of onclick - javascript

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

Related

DOM Manipulation

Newbie question - Is this code eloquent enough to create four list items? or Should I be using documentFragment instead? The code seems to work fine - JsFiddle.
Created list and li variables
var list = document.getElementById("myList");
var li = null;
Created x number of list elements and companion text nodes
for(var i=1; i<=4; i++){
var li = document.createElement("li");
li.appendChild(document.createTextNode("Number " + i));
Add li to list
list.appendChild(li);
}
Based entirely on the JSFiddle demo you've provided: No. What you currently have is semantically incorrect. You're currently appending your li to the body, not the ul element:
<ul></ul>
<li>Number 1</li>
Change:
document.body.appendChild(li);
To:
list.appendChild(li);
JSFiddle demo.
As for the code you've provided in the question, you also need to change it so that your li elements get appended to your ul element. You also need to change your class into an ID, as getElementById("myList") pulls an element with an ID of "myList", whereas your current ul has no such ID.
Actually there is an error, because you're adding the lis to the body instead of the ul
also the markup is not well created, change
<ul class="myList"></ul>
with
<ul id="myList"></ul>
To use an id and then:
var list = document.getElementById("myList");
var li = null;
for(var i=1; i<=4; i++){
var li = document.createElement("li");
li.appendChild(document.createTextNode("Number " + i));
//document.body.appendChild(li); **error here**
list.appendChild(li); //fix
}

Adding/removing class dynamically

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!

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

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>

Whether particular li with a specific text exists inside a ul using JQUERY

I have a code
like
<ul id="uploadedfiles">
<li>
A_001
</li>
<li>
B_001
</li>
</ul>
Now i want to insert a new li but i want to check that something that whether a li with a text say A_ exist in that ul. If it exists than remove the older and add the new li.
Say if i add C_001 it is added with no issue
But if i add A_002 then it replace the A_001 with A_002.
Please provide the code for the same if possible.
Any help is appreciated!
Added:
The real data in li have text like control20_a.jpg , control21_b.jpg .....
Then when adding a new li say control20_c.jpg the code must replace control20_a.jpg. But add a new li if it does not exists
This is probably not very idiomatic jQuery, but it seems to do the job.
Working Example
var add = function(entry) {
var match = $('#uploadedfiles li:contains(' + entry.slice(0, entry.indexOf('_')) + ')');
if (match.length > 0) {
match.text(entry);
} else {
$('#uploadedfiles').append($('<li>' + entry + '</li>'));
}
}
I would add a class to the li (like <li class="a"> and <li class="b">
When adding the new LI i would strip the first char of the name and find the LI
If no li, I would create it else change the innerHTML for the new one.
Good luck
UPDATE:
if the elements are from 001 to 002 etc you could do
$("ul li").each(function() {
var firstChar = $(this).text().substring(0,1);
var removeElms = $("ul li:contains('"+firstChar+"'):not(:last)");
removeElms.remove();
});

Categories

Resources