How can I properly convert the following Jquery to pure Javascript? - javascript

How can I convert the Jquery below to pure JavaScript?
var $buttons = jQuery("#thePaginator li a");
for (var index = 0; index < $buttons.length; index++) {
var $button = $buttons.eq(index);
$button.click(function() {
var newPage = $(this).data("page");
jQuery("#attribute-myAttribute").val(newPage);
jQuery("#update").click();
});
}
I wouldn't normally ask a question like this, but the conversion has been difficult, especially with the event listener. Here is what I have so far:
runPaginate();
function runPaginate(){
var buttonArray = document.getElementById("paginator_TCC").querySelectorAll('li');
for(i=0;i<(buttonArray.length);i++){
buttonArray[i].addEventListener('click', runUpdate);
}
}
function runUpdate(){
console.log("runUpdate started")
// will need to add code in here for update
}
update (in Jquery) is a method that is called to update attributes on the page. Consider the runUpdate function to suffice for that method call.
I believe that I'm having so much trouble because I'm dealing with HTML Collection, so when I get the li elements (which are actually buttons) I can't seem to add an event listener to them. Below is the inspection result from Dev Tools:
<div id="thePaginator" class="simple-pagination">
<ul>
<li class="disabled">
<span class="current prev">Prev</span>
</li>
<li class="active">
<span class="current">Year 1</span>
</li>
<li class="disabled">
<span class="current next">Next</span>
</li>
</ul>
</div>
Any assistance is appreciated.

I'd use a for...of loop, and move the callback into the loop. That way you can access the iterator:
for(const button of buttonArray){
button.addEventListener('click', function runUpdate() {
const { data } = button.dataset;
//...
});
}

This is the JS equivalent of your jQuery (this just replaces the jQuery method calls with their equivalent JS method calls)
var buttons = document.querySelectorAll('#thePaginator li a');
for(var index = 0; index < $buttons.length; index++) {
var button = buttons[index];
button.addEventListener("click", function(evt) {
var newPage = this.dataset.page;
document.getElementById('attribute-myAttribute').value = newPage;
document.getElementById('update').click();
})
}

Related

can't get index of current clicked element in array using javascript

This is my HTML code
var link = document.getElementsByClassName("link");
for (i = 0; i < link.length; i++) {
link[i].addEventListener("click", click);
function click() {
console.log(link.indexOf(this));
}
}
<div class="links">
<ul>
<li>
<div class="hole-counter"><span></span></div><a class="link">Home</a>
</li>
<li>
<div class="hole-counter"><span></span></div><a class="link">About</a>
</li>
<li>
<div class="hole-counter"><span></span></div><a class="link">Gallery</a>
</li>
<li>
<div class="hole-counter"><span></span></div><a class="link">Contact</a>
</li>
</ul>
</div>
And this is javascript code
i get this error in console
Uncaught TypeError: link.indexOf is not a function at HTMLAnchorElement.click (index.html:97)
Your link variable is not an Array, therefore you cannot call indexOf() on it. You must first convert link to an array.
var link = Array.from(document.getElementsByClassName("link"));
The link variable in your code is HTMLCollection, you need to convert it to an array before using indexOf
You can do this
const links = [...document.getElementsByClassName("link")];
links.forEach(link => link.addEventListener("click", click));
function click() {
console.log(links.indexOf(this))
}
The link variable is an array like element, you need to convert that to an array first:
var link = document.getElementsByClassName("link");
for (i = 0; i < link.length; i++) {
link[i].addEventListener("click", click);
}
function click() {
console.log(Array.from(link).indexOf(this));
}
Your link variable is just a variable and the indexOf function is specifically for arrays. So you should first convert your variable into an array. You can do that by either declaring it as an array or converting it into an array afterwards.

Using addEventListener and getElementsByClassName to pass an element id

