.click not being registered on button [duplicate] - javascript

This question already has answers here:
jQuery click event not working after adding class
(7 answers)
Closed 7 years ago.
I have this button rendered after some text in an unordered list:
The button's HTML is like this:
<a
data-action="remove"
data-class-name="ECEC 301 Advanced Programming for Engineers Lab"
class="btn btn-danger remove-item btn-xs btn-font-12-px btn-raised margin-add-to-cart mdi-content-remove-circle-outline">
</a>
And this is the unordered list element it is within:
I am trying to write some jQuery that calls an action when the button is clicked, but no matter what I write, I just cannot register the click action, for example:
$('.btn.btn-danger.remove-item').on('click', function(){
console.log("you should see this");
});
$("[data-action]").click(function() {
console.log("yeah");
});
$('a[data-action="remove"]').click(function() {
console.log("yeah");
});
EDIT: The button is created dynamically AFTER page-load using jQuery (I call my JSON API to create the unordered list of classes)

Since button is generated dynamically you need to use event delegation
$(document).on('click','.btn.btn-danger.remove-item', function(){
console.log("you should see this");
});
Event delegation refers to the process of using event propagation (bubbling) to handle events at a higher level in the DOM than the element on which the event originated. It allows us to attach a single event listener for elements that exist now or in the future.
Taken from : http://learn.jquery.com/events/event-delegation/

