Event delegation after removing class - javascript

I have a button
<button data-button='next' class="disabled">next</button>
I remove the disabled class to activate but the event does not work
$("[data-button='next']:not(.disabled)").on('click', document, function(){
How can I get this working

Which is not the right syntax for event delegation, update it as follows.
// provide any selector which is parent of the dynamic element
//--\/-- and present when handler is attaching
$(document).on('click', "[data-button='next']:not(.disabled)", function(){
// --------------------^^^^^---- provide the selector of corresponding dynamic element
// code here
});
$(document).on('click', "[data-button='next']:not(.disabled)", function() {
console.log('clicked');
});
$("[data-button='next']").removeClass('disabled')
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button data-button='next' class="disabled">next</button>

Related

How to convert jQuery to JavaScript name attribute

I'm trying to find a way to create 'on click' events for dynamically generated buttons in JS. I know that in jQuery it can be done like this:
$(document).on('click', 'name=[buttonName]', function() {});
I know the e.target method in JS, but I'm wanting to find a way to do it with a name attribute instead.
Thanks
Firstly that line of jQuery isn't quite right as the square brackets are in the wrong place:
$(document).on('click', '[name="buttonName"]', func);
To achieve the same in plain JS you would need to attach a click event handler to a static parent element, then check the name property of the clicked element:
document.addEventListener('click', function(e) {
if (e.target.name == 'buttonName') {
// do something...
}
});
document.addEventListener('click', function(e) {
if (e.target.name == 'buttonName') {
alert('Hello!');
}
});
<button>I do nothing!</button>
<button name="buttonName">I say hello!</button>
You can use querySelector in a similar way than you would in jQuery, and attach the event listener whenever a new element is added to the DOM.
document.querySelector("button[name='buttonName']").addEventListener("click", function(){
alert("Hello, World");
});
<button name="buttonName">Click me</button>
The difference to the original jQuery code is that in that example it listens to events on the document whereas this does not.
You can use getElementByName to add click event to your button which is dynamically render
document.getElementByName("ButtonName").addEventListener("click", function(e) {
});

Trying to write a function from inline javascript

I've got some code from a developer that left our company. He wrote an inline function looking like this:
<button class="xxx" id="MyID" type="button" onclick="javascript: $('#openThis').slideToggle('slow');">btnText</button>
I've tried to remove this and put it in another function to write a callback so I can scroll to the toggled area when it's visible.
$("#MyID").click(function () {
$("#openThis").slideToggle("slow");
});
But I can't seem to get it to work. What am I doing wrong?
are you adding the listener before or after the object is created on the DOM?
because if you are trying to bind that onclick function without waiting the document to be ready theres no object to create the listener.
something like this could work:
$(document).on('ready', function() {
$("#MyID").click(function () {
$("#openThis").slideToggle("slow");
});
});
If you button is added dynamically then use on instead of click
Attach an event handler function for one or more events to the
selected elements.
Event handlers are bound only to the currently selected elements; they
must exist at the time your code makes the call to .on()
//Instead of document you can use a container id
$(document).on('click',"#MyID",function () {
$("#openThis").slideToggle("slow");
});
What this approach does is it adds event to a currently selected element which is document here and it will delegate the event to your selector which is #MyID in this case.
Delegated events have the advantage that they can process events from
descendant elements that are added to the document at a later time.
$(document).on('click', '#myBtn', function(){
$('#foo').slideToggle('slow');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<div id="foo">content</div>
<button id="myBtn">Click me</button>
You want to scroll to the area so remove the JavaScript from the button
You need to do something like this
$("#MyID").click(function() {
$('html, body').animate({
scrollTop: $("#openThis").offset().top
}, 2000);
$("#openThis").slideToggle("slow");
});
You should delete the onclick="" attributes in the button tag and in your javascript :
$("#MyID").click(function (e) {
e.preventDefault();
$("#openThis").slideToggle("slow");
});
Use the prevent default.
Hope that help

target a button inserted by ajax with javascript

hello i'm inserting this image with a button by ajax when visitor upload an image
for (var i = 0; i < data.length; i = i + 1) {
imageThump += '<img src="' + data[i].path + '" />';
imageThump += '<button id="edit-details" type="button" class="btn btn-info">Edit Details</button>';
}
$('#uploaded-images-thumb').append(imageThump);
i want to target the button with javascript but it keeps failing ???
$('#edit-details').on('click', function(){
console.log('clicked');
});
You need to deal with dynamic event (aka live event). As the button injected into DOM after DOM load.
$('body').on('click', '#edit-details', function(){
console.log('clicked');
});
NOTE: instead of body, should bind to its closest non-dynamic parent element.
If your #uploaded-images-thumb is non-dynamic then better to bind against it. like:
$('#uploaded-images-thumb').on('click', '#edit-details', function(){
console.log('clicked');
});
For more detail check .on()
You need to delegate the event, because when you inserted your event handlers, the element was not present:
$("body").on('click', '#edit-details', function(){
console.log('clicked');
});
So we have selected body, which is a static tag and delegate the events inside them. Also, as a side-note, it is better to bind the event to the closest static parent and not the absolute parent, which is the document or the body.
In your example, it could be like:
$("#uploaded-images-thumb").on('click', '#edit-details', function(){
console.log('clicked');
});
Exactly what was mentioned above is the answer. Essentially the element doesn't possess the same events (click) as the existing DOM elements, so when it's dynamically generated you don't have access to the needed events for the new element.
To expand on what the other posters have mentioned, Here is a small example of the structural idea.
<div id="element-wrapper">
<button class="my-btn">Existing Button (has event)</button>
<button class="my-btn">Existing Button (has event)</button>
<button class="my-btn">Just Dynamically Added to DOM!!!</button>
</div>
This code below will work for all the buttons except the last one:
$('.my-btn').click(function() {
alert('Clicked!');
});
This code below will work for ALL buttons (since '#element-wrapper' is not dynamic):
$('#element-wrapper').on('click', '.my-btn', function() {
alert('Clicked!');
});

jquery .on() doesn't work for cloned element

It seems .on() failed to bind newly created element from clone()
<div class="container">
<div class="add">add</div>
</div>
$(".remove").on("click",function() {
$(this).remove();
});
$(".add").on("click", function() {
$(this).clone().toggleClass("add remove").text("remove").appendTo($(".container"));
});
jsfiddle
Why this doesn't work?
Update:
please note that, I know .clone() takes two parameters, but I don't want to let the cloned element continue registered to the old events, but a new one, I could use .off() and .on() to register again, but my question is why the previously declared .on(".remvove") didn't capture the change in the cloned element.
Because you need to pass a boolean parameter to clone so that all data and event handlers will be attached to cloned element.
https://api.jquery.com/clone/
$(".remove").on("click",function() {
$(this).remove();
});
$(".add").on("click", function() {
$(this).clone(true).toggleClass("add remove").text("remove").appendTo($(".container"));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="container">
<div class="add">add</div>
</div>
Edited
$(".container").on("click", '.remove', function() {
$(this).remove();
});
$(".add").on("click", function() {
$(this).clone().toggleClass("add remove").text("remove").appendTo($(".container"));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="container">
<div class="add">add</div>
</div>
"my question is why the previously declared .on(".remvove") didn't capture the change in the cloned element."
Because the event listener was attached to all the elements with class names .remove which existed in the DOM at that point in time.
But with clone you created a new Element. It has just been created. A fresh node. How can your earlier listener work on this.
Solutions:
1.) Either use event delegation and attach your listener to a static ancestor node
2.) Pass the boolean flag while calling the clone function so that your listeners also get copied.
3.) Register the Event Listener Again on that node.
Unbind and bind the function.
bindEvent();
function bindEvent(){
$(".remove").unbind("click");
$(".remove").bind("click",function() {
$(this).remove();
bindEvent();
});
$(".add").unbind("click");
$(".add").bind("click", function() {
$(this).clone().toggleClass("add remove").text("remove").appendTo($("body"));
bindEvent();
});
}
jsfiddle

Jquery appending with styling and functions

i appending buttons with some IDs and i use those IDs to make on click stuff
when it appending didn't take button() effect
and on click it don't take the function that I created it for this button id
$("button#edit-doc").each(function() {
$(this).button();
$(this).on("click", function(){
alert("clicked");
});
});
append button
$("#append").on("click", function(){
$('div#container').append("<button id='edit-doc'> Edit </button>");
});
container
<div id="container"></div>
This seems to be what you're after:
function handler() { alert('clicked'); }
$("#append").on("click", appendButton);
function appendButton(){
$('#container').append(function() {
return $("<button id='edit-doc'> Edit </button>").on("click", handler);
})
}
http://jsfiddle.net/PF8xY/
See jQuery how to bind onclick event to dynamically added HTML element for more information on this behavior.
$(document).on("click", "#selector", function(){
//Your code here.
});
Using document for your selector with .on will allow you to bind events to dynamically created elements. This is the only way I've found to do it when the DOM elements don't exist prior to execution.
I do this in a dynamically created table that is sort-able and works great.
EDIT:
Here is an example. Click the button to add a div then click the div to get it's contents.
http://jsfiddle.net/FEzcC/1/
The first code-block attaches an event listner to all buttons with class='edit-doc', use classes instead of an id since an id's name may only exist once per page. So I was saying, when your browser reaches this code an event listner is added to all available buttons in your document at that moment. It doesn't add an event listner to buttons you will be adding later onclick of some element, because it doesn't know. You will have to explicitly execute the code again for the buttons that you append. But what you don't want is to add a new event listner to the original buttons, causing two events being called.
Something like:
// Load all buttons with class=edit-doc and add event listner
$(function() {
$("button.edit-doc").button().on("click", function(){
alert("clicked");
});
});
// Append button if button with id=append is clicked
$("#append").on("click", function(){
var button = $.parseHTML("<button class='edit-doc'>Edit</button>");
$('div#container').append(button);
$(button).button().on("click", function(){
alert("clicked");
});
});
Working example:
http://jsfiddle.net/RC9Vg/

Categories

Resources