Javascript: Issue when using .click method - javascript

Firsty here is the html which corresponds with the code
<div class="grid_12">
<ul id="categories">
<li class="filter">Categories:</li>
<li id="ny"> New York</li>
<li id="sc">Spanish Cities</li>
<li id="gv">A Glasgow Viewpoint</li>
<li id="sch">Some Churches</li>
<li id="bh">Barcelona Highlights</li>
<li id="mp">Martin’s Pictures</li>
</ul>
</div>
<!-- end .grid_12 - CATEGORIES -->
The idea here is that when each of these links are pressed a var id is changed to the correct number depending on which is clicked
Here is the code i have used to do this
if (nyView.click) {
id = 1;
} else if (scView.click) {
id = 2;
} else if (gvView.click) {
id = 3;
} else if (schView.click) {
id = 4;
} else if (bhView.click) {
id = 5;
} else if (mpView.click) {
id = 6;
}
the view vars are simply locators to find the correct div element so they are done like this
nyView = document.getElementById('ny');
scView = document.getElementById('sc');
gvView = document.getElementById('gv');
schView = document.getElementById('sch');
bhView = document.getElementById('bh');
mpView = document.getElementById('mp');
My issue is that no matter the element i clicked i only get the orginal... for me it seems like the code groups it all together so when u click the ny link it takes this as all other divs are clicked. This was tested as when i clicked the ny link innerHTML in all divs was executed... i am completely stuck as to why this is so would greatly appreciate the help

You don't need inline event handlers
You can use event delegation
Use index to get the clicked element index in ul
HTML
<div class="grid_12">
<ul id="categories">
<li class="filter">Categories:</li>
<li id="ny"> New York
</li>
<li id="sc">Spanish Cities
</li>
<li id="gv">A Glasgow Viewpoint
</li>
<li id="sch">Some Churches
</li>
<li id="bh">Barcelona Highlights
</li>
<li id="mp">Martin’s Pictures
</li>
</ul>
</div>
Javascript
var id;
$('#categories').on('click', 'li>a', function () {
id = $(this).closest('li').index();
});
Demo: http://jsfiddle.net/tusharj/q9xbqck0/3/

When you say nyView.click you are referring to the function definition and that would always be treated as true value, so you would get first condition always.
var id;
$('#categories').on('click', 'li', function(){
id = this.id; // id = $(this).index();
});

My approach is very different, maybe someone else can work with your logic. I can't. My approach:
<div class="grid_12">
<ul id="categories">
<li class="filter">Categories:</li>
<li class="licategory" data-val="ny" data-id="1"> New York</li>
<li class="licategory" data-val="sc" data-id="1">Spanish Cities</li>
<li class="licategory" data-val="gv" data-id="1">A Glasgow Viewpoint</li>
<li class="licategory" data-val="sch data-id="1"">Some Churches</li>
<li class="licategory" data-val="bh" data-id="1">Barcelona Highlights</li>
<li class="licategory" data-val="mp" data-id="1">Martin’s Pictures</li>
</ul>
$("li").on("click",function(){
$("this").data("val");
$("this").data("id");
})

Add one common class like .categoryin all li and get the index()
$(".category").click(function(){
// console.log(this.id);
alert($(this).index())
});
Fiddle

nyView.click returns a function that's why value of id =1 always no matter which link you clicked.....try this code
<!doctype html>
<html>
<head>
<script>
function getImageCategories(element) {
var nyView = document.getElementById('ny');
var scView = document.getElementById('sc');
var gvView = document.getElementById('gv');
var schView = document.getElementById('sch');
var bhView = document.getElementById('bh');
var mpView = document.getElementById('mp');
var id=0;
if (element.parentNode === (nyView)) {
id = 1;
} else if (element.parentNode===scView) {
id = 2;
} else if (element.parentNode===gvView) {
id = 3;
} else if (element.parentNode===schView) {
id = 4;
} else if (element.parentNode===bhView) {
id = 5;
} else if (element.parentNode===mpView) {
id = 6;
}
alert(id);
}
</script>
</head>
<body>
<div class="grid_12">
<ul id="categories">
<li class="filter">Categories:</li>
<li id="ny"> New York</li>
<li id="sc">Spanish Cities</li>
<li id="gv">A Glasgow Viewpoint</li>
<li id="sch">Some Churches</li>
<li id="bh">Barcelona Highlights</li>
<li id="mp">Martin’s Pictures</li>
</ul>
</div>
</body>
</html>

