Click function not working on div class created on the fly - javascript

I am unsure as to how to approach this problem.
I have some buttons made in the HTML with some data attributes added to them. These buttons have a class called roleBtn which will call my jQuery roleBtnClicked function and grab the variables in the HTML's data attributes.
$(".roleBtn").click(roleBtnClicked);
function roleBtnClicked(event){
reg.roleName = $(this).html(); /* Get role name: Actor */
reg.blueBtn = $(this).data('blue'); /* Get blue-btn-1 */
reg.the_Num = $(this).data('num'); /* Get the number */
reg.modal_ID = $(this).data('modal'); /* Get modal-1 */
Now using this information, after the roleBtn is clicked a modal window will come up, I then have a doneButton which will close the modal window and use the variables from the data attributes to then generate new HTML on the fly. This new HTML will contain a button with the class of blueBtn.
My problem is that my click function for blueBtn won't work on a blue button that was created on the fly. It will work on a div that already has the class blueBtn before hand, but doesn't work if it was created on the fly.
Do you know a workaround to this? Or am I missing something simple?
After the doneButton is clicked I have another function that creates the new HTML including the blueBtns on the fly:
$('.selected_row .choices-col-left').append('<div class="blueBtn-holder" id="blueBtnHolder-'+theNum+'"><div class="blueBtn" id="'+blueBtn+'" row="'+rowName+'" modal="'+modal_ID+'" num="'+theNum+'">'+roleName+'</div></div>');
My blue button click function which doesn't work
$(".blueBtn").click(blueBtnClicked);
function blueBtnClicked(event){
alert("Where are you blueBtn on the fly?");
console.log("Where are you blueBtn on the fly?");
};

Try this:-
You need Event delegation for dynamically created elements using .on()
$(".selected_row").on('click', '.blueBtn', blueBtnClicked);
function blueBtnClicked(event){
alert("Where are you blueBtn on the fly?");
console.log("Where are you blueBtn on the fly?");
};
Demo
When you just bind a click event, it will be only bound to the existing DOM elements, so you want to bind the event to the parent element and later any elements you add with the same selector with that container will have the event available by delegation.
From Jquery Docs
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.

That's because you have to reassign event handlers for newly created items.
A better approach would be using .on on the container object, and then specify the child objects that should respond to the clicks:
$(".container").on('click', '.blueBtn', blueBtnClicked);
This way even if you ad objects on the fly, they will still respond. This is actually a lot more efficient way of handling that, because you only create one event handler as oppose to many. This is actually called event delegation.
Remember that when you do $(selector).click, you're telling jQuery to find all elements matching selector and assign the specific "click handler" to them. This does not happen again when you create new objects, because you're not telling jQuery to handle every future object as well (jQuery will not be aware of you adding a new button and will not assign a handler to it).

Related

Javascript events (click)

My website works basically with javascript. the server returns the html in a JSON array then javascript will add it to DOM.
My problem is with events.
Should I add the click event to body/window and then check if target match or add event to every element ? (the most events will be in the feed, where elements have same class):
<div id="feed_1">
<div class="like_button" data-click="something here">Like</div>
</div>
<div id="feed_2">
<div class="like_button" data-click="something here">Like</div>
</div>
note: I'm not using jQuery
If you are asking whether or not you should add an even to every element in the HTML document, or to have one event listener that specifies a target upon a click, the better way is definitely the latter.
With events that work with a large number of elements, we enforce DRY principles through the use of event delegation. This involves declaring an event listener with the event parameter, and then triggering the event onto the event target. example:
var el = document.getElementByID('container');
el.addEventListener('click', function(e) {
doSomething(e.target); // do something to the target element
});
The idea here is that your container element encompasses everything you wish to be 'clickable', however, when you click an element within the container, the event will only fire for that clicked element. This way we prevent having to define an event listener for each individual element.
Hope this helps.

Js click property not working on html loaded by js

I have created a dynamic page in which i am loadin 10 element by default. after that if user scroll doun i am apppending more element to this page by js (appending data by ajax).
and on click of a tag i am doing some js work
I am using
$('.atnd_modal').click(function(){
alert("dsfds");
});
not
onclick ="function()" and i dont want to do that onclick.
Problem i am facing that this js is working perfectely for first 10 result but after that it stop working for the block i have appended by js.
how can to do it working for both the cases ??
Try jquery on() for event delegation. It will work on dynamic loaded element on DOM also.
$('body').on('click','.atnd_modal', function(){
alert("dsfds");
});
Delegated events have the advantage that they can process events from
descendant elements that are added to the document at a later time.
Your click event is not working because when you use click() it will attach this handler to all elements having atnd_modal class, but when new element loading in DOM that event is not attached automatically with new element. For previous elements it will work fine but for new element it won't. So here comes Delegated events. We shall attach event to parent element with on() or delegate()
If you want to bind an event to the dynamically added new elements you have to use event delegation :-
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.
Change your code like this, use Jquery On
$('body').on('click','.atnd_modal', function(){
alert("dsfds");
});

Event stops working after dynamic ul li changes

The Code:
if($('.info-dropdown').length){
setTimeout(function(){
$('li').has('input[type="checkbox"]').on('click', function(){
$(this).find('.brand-checkbox').parent().toggleClass('active');
});
}, 10);
}
The Problem: This code detects event click on element checkbox. After dynamically changing this ul li the event stops working.
Note: These checkboxes are from bootstrap dropdown menu.
To bind event for dynamic HTML, You can follow below code :
$('containerSelector').on('eventName', 'mainElementSelector' function(e){
});
Realtime example
$("ul").on("click", "li:has(:checkbox)", function(){
});
Event handlers added directly to an object are added only to that specific DOM object. If you then add or replace more DOM objects, those DOM object won't have any of these event handlers on them. You will have to either manually add the event handlers after you create or replace the DOM objects or you will have to switch to using delegated event handling.
Delegated event handling attaches the event handler to a common parent object (that is not replaced) and uses the fact that many events bubble up the parent chain in order to process the event from the common parent. This allows you to freely create or replace child elements, but still have one event handler that works for all child objects.
You can read a lot more about how to do delegated event handling in these other answers:
jQuery .live() vs .on() method for adding a click event after loading dynamic html
Does jQuery.on() work for elements that are added after the event handler is created?
JQuery Event Handlers - What's the "Best" method
As illustrated in those referenced answers, the general idea is like this:
$("#staticParentSelector").on("click", ".selectorForDynamicChildren", function(e) {
// event handler code here
});

How do I attach a JS click event to an AJAX loaded button?

I need to attach a JavaScript click listener to an add new record confirmation on a DevExpress gridview.
I can't use a regular click event listener as it's loaded via AJAX integrated into the control. I also have no access to the button's code so am unable to extend it.The only thing I do have is the button name.
Ideally I want to listen for the appearance of the button on the DOM and then attach the listener, is there any way to do this?
You do not need to wait for the appearance of the button in the DOM.
Just use a delegated event handler attached to a non-changing ancestor of the dynamic elements.
e.g.
$(document).on('click', '.someclass', function(){
///
});
If you only have the element name for the button use an attribute selector:
e.g.
$(document).on('click', '[name="somename"]', function(){
///
});
Delegated events work by listening for events bubbling up to a non-changing ancestor (document is the default if nothing closer is available). It then applies the selector at event time (not at event registration time). It then calls the function for any matching element that caused the event.
The end result is that it will work with elements that may exist later, when the event occurs.
Note: if nothing is closer to the dynamic content, use document, but do not use 'body' as styling can make it have a zero height and delegated mouse events will not work!

Adding event listeners to current and future elements with a particular class

With JQuery, is it possible to add an event listener to any element that currently, or will in the future, have a particular class?
I'm working on a project that makes heavy use of contentEditable, so the DOM is changing, and elements can have classes added and removed as a result of user input.
I would like to be able to say "elements of class X should do Y when clicked", but if I understand correctly, $(".X").click(Y) will only add the event listener to elements that currently have class X.
Furthermore, if an element is no-longer part of class X, then it will still have the click event listener.
How can I do this?
Yep. What you're talking about is called event delegation. Here's an example:
$('#container').on('click', '.innerElement', function(){
/// Do stuff
});
In your case, #container would be an element that is known to exist on page load which will contain the child elements you care about (either now or in the future). This approach takes advantage of event bubbling in the DOM.
As another poster mentioned, the live method will also work -- but it has been deprecated in jQuery 1.7, and is generally not as performant as using more selective delegation (such as the example above).
you'll want to use event delegation. jquery 1.7 has made this more abstract than previous versions, but it looks something like this:
$("#myWrappingElement").on("click", ".myclass", function(event){
alert($(this).text());
});
this basically adds a click event listener to the #myWrappingElement element, and jquery will automagically look to see what the original event target was and fire the proper function. this means you can add or remove .myclass elements and still have events fire on them.
the jQuery live() method swill allow to have a "live" action listener - so if new DOM elements match the selector, they will be attached to the action listener. For example:
$(".X").live("click", function(){
alert('some action');
});
See the documentation here for more info: http://api.jquery.com/live/
I'm not sure that the second part of your question about keeping the action listener attached after removing the class os possible - someone else might have a solution though.

Categories

Resources