I'm defining a list of items from a JSON file and displaying that list on a web page. The intention is for users to click on any item in that list to display more information on that item (information that is held in the same JSON file).
All items of that list are members of the same class, and each has a unique id defined from the JSON file. The HTML looks something like this:
<ul>
<li class="menu" id="bob">Robert Smith</li>
<li class="menu" id="jane">Jane Doe</li>
<li class="menu" id="sue">Susan Carter</li>
</ul>
I was planning to use something along the lines of
var userSelection = document.getElementsByClassName('menu');
in concert with
userSelection.addEventListener('click', myFunctionToPrintDetails());
but I am not sure how to pass the id from the event listener to the print function in order to determine which details to print.
I have a lot of experience with HTML/CSS but very little with JSON/AJAX, so possible I'm going about this completely bass-ackwards. If there is a more appropriate way to get this done I'm open to the feedback.
I tried both answers but neither worked. When I log userSelection.length to the console I get 0; when I log userSelection I get:
HTMLCollection(0)
> sue: li#sue.menu
length: 3
> jane: li#jane.menu
> bob: li#bob.menu
> 0: li#bob.menu
> 1: li#jane.menu
> 2: li#sue.menu
codepen demo
var userSelection = document.getElementsByClassName('menu');
for(var i = 0; i < userSelection.length; i++) {
(function(index) {
userSelection[index].addEventListener("click", function() {
console.log("Clicked index: " + index);
})
})(i);
}
As pointed out by #torazaburo in the comments, you can use the following if the browsers you want to support are complying with ECMAScript 6 (ES6), the newest version of JavaScript.
var userSelection = document.getElementsByClassName('menu');
for(let i = 0; i < userSelection.length; i++) {
userSelection[i].addEventListener("click", function() {
console.log("Clicked index: " + i);
})
}
Here's how I would do it. I would first create an array using Object values.
const userSelection = Object.values(document.getElementsByClassName('menu'));
Then I would loop through them using a foreach.
userSelection.forEach(link => {
link.addEventListener(event => {
event.preventDefault();
// more code here
});
});
Easy peasy!
You can get the id from the element that responded to the click event with this.id:
var items = document.getElementsByClassName('menu');
for (var i = 0; i < items.length; i++) {
items[i].addEventListener('click', printDetails);
}
function printDetails(e) {
console.log("Clicked " + this.id);
}
<ul>
<li class="menu" id="bob">Robert Smith</li>
<li class="menu" id="jane">Jane Doe</li>
<li class="menu" id="sue">Susan Carter</li>
</ul>
<ul id = "menuList">
<li class="menu" id="bob">Robert Smith</li>
<li class="menu" id="jane">Jane Doe</li>
<li class="menu" id="sue">Susan Carter</li>
</ul>
// JS - Event Bubbling
const menuList= document.getElementById("menuList");
menuList.addEventListener("click", function (e) {
console.log(e.target); // log clicked element
});
Here is a shorter version I'm using all the time:
[...(document.getElementsByClassName('__MYCLASSNAME__')].forEach(d => {
d.addEventListener('click', MYFUNCTION__);
})

.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?

include variable with addEventListener

I´ve just started to learn JavaScript and made a click function to change value of i depending on which li element is being clicked. Instead of having 3x of basically same function is it possible to send variable with addEventLisener to check with a if statement. Because if I add 1 or 2 more li it would add a lot of unnecessary code.
HTML:
<div><img src="image1" />
<ul>
<li id="list1">1</li>
<li id="list2">2</li>
<li id="list3">3</li>
</ul>
</div>
JavaScript:
var list1 = getElementById('list1');
var list2 = getElementById('list2');
var list3 = getElementById('list3');
list1.addEventListener("click", clicked1);
list2.addEventListener("click", clicked2);
list3.addEventListener("click", clicked3);
var i = 0;
function clicked1(){
i= 0;
loop();
}
function clicked2(){
i = 1;
loop();
}
function clicked3(){
i = 2;
loop();
}
function loop(){
if (i > 2){
i=0;
}
var imageloop = getElementById('slideshow').getElementsByTagName('img');
imageloop[0].src = 'image' + i;
i++
setTimeout(loop,3000);
}
So when one of the li element is being clicked it will change the img currently displaying.
Bind to the list, not the list item - <ul id="ul1">... :
document.getElementById('ul1').addEventListener('click', function (e) {
var li = e.target;
alert(li.id); // list1, list2, respectively, etc.
});
http://jsfiddle.net/seancannon/D6HX4/
As Teemu said, bind to the list and use e.target. Then, change i according to e.target.innerHTML (because for your purposes, that's easier since the innerHTML is similar to the id, but simpler).
Assuming the <ul> element now has an id of "list":
var list = document.getElementById("list");
var i = null;
list.addEventListener("click", function(e) {
window.i = parseInt(e.target.innerHTML, 10);
console.log(window.i);
});
You don't need Separate code for each <li>,
Here is How to do it in single function:
HTML:
<div>
<ul id="All_List">
<li id="list1">1</li>
<li id="list2">2</li>
<li id="list3">3</li>
</ul>
</div>
JavaScript:
var clicked_li=0; /* It'll store the number of <li> being clicked */
var ul=document.getElementById("All_List"); /* <ul> Element with all <li> */
window.onload=function(){
var lis=ul.getElementsByTagName("li"); /* All <li>'s from <ul> */
for(var i=0;i<lis.length;i++){
var li=lis[i]; /* Specific <li> from <ul> ie, lis[0] means first <li> of <ul> */
li.addEventListener("click", function(){ /* Listen and bind click event to that <li> */
clicked_li=getIndex(this); /* Store Which <li> Was clicked in clicked_li */
alert("'list"+clicked_li+"' was clicked!");
/* if you just want to get the id you can use event.target.id; instead of getIndex(); */
}, false);
}
};
function getIndex(node) {
var childs = node.parentNode.getElementsByTagName("li"); /* Get parent <ul> and all child <li> of that parent */
for (var i = 0; i < childs.length; i++) {
if (node == childs[i]) break; /* Find which <li> from current <ul> was clicked */
}
return (i+1); /* Return No.(index) of that <li> starting with 1 */
}
and here is the:
fiddle for the same.
Hope it'll help you. Cheers!
This is an "improve/clearer" of Vedant Terkar answer. Which may give a more clear aspect on
the answer he gave.
if we give ul id group. We dont need id for each of the list-item inside the ul.
<ul id="group">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
Javascript
var i=0;
we set i to be a global variable and equal to 0 assuming it will display image(0) if nothing else is called.
window.onload=function(){
var lis=document.getElementById("group").getElementsByTagName('li');
We are now creating a Nodelist which is called lis. Then we loop through the NodeList to se which list-element is being clicked at.
for(i=0;i<lis.length;i++){
var li=lis[i];
li.addEventListener("click",index, false);
}
}
function index(){
var lis = document.getElementById("group").getElementsByTagName('li');
i = getIndex(this);
for(var a=0; a < lis.length; a++){
if(a ==i){
lis[i].innerHTML = 'Choosen';
}else{
lis[a].innerHTML = 'list'+a;
}
}
}
function getIndex(node) {
var childs = node.parentNode.getElementsByTagName("li");
for (var i = 0; i < childs.length; i++) {
if (node == childs[i]) break;
}
return (i);
}

Problem accessing div elements

<div id="nav">
<ul id="linkselect">
<li class="important" >Home</li>
<li><a href="rlsdoc.html" >Release Document</a></li>
<li>Data Dump</li>
<li>Facility Setup</li>
<li>DBU Elimination</li>
<li>Contact us</li>
</ul>
</div>
I want to put all the links (Home, Release Document etc) of div "nav" into a array so that I can iteratively use them. Please help me with the JavaScript code for this. Thanks in advance.
document.getElementById("nav").getElementsByTagName("a")
this will return a node list that contains all "a" nodes
This should do what you need with pure JavaScript:
window.onload = function() {
var data = [];
var oDiv = document.getElementById("nav");
var links = oDiv.getElementsByTagName("a");
for (var i = 0; i < links.length; i++)
data.push(links[i].innerHTML);
alert(data.join("\n"));
};
Live test case.
We could use a combination of .querySelectorAll() to query the desired anchors and Array.prototype.forEach to iterate over those static element references.
var anchors = document.querySelectorAll('#linkselect a'),
each = [].forEach;
each.call( anchors, function( a ) {
console.log( a );
});
Note: Both methods are not available in "old'ish" browsers, but are easily to create, lots of shims available.
Try this.
Javascript
var items = [];
var anchors = document.getElementById("nav").getElementsByTagName("a");
for(var i = 0; i<anchors.length; i++){
items.push(this.href);
}
jQuery
var items = [];
$("#nav a").each(function(){
items.push(this.href);
});
jQuery:
$('#linkselect li a')
plain javascript:
document.getElementById('linkselect').getElementsByTagName("a")

Categories

Resources