The issue is that the element doesn't exist when the click handler is being added.
Basically, you are saying "hey jquery, find this element and do XYZ when it is clicked". jQuery looks for it, doesn't find anything (since the element has not been created yet), and since it is chill it doesn't say anything to you about it (it would be super annoying if it errored out all of the time).
The way around this is by using event delegation. What that means is that you attach the event to an element that will be there, and then jQuery filters every event sent to that parent element and checks to see if the event that triggered it happened to an element that matches the selector.
It may sound complicated, but it is straight forward. All you need to do is update
$(".btn.btn-danger.remove-item").on("click...
to this
$(document).on("click", ".btn.btn-danger.remove-item"...

Related

Clicking a <span> tag to run JQuery javascript function [duplicate]

This question already has answers here:
Event binding on dynamically created elements?
(23 answers)
Closed 4 years ago.
I create a span using PHP like this.
if ($subnetkey == 1 ) { echo ("<span class='subnetkey'>S/N of: $subnetnum</span> ");}
It works, and shows the correct data on screen. Additionally if I look at it using 'Inspect Element' its properly formatted.
<span class="subnetkey">S/N of: 780</span>
I have this script at the top of the page. I've also tried it at the bottom.
<script>
$(document).ready(function(){
$(".subnetkey").click(function() {
alert("subnet click mode");
});
});
</script>
When I click the span, nothing happens. I get no errors, and of course I don't see the alert fire.
It seems like this is a timing issue between building the page dynamically and using the page. But in case thats not it, what can I do to make the function fire?
JQuery Event Methods like click(), dblclick(), mouseenter() etc. work only for elements already created when DOM is rendered. For dynamically created elements you use on() method with the below syntax (see previous post):
$(staticAncestors).on(eventName, dynamicChild, function() {});
Since it is a dynamically created element your code won't work. Try:
$(document).on('click', '.subnetkey', function() {
alert("subnet click mode");
});
jQuery is only aware of the elements in the page at the time it runs, so new elements added to the DOM are unrecognized by jQuery. To combat the problem use event delegation, bubbling events from newly added items up to a point in the DOM which was there when jQuery ran on page load. Many people use document as the place to catch the bubbled event, but it isn't necessary to go all the way up the DOM tree. Ideally you should delegate to the nearest parent existing at the time of page load.

Loaded html content with ajax wont detect other js functions [duplicate]

This question already has answers here:
JavaScript does not fire after appending [duplicate]
(3 answers)
Closed 7 years ago.
Guys i have blog post list loaded with ajax that list append html in one div. That ajax html result have some buttons witch need to execute some js events on click. Problem is bcs that loaded html result wont detect some events...
With ajax i get full post list like below post-list.php but when i try to click on button like or dislike in that ajax result event is not fired idk whay all that functions is in one file. I check to inspect with firebug he only detect listPosts() function.
See example:
In my index this result is loaded :
post-list.php file
<!-- List of post loaded from db (LOOP)
<h1>Post title</h1>
<p> Post content </p>
<button id="like">Like</button> <!-- jquery click event need to be fired but wont -->
<button id="dislike">Dislike</button> <!-- the some -->
Script example:
var Post = {
addPost: function() {
// Ajax req for insert new post
}
listPosts: function() {
// Ajax req for fetching posts
}
likePost: function() {
// example
$("#like").click(function() {
console.log("liked") // debug
$.ajax() // etc;
});
dislikePost: function(obj) {
// the some
});
init: functon() {
Post.addPost();
Post.listPosts();
Post.likePost();
Post.dislikePost();
}
}
Post.init();
This script load all post with ajax, add new post on some event, send like result in db and dislike. So in this post list result when i try to click like or dislike button nothing is happening.
Only work if i do this:
<button id="like" onclick="Post.likePost(this);">Like</button>
But i dont want to do this in this way. I dont understand that script detect listPosts() but wont detect other functions in that ajax response.
Event bubbling.
Delegated events have the advantage that they can process events from
descendant elements that are added to the document at a later time. By
picking an element that is guaranteed to be present at the time the
delegated event handler is attached, you can use delegated events to
avoid the need to frequently attach and remove event handlers. This
element could be the container element of a view in a
Model-View-Controller design, for example, or document if the event
handler wants to monitor all bubbling events in the document. The
document element is available in the head of the document before
loading any other HTML, so it is safe to attach events there without
waiting for the document to be ready.
$('#container-div').on('click', '#like', function() {
console.log('Liked');
});
If you have a static container-div, it will have all events within it bubble up, i.e. it can see any events caused by dynamically created objects.
I would recommend to use class name instead of duplicating same ids again and again:
<button class="like">Like</button>
<button class="dislike">Dislike</button>
Now you can delegate the event to the static parent element:
$('staticParent').on('click', '.like', Post.likePost)
.on('click', '.dislike', Post.dislikePost);
where $('staticParent') would be the container element which holds the buttons and it was there before posts load. Although you can replace it with $(document) too, but lookup from document could make event execution a bit slow.
The solution to this problem would be to use "event delegation". This is a very powerful feature, and allows you to use event handlers without needing to explicitly attach them to an element or group of elements. This is an example:
$('#like').on('click',handleLike);
This would mean that anything matching the selector will have the callback fired. Also, I would recommend changing from using ids to something more generic, like CSS classes.

jQuery Click Function not Working on Class [duplicate]

This question already has answers here:
Events triggered by dynamically generated element are not captured by event handler
(5 answers)
Closed 8 years ago.
So I have a bunch of game pieces that I want to be clickable. If I add a click function to a button I get the desired result, but when I add it to the game piece class, it fails to work.
Here is an example that works fine on jsfiddle, but not when I use it in my script:
http://jsfiddle.net/sLt7C/
Here is what I want to do on my page:
$('.gamePiece').click(function(){
$('.gamePiece').addClass("toggled");
});
This doesn't work, but if I switch the identifier to a button on the page it does work:
$('#btn_AddClass').click(function(){
$('.gamePiece').addClass("toggled");
});
What could be causing this to fail?
Not sure if this has any impact on what could be causing it to fail, but the "game pieces" are span elements that are generated after clicking a "New Game" button.
Here is a fiddle showing more code http://jsfiddle.net/sLt7C/4/
For further clarification:
This doesnt work
$('.gamePeice').click(function(){
$(this).addClass("toggled");
});
This works
$('#btn_addClass').click(function(){
$('.gamePeice').addClass("toggled");
});
If the game pieces are added after the page load (i.e. by clicking a button) you need to use event delegation by using jquery .on()
Event delegation allows us to attach a single event listener, to a parent element, that will fire for all descendants matching a selector, whether those descendants exist now or are added in the future.
$(myContainer).on('click', '.gamePiece', function(){
$(this).addClass("toggled");
});
I think you want this:
$(document).ready(function() {
$(document).on('click', '.gamePeice', function(){
$(this).addClass("toggled");
});
});
instead of
$('.gamePeice').click(function(){
$(this).addClass("toggled");
});
$('#btn_addClass').click(function(){
$('.gamePeice').addClass("toggled");
});
just prove http://jsfiddle.net/aras7/sLt7C/7/

How can jquery capture an <input> file tag that was itself rendered using jquery after a user clicks? [duplicate]

This question already has answers here:
Event binding on dynamically created elements?
(23 answers)
Closed 9 years ago.
How do you hook into javascript / popup functionality that is invoked after a user clicks?
We have javascript code that gets invoked by a user click. This javascript code renders a popup dialog that contains an choose file tag. This choose file tag is literally appended by doing something like:
output.append('<input type="file" ......'>
So the problem with this is if the user doesn't first click this tag never gets rendered in the response.
We are currently using a jQuery $() function to execute our code that looks for tags as soon as the web page loads, however our $() function does not get called when the user clicks the link rendering the popup.
Is there another hook we can use in jQuery besides $() that gets invoked when a popup gets rendered?
If I understand correctly, you want to attach an event handler at page load time to an input that will not exist until the user clicks a link. One solution is to use event delegation. You can look for "delegated events" in the documentation for the .on() function.
Basically, you call .on() on an element that already exists in the DOM that is an ancestor of the element that will be added later. You supply a selector as the second parameter that identifies the element you want the handler to execute for.
You could use:
$(document).ready(function() {
$(document.body).on('click', 'input:file', function() {
...
});
});
But it is more efficient to use a closer ancestor than the <body> element if you can, and you might have a better selector for identifying the file input element than the one I show above (since it will match all file input elements).
Either create proper elements with event handlers :
var file_input = $('<input />', {
type : 'file',
on : {
change : function() {
// do stuff
}
}
});
output.append(file_input);
or use a delegated event handler
output.on('change', '.file_input', function() {
// do stuff
});
output.append('<input type="file" class="file_input" ......'>
Of course it is possible. You have to define your function for the later rendered element after it is rendered.
HTML:
<div id="holder">
<button id='first'>first</button>
</div>
JQuery:
$('#first').click(function () {
alert('first click');
$('#holder').append("<input id='second' type='file' name='pic' accept='image/*'>");
$('#second').click(function () {
alert('second click');
});
});
Here is a demo: JSFIDDLE

<li> click function not working after ajax[Event delegation issue] [duplicate]

This question already has answers here:
Events triggered by dynamically generated element are not captured by event handler
(5 answers)
Closed 9 years ago.
In my webpage i am updating the contents of an unordered list $.get() every 5 seconds. The problem is the click function for the list items is not working. The list items are getting updated fine as they should but something is wrong with the click function
$(document).ready(function(){
$(".request").click(function(){
alert("hello");
//do some stuff
});
window.setInterval(function() {
$.get('/changeListItems/',function(data,status){
//alert(data[0]);
$('#collabRequests > li').remove();
for(user in data)
$('#collabRequests').append('<li class=\"request\">'+'user-'+data[user]+' wants to collaborate!'+'</li>');
});
},5000);
});
<!-- Html snippet -->
<div id="invitedUsers">
<h2> List of users you have invited for this page</h2>
<ul id="collabRequests">
</ul>
</div>
Delegate the event
Replace
$(".request").click(function(){
with
$(document).on("click", ".request", function(){
Still better.. Replace the document with a static ancestor that is present on the page at the time the event was bound.
Your selector, $(".request") is evaluated once. It does not periodically scan the DOM to find new elements with that class and attach click handlers to them. You are dynamically modifying the contents and not reattaching your handler.
The issue is that you're trying to attach an event handler directly on elements that do not exist in the DOM at the time that you're listening for their events.
As Sushanth suggested, the best way to handle events on dynamically injected DOM nodes is to simpy delegate them.
The other option is to bind the event handler at the time you add the new node to the DOM, but this can quickly get expensive if you're adding/removing many nodes. You'll also need to remember to unbind event handlers whenever an element is removed from the DOM tree or else your script may end up leaking memory.

Categories

Resources