how to add click only on button - javascript

I am using jquery to bind a click on a button. In this var testId i am getting the id of the button and var showmoreId is getting the id of a div but the problem is onclick binds with the li so when i click anywhere in li onclick is working but i want it to work on button click and i also want the id of the div on click but do not want li to work on click so what can i do to fix it.
async function userData(userdata) {
let newValue = "";
userdata.forEach(max=> {
let add = `<div class="rb-container">
<ul class="rb">
<li>
<div>
<p>${max.name}</p>
<div>
<p>${max.email}</p>
<button id="showMoreLess_${max.id}" data-order-id="${max.id}">View More</button>
</div>
<div id="showme_${max.id}" class="showBlock" style="display:none";>
<div>
<div>
<p>Quantity:</p>
<p>${max.volume}</p>
</div>
<div>
<p>${max.group_email}</p>
<p>Group_Email</p>
</div>
</div>
</div>
</div>
</li>
</ul>
</div>`
newValue += add ;
let container = document.querySelector('.user-details');
container.innerHTML = newValue;
}
$(document).ready(function() {
$('.rb-container li').unbind('click');
$('.rb-container li').on('click', function () {
var testId = $(this).find('button').attr('id');
var showmoreId = ($(this).find('div > div').next().attr('id'));
viewFullDetails(testId, showmoreId);
});

The .on() function supports an optional selector to handle events on certain child elements.
$('.rb-container li').on('click', 'button', function() {
var testId = $(this).attr('id');
var showmoreId = $(this).closest('li').find('div > div').next().attr('id');
viewFullDetails(testId, showmoreId);
});
Note that I just added the selector 'button' but of course you can use any selector, e.g. #id. I then found the closest li to go from there to get the showmoreId.
Please also consider to use .off() instead of .unbind() as the latter has been deprecated.

Related

Get ID of preceding image on click event

I have this HTML code
<div> <img src="download1.jpeg" image-id="9a8ae555af5f"></div>
<div><h1>test</h1></div>
When a user clicks on the "test" link, i would like to navigate through the tree and fetch the "image-id" attribute of the image preceding the link
I have tried this but imageID returns undefined
function trackClick(event)
{
let imageId = this.$('a').prev('img').attr('image-id');
console.log("imageId", imageId);
}
document.addEventListener('click', trackClick, true);
Any ideas on how i can make this work using js or css selectors?
thanks
This is jquery solution with prev() and parent() function:
$('#test').on('click', function() {
alert($(this).parent().parent().prev('div').find('img').attr('image-id'))
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<img src="download1.jpeg" image-id="9a8ae555af5f">
</div>
<div>
<h1>
<a href ="#" id = 'test'>test</a>
</h1>
</div>
Using Vanilla JS, step by step:
function trackClick(event)
{
let targetElement = event.target || event.srcElement;
let closestDiv = targetElement.closest('div');
let previousDiv = closestDiv.previousElementSibling;
let insideImage = previousDiv.getElementsByTagName('img');
// or
// let insideImage = previousDiv.children;
console.log(insideImage[0].getAttribute('src'));
}
document.addEventListener('click', trackClick, true);

How can i delete a specific li list on click?

const list = document.getElementById('list')
const addtodo = document.getElementById('addtodo')
//const items = document.querySelector('.item')
const deleteItem = document.querySelector('.delete')
addtodo.addEventListener('keypress', submitTodo)
function submitTodo(event) {
if (event.keyCode == 13) {
event.preventDefault()
let value = addtodo.value
let li = document.createElement('li')
li.innerHTML = `
<img class="unchecked" src="icon/unchecked.svg" />
${value}
<img class="delete" src="icon/icons8-multiply-26.png" /> `
list.appendChild(li)
}
}
deleteItem.addEventListener('click', items)
function items(item) {
if (item.target.classList.contains('delete')) {
item.target.parentElement.remove()
}
}
The code above only allows me to delete one item and its the first one on the list
I try to solve it on my own but couldn't any idea whats wrong
When deleteItem.addEventListener('click', items) is ran, it only attaches the eventListener to the elements currently on the DOM - the ones you create dynamically will not have this eventListener
You can use 'event delegation' instead to listen for clicks, and filter theses clicks based on if the click was coming from the correct element
You can read more about event delegation from davidwalsh's blog and this StackOverflow answer
document.addEventListener('click', function(e) => {
if(e.target && e.target.classList.includes('delete')){
e.target.parentElement.remove()
}
});
You could also make use of the elements onclick attribute, and pass this in the parameter of the function call - this way you can access the HTML Element directly from the parameter; this also avoids having to have an eventListener, or using an if to check if it's the correct class / ID
// Add the function to the onclick attribute of the img
<img class="delete" onclick="deleteItem(this)" src="demo.png" />
// in this function, 'item' refers to the DOM Element that was clicked
function deleteItem (item) {
item.parentElement.remove();
}
This code will allow you to remove the first element on ul .
let list = document.getElementById("list"); // ul element
let remove = document.getElementById("remove"); // remove button
// on double click event
remove.onclick = () => {
// remove the first child from the list
list.removeChild(list.firstChild);
}
<ul id="list">
<li>One</li>
<li>Two</li>
<li>three</li>
</ul>
<input type="button" id="remove" value="Remove First"></input>

Toggle class to an element by click another element

I want to click on an element to toggle a class being referenced on a completely unrelated element (not a child, parent or sibling)
For example, initially the code would look like this
<a id="button">Button</a>
<div class="navigation">
Foo
</div>
When the user clicks the element with the id button the HTML would change to look like this (the class "open" is referenced on element with "navigation" already referenced":
<a id="button">Button</a>
<div class="navigation open">
Foo
</div>
The user should be able to toggle the class by clicking the element with the id button.
I would like to use pure javascript to achieve this effect.
You could attach click event to the button with id button then on click select the element with class navigation using getElementsByClassName() (ti will return list of nodes) then select the first one using [0] then use toggle() :
document.getElementById('button').onclick = function(){
document.getElementsByClassName('navigation')[0].classList.toggle("open");
}
Hope this helps.
document.getElementById('button').onclick = function(){
document.getElementsByClassName('navigation')[0].classList.toggle("open");
}
.open{
background-color: green;
color: white;
}
<a id="button">Button</a>
<div class="navigation">
Foo
</div>
You don't really need javascript. Checkboxes work great at storing on/off state. You just need to get a little crafty with the CSS to use it elsewhere. Here is an example:
label.divcheck { color:blue; text-decoration:underline; }
input.divcheck { display:none; }
input.divcheck + div { display:none; }
input.divcheck:checked + div { display:block;}
<label class="divcheck" for="navigation">Button Nav</label>
<label class="divcheck" for="other">Button Other</label>
<input type="checkbox" class="divcheck" id="navigation"/>
<div class="navigation">
Foo
</div>
<input type="checkbox" class="divcheck" id="other"/>
<div class="navigation">
Other
</div>
Multiple elements with class navigation
navigation is a class, so I assume there is more than one element you would like to give class open on click on element with id button. Do it that way:
function toggleNavigation(element) {
element.classList.toggle('open');
}
document.getElementById('button').addEventListener('click', function() {
Array.from(document.getElementsByClassName('navigation')).forEach(toggleNavigation);
});
.navigation {
background-color: lightgreen;
}
.navigation.open {
background-color: lightblue;
}
<a id="button">Button</a>
<div class="navigation">Foo</div>
<div class="navigation">Foo</div>
<div class="navigation">Foo</div>
Single element with class or id navigation
If it is otherwise (i.e., there is only one element with class navigation, in which case it should be an id, not a class) you can replace above JavaScript to:
document.getElementById('button').addEventListener('click', function() {
document.getElementsByClassName('navigation')[0].classList.toggle('open');
});
or if you will change navigation to be an id:
document.getElementById('button').addEventListener('click', function() {
document.getElementById('navigation').classList.toggle('open');
});
You need to add event handlers. This can be done by simple setting the onClick property on the Element object:
document.getElementById('button').onClick = function onClick() {
document.getElementsByClassName('navigation')[0].className += 'open';
};
However, it's preferable that you use addEventListener so multiple event listeners can be added to the same element:
document.getElementById('button').addEventListener('click', function onClick() {
document.getElementsByClassName('navigation')[0].className += 'open';
}, false);
EDIT: It's also better to cache your element references in variables like so:
var button = document.getElementById('button');
var nav = document.getElementsByClassName('navigation')[0];
button.addEventListener('click', function onClick() {
nav.className += 'open';
}, false);
EDIT2: as in Zakaria's answer, you may want to use classList.add(x) instead of className += x. It's more in line with how jQuery's things work. However, be aware that classList is not supported in older versions of IE.
EDIT3: Here's a final version using classList.toggle
var button = document.getElementById('button');
var nav = document.getElementsByClassName('navigation')[0];
button.addEventListener('click', function onClick() {
nav.classList.toggle('open');
}, false);
And here's a quick replacement for classList using className instead:
function classList(elem) {
var cl = {
add: function (clas) {
elem.className += clas;
},
remove: function (clas) {
elem.className = elem.className.replace(clas, '');
},
toggle: function (clas) {
if (elem.className.indexOf(clas) > -1) {
cl.remove(clas);
} else {
cl.add(clas);
}
}
};
return cl;
}
// usage
classList(nav).add('open');
classList(nav).toggle('open');
Try this:
document.querySelector('div.navigation').classList.toggle('open');
This will work if you only have one div element that has the class navigation. It would be better to give it an id, for example id=navigation

Finding the value of a class within a list

I have
<ul id="list">
<li data-markerid="0" class="">
<div class="list-label">A</div>
<div class="list-details">
<div class="list-content">
<div class="loc-id">2</div>
<div class="loc-addr">England</div>
<div class="loc-dist">2 miles</div>
<div class="loc-addr2">Test</div>
<div class="loc-addr2">Bristol</div>
</div>
</div>
</li>
<li data-markerid="1" class="">
<div class="list-label">A</div>
<div class="list-details">
<div class="list-content">
<div class="loc-id">3</div>
<div class="loc-addr">England</div>
<div class="loc-dist">60 miles</div>
<div class="loc-addr2">Test</div>
<div class="loc-addr2">London</div>
</div>
</div>
</li>
</ul>
I'm wanting to extract the value of this using JQuery.
I tried:
var targetID = $(this).find('.loc-id').text();
But this gets me values of both loc-id's. I want just the one that I'm selecting (clicking).
For full context, please look here: Parsing data using JQuery
$('#list').click(function () {
//Change the src of img
var targetID = $(this).find('.loc-id').text(); // Get the ID
// Since array of objects isn't indexed, need to loop to find the correct one
var foundObject = null;
for (var key in parsedArray) {
if (parsedArray.hasOwnProperty(key) && parsedArray[key].id == targetID) {
foundObject = parsedArray[key];
break;
}
}
// If the object is found, extract the image and set!
if (!foundObject)
return;
var imageSrc = foundObject.LocationPhoto; // From the object
$('#location-image').attr('src', imageSrc); // Set the new source
});
Thanks
In your click handler, this references the <ul> element which has multiple <li> children.
Change the click handler to act as a delegate instead:
$('#list').on('click', 'li', function () {
Now, inside the click handler, this references an <li> element so the search should only yield a single value.
For var targetID = $(this).find('.loc-id').text(); to work, you must be clicking an element that is an ascendant of only one .loc-id. For example:
$('.list-details').on('click',function(){
var targetID = $(this).find('.loc-id').text();
});
You need to change selector. In your event handler. $(this) referes to ul which has multiple loc-id thus when you are using text() its concatenating text.
Use
$('#list li').click(function () {
//Change the src of img
var targetID = $(this).find('.loc-id').text(); // Get the ID
alert('targetID: ' + targetID)
});
instead of
// When we select the item
$('#list').click(function () {
//Change the src of img
var targetID = $(this).find('.loc-id').text(); // Get the ID
DEMO
You could use event.target in case you are delegating on #list:
Demo: http://jsfiddle.net/abhitalks/CxcU8/
$("#list").on("click", function(e) {
var $t = $(e.target);
if ($t.hasClass('loc-id')) {
alert($t.text());
}
});

event.preventDefault() on hyperlink not working

I'm aware that this issue was addressed many times, that's why I read most of the topics on this problem that were already opened on Stack Overflow but none of the suggestions have helped me.
I have a list of div elements, each containing a hyperlink and a span element with additional information. The span elements are initially hidden and they need to be toggled whenever the sibling anchor element is clicked.
<div class="politician">
<a href="">
Антонијо Милошоски
</a>
<span class="additional" style="display: none">
2013ВМРО-ДПМНЕ1997-1
</span>
</div>
<div class="politician">
<a href="">
Силвана Бонева
</a>
<span class="additional" style="display: none">
2013ВМРО-ДПМНЕ1991-1
</span>
</div>
Here's the jQuery code I have written to handle the toggling of the hidden elements:
$('.politician a').click(function (e) {
e.preventDefault();
var $this = $(this).parent().find('span');
$(".politician span").not($this).hide();
$this.toggle();
});
My problem was already stated in the title. I'm expecting the hidden elements to be shown, but instead the page gets refreshed. I guess there has to be something wrong with the way I'm using the preventDefault() method.
EDIT
Here is the piece of code that generates the div.politician elements.
function populateList(politicians) {
var politlist = $("#list").html("");
for (var i in politicians) {
var person = politicians[i];
var politinfo = "<div class=\"politician\">" + person.name + " " + person.surname + "<span class=\"additional\" style=\"display: none\">" + person.lastserved;
for (var j in person.member)
{
var membership = person.member[j]
politinfo += membership.party + membership.enrol + membership.leave;
}
politinfo += "</span></div>";
$(politinfo).appendTo(politlist);
}
}
Since you're adding elements dynamically, you need to use event delegation:
$('#list').on('click', '.politician a', function(e) {
// your code
});
This is happending because your html is not loaded when you add click event listener to it.
Wrap your code in document.ready function, like this:
$(function(){
$('.politician a').click(function (e) {
var $this = $(this).parent().find('span');
$(".politician span").not($this).hide();
$(this).toggle();
e.preventDefault();
});
});
http://plnkr.co/edit/gist:1986619?p=preview

Categories