Related

How to reset with an eventListener in Javascript

i have this assignment running good but stuck on where i have to reset values. i have tried .removeEventListener which doesn't work the way i want it and also i don't wanna reload the page. Below are my codes...
Html
<!DOCTYPE html>
<html>
<head>
<title>Table Soccer Teams</title>
<link rel="stylesheet" type="text/css" href="soccer.css" />
<script type="text/javascript" src="table_soccer.js" ></script>
</head>
<body>
<a id="reset" href ="#" class="btn" >Reset</a>
<div id="soccer_field">
<div class="players" onsubmit="return(validateForm ());">
<h2>Possible Players</h2>
<ul id="first">
<li class="list-item">Player 1</li>
<li class="list-item">Player 2</li>
<li class="list-item">Player 3</li>
<li class="list-item">Player 4</li>
<li class="list-item">Player 5</li>
<li class="list-item">Player 6</li>
<li class="list-item">Player 7</li>
<li class="list-item">Player 8</li>
</ul>
<p class="three">Click on names above to select player </p>
</div>
<div class="actual_players">
<h3>Actual Players</h3>
<ul id="actual-players" ></ul>
<p class="two">Click button below to generate Teams</p>
<a id="generate" href ="#" class="btn">Click here</a>
</div>
<div class="teams">
<h1>Teams</h1>
<h4>Team 1</h4>
<p id="forward-one"><span>Forward:</span></p>
<p id="defender-one"><span>Defender:</span></p>
<h5>Team 2 </h5>
<p id="forward-two"><span>Forward:</span></p>
<p id="defender-two"><span>Defender:</span></p>
</div>
</div>
</body>
</html>
Javascript
function init(){
var listItems = document.getElementsByClassName("list-item");
for(var i=0; i<listItems.length; i++){
listItems[i].addEventListener("click", function(){
var text = this.innerHTML;
var liElement = document.createElement("LI");
liElement.ClassName = "test";
var text = document.createTextNode(text);
liElement.appendChild(text);
var lis = document.getElementById("actual-
players").getElementsByTagName("li");
if (lis.length == 4){
alert("Don't let more than four players");
} else {
document.getElementById("actual-
players").appendChild(liElement);
this.remove();
}
});
}
document.getElementById("generate").addEventListener("click",
function(){
var temp = [];
var t = document.getElementById("actual-
players").getElementsByTagName("li");
for(var i=0; i<t.length; i++){
temp.push(t[i]);
}
var x = temp.length;
if (x < 4 || x == null) {
alert("Actual players field must not be empty or have less
than 4 players");
return false;
}
var positions = ["forward-one", "defender-one", "forward-two",
"defender-two"];
for (var i = 0; i < 4; i++){
var index = Math.floor(Math.random()*temp.length);
var player = temp[index];
document.getElementById(positions[i]).appendChild(player);
temp.splice(index, 1);
}
});
Below is where i wanna write my reset codes... i want the distributed players to be removed when reset is clicked...
document.getElementById("reset").addEventListener("click", function()
{
});
Here is the doc of element.removeEventListener
Try to pass a named function (not an anonymous one) to addEventListener and removeEventListener.
var generate_element = document.getElementById("generate");
var generate_func = function(){...};
generate_element.addEventListener("click",generate_func);
// and later in your code
generate_element.removeEventListener("click",generate_func);
Removing the event listener will not change the DOM tree itself.
You can either populate it using an id and use
document.removeChild(document.getElementById("yourId"))
but then you need to keep track of "yourId" when creating it. -In case you will need this value later it could make sense.
OR
you can simply clear the content:
document.getElementById("forward-one").innerHTML = "<p id='forward-one'><span>Forward:</span></p>";
but in that case make it nicer and move the id to a div in html:
<p><span>Forward:</span><div id="forward-one">Apa, www</div></p>
and then use:
document.getElementById("forward-one").innerHTML = "";

Pure JavaScript way to store a var of a link within a list

I can't edit my HTML but I wanted to store a variable of the anchor within a list item so that I can make an onclick event.
At the moment nothing seems to work and I'm assuming it's probably the querySelectorAll being used incorrectly. Help appreciated.
//set the link class on nav items
var link = document.querySelectorAll('.nodiv a');
console.log(link);
link.onclick = function(e) {
e.preventDefault();
alert("clicked!");
}
<ul>
<li class="nodiv">Link</li>
<li class="nodiv">Link</li>
<li class="nodiv">Link</li>
<li class="nodiv">Link</li>
</ul>
querySelectorAll returns a node list, so you have to loop through the list to get the actual nodes.
//set the link class on nav items
var link = document.querySelectorAll('.nodiv a');
console.log(link);
for (var i = 0; i < link.length; i++) {
link[i].onclick = function (e) {
e.preventDefault();
alert('clicked!');
}
}
<ul>
<li class="nodiv">Link</li>
<li class="nodiv">Link</li>
<li class="nodiv">Link</li>
<li class="nodiv">Link</li>
</ul>
You tried to add the onclick function to an array of elements. You need to set it to one single element like this:
//set the link class on nav items
var link = document.querySelectorAll('.nodiv a');
console.log(link);
for(var i=0;i<link.length;i++) {
link[i].onclick = function(e) {
e.preventDefault();
alert("clicked!");
}
}
<ul>
<li class="nodiv">Link</li>
<li class="nodiv">Link</li>
<li class="nodiv">Link</li>
<li class="nodiv">Link</li>
</ul>

How to set the active class on progress bubbles in Javascripts

I am trying to set the active class on my progress bubbles with a click of a button on my web page
<div ng-show="step.one" class="progress-bubble-container">
<ul class="progress-bubbles">
<li id="gs1" class="active">1</li>
<li id="gs2">2</li>
<li id="gs3">3</li>
<li id="gs4">4</li>
</ul>
</div>
I have four steps and each step pass in the step number to my javascript method
<a ng-click="SubmitRegistration(1)" class="btn btn-primary main-btn pull-right next-step">Register</a>
I tried something like this:
$scope.setNavigation = function(num) {
var nextStep;
nextStep = num + 1;
return $("#gs" + nextStep).addClass('active');
};
This is not working. What am I doing wrong here?
you can do that with simple counter
your html:
<ul>
<li class="step"></li>
<li class="step"></li>
<li class="step"></li>
</ul>
<div class="stepContent"></div>
<div class="stepContent"></div>
<div class="stepContent"></div>
your js:
var steps = $(".step"),
cntns = $(".stepContent"),
current = 0;
//default step activation
setStep(current);
steps.click(function(e){
current = $(this).index();
setStep(current);
});
function setStep(num){
step.removeClass("isActive").eq(num).addClass("isActive");
cntns.removeClass("isActive").eq(num).addClass("isActive");
}

How to get the prev and next elements of a particular class which are not siblings

Here is my code :
<ul>
<li class="active">
<div class="course_video_heading"><span class="minus"></span> Introduction <div class="course_duration" align="right">1m 21s</div></div>
<ul>
<li class="course_video viewed">
Welcome <div class="course_duration" align="right">1m 21s</div>
</li>
<li class="course_video viewed">
I need to select this <div class="course_duration" align="right">1m 21s</div>
</li>
</ul>
</li>
<li>
<div class="course_video_heading"><span class="plus"></span> Warm up <div class="course_duration" align="right">1h 15m</div></div>
<ul>
<li class="course_video viewed current">
Roll down <div class="course_duration" align="right">57s</div>
</li>
<li class="course_video">
Roll down with demi pointe variation <div class="course_duration" align="right">57s</div>
</li>
<li class="course_video" data-file="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4" data-image="http://content.bitsontherun.com/thumbs/nPripu9l-480.jpg">
Side roll down <div class="course_duration" align="right">57s</div>
</li>
<li class="course_video">
Side roll down variation with contraction <div class="course_duration" align="right">57s</div>
</li>
<li class="course_video">
Class exercise <div class="course_duration" align="right">57s</div>
</li>
</ul>
</li>
<li>
<div class="course_video_heading"><span class="plus"></span> Brushes <div class="course_duration" align="right">1h 5m</div></div>
<ul>
<li class="course_video">
Welcome <div class="course_duration" align="right">1m 21s</div>
</li>
</ul>
</li>
</ul>
My requirement : There is a element, <li class="course_video viewed current">, I need the previous li which has course_video class. In this case it would be :
<li class="course_video viewed">
I need to select this <div class="course_duration" align="right">1m 21s</div>
</li>
What have I tried :
$(".current").prev(".course_video")
This is not working as it is in different li
Note : It is not the duplicate of following questions :)
jQuery to find nearest Div of Parent
Getting next closest select element with jquery
jquery find closest previous sibling with class
Try this : read the index of current li and if it is 0 then find the previous li of its parent li and then find the course_video. And if index is not 0, then find previous li using prev()
var index = $(".current").index();
if(index==0)
{
var previousLi = $(".current").closest('li').prev('li').find("li.course_video:last");
}
else
{
var previousLi = $(".current").prev(".course_video");
}
var vindex;
$().ready(function () {
$("li .course_video").each(function (index) {
if ($(this).hasClass('current')) {
vindex = index;
}
});
$("li .course_video").each(function (index) {
if (index == vindex - 1) {
alert($(this)[0].outerHTML);
}
});
});
this code will help you.
$('.current').parents('li').prev().find('li:last')
Here's the jsFiddle
You can do it easily with a function that checks the index of the item: if the index is 0 then you'll select the last li in the previous ul.
Element.prototype.previousLi = function() {
var i = $(this).index(),
n = this.parentElement.previousSibling.children.length;
if (i) return this.parentElement.children[i-1];
else return this.parentElement.previousSibling.children[n-1];
}
Then you can do:
var el = $(".course_video.viewed.current")[0];
var previous = el.previousLi();
Try this code , it will give you the desired result :
<script>
var currentLI = $("li.current");
prevLi=$(currentLI).parent('ul').parent('li').prev('li').find('li.viewed:last');
alert($(prevLi).html());
</script>

Looking for elements with specific depth in JavaScript

I need to write a function in pure JavaScript witn no framework to get all specific tags, but only from first level under parent.
For example: I need to call some function on first <ul> and get all <li> from first level of it (<li> with text 1.2 and <li> with text 2.1)
<div id="sideNavigation">
<ul>
<li class=" act open ">
1.2
<ul>
<li class=" ">
1.2
<ul>
<li class=" ">
1.3
<ul>
<li class=" ">1.4</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li class=" ">
2.1
<ul>
<li class=" ">2.2.1</li>
<li class=" ">2.2.2</li>
<li class=" ">2.2.3</li>
</ul>
</li>
</ul>
</div>
I've been trying to do it like this:
var allLi = document.getElementById("sideNavigation").getElementsByTagName("li");
but it returns all <li> in this div not only first level <li>. Do you have any quick method to solve my problem or do I have to implement a new function to detect depth of nodes
You can use the attribute .children to get those "li"
var firstDepthLi = document.getElementById("sideNavigation").children[0].children;
If you want a generic function you can create something like:
var getElementsByDepth = function(el, tagname, depth) {
var children = el.children;
var res = new Array();
for(var i=0; i<children.length; i++) {
if (children[i].tagName == tagname) {
res.push(children[i]);
if (depth > 0)
res.concat(getElementsByDepth(children[i], tagname, depth-1));
}
}
return res;
}
Try:
var allLi = document.getElementById("sideNavigation").getElementsByTagName("li")[0];
That should return the first li element out of all li's on the page. Change the zero at the end to a different number to get a different element. You could even set a variable for the value:
var liNum = 0;
var allLi = document.getElementById("sideNavigation").getElementsByTagName("li")[liNum];
And in a function:
function getLi(depth) {
var specificLi = document.getElementById("sideNavigation").getElementsByTagName("li")[depth];
return specificLi;
}
var firstLi = getLi(0);
console.log(firstLi);
<div id="sideNavigation">
<ul>
<li>First list tag</li>
<li>Second list tag</li>
<li>Third list tag</li>
</ul>
</div>
And to make the function even shorter, you could just do:
function getLi(depth) {
return document.getElementById("sideNavigation").getElementsByTagName("li")[depth];
}
That should work. :)

Categories

Resources