Jquery click event is not working properly - javascript

I want a new text input box will be appended when i click onto the latest generated text box.
But It generates new text input box only when i click the first text input box. So, any solution?
<script type="text/javascript">
$(function(event){
$('.add-new').click(function(){
$('.add-new').removeClass();
$('form').append("<br><input type='text' name='user[]' class='add-new'/>");
});
});
</script>
<div>
<form method='post' name='login'>
<input type='text' name='user[]' class='add-new'/>
</form>
</div>

$('form').on('click','.add-new', function(){
Direct event => Delegate Event
Live DEMO
Full code:
$('form').on('click', '.add-new', function() {
$(this).removeClass('add-new');
$(this).closest('form').append("<br><input type='text' name='user[]' class='add-new'/>");
});​
Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to .on(). To ensure the elements are present and can be selected, perform event binding inside a document ready handler for elements that are in the HTML markup on the page. If new HTML is being injected into the page, select the elements and attach event handlers after the new HTML is placed into the page. Or, use delegated events to attach an event handler, as described next.
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.
on docs

demo http://jsfiddle.net/JuvwB/8/
Plz note: you should use $(this) as your even is bind to .add-new already.
rest all the above are nice solutions,
Hope this helps, cheers
code
$(function(event){
$('.add-new').on('click', function(){
$(this).removeClass();
$('form').append("<br><input type='text' name='user[]' class='add-new'/>");
});
});​

$('form[name=login]').on('click', '.add-new', function() {
$(this).removeClass(); // $(this) instead of $('.add-new')
// $(this) point to the clicked element
// which you want
$('form').append("<br><input type='text' name='user[]' class='add-new'/>");
});
As you're changing the class name add-new and append new element dynamically with same class, so you need delegate event.
Read more about .on()
Note
syntax of .on() for delegate event
$(container).on(eventName, target, handlerFunction)

The reason why this doesn't work is because when you set the 'click' event your target doesn't exist, so no 'click' event is bound to it.
jQuery has a fancy function called the 'on' function that catches bubbling events.
$(document).on('click','.add-new', function(){
}
All events (click, mouseover, etc) start in the deepest node and bubble up through the html tree until the document. It is safe for you to catch them in the document, unless you explicitly call "stopPropagation" or return false on a processed in the middle of the bubling click handler function.
You can also catch it in the middle of the tree with $("form").on... or even $("div").on...

Related

jQuery the new appended data can not be captured by .on()

I am trying to get the value of an input box that been .append() to the HTML recently. The Input box does not exist normally. it get .append() on button click by a function.
The Value of the input should be captured and sent via jQuery Ajax to backend(php).
The Function which append the Input field:
function toggleOrder(){
$(".orderContainer").append(`
<div class="orderFilterBox">
<input id="orderFilterInput" type="text" placeHolder="Enter IMEI">
</div>
`);
}
The Function where the input value captured and sent to backend
$(document).ready(function(){
$("#orderFilterInput").on("change paste",function(){
//DO THE MAGIC
//...
});
});
I belive that the problem being there that the code on the pageload where the input not exist. im not sure how to avoid that.
Also if you would suggsest a better question title to help other people, then please go for it
if you use .on you need focus on static element which exist in page load. orderFilterInput.on is bad if orderFilterInput does not exist.
You can try
$(document).on("ready", function(){
$("body").on("change paste","#orderFilterInput", function(){
//DO THE MAGIC
//...
});
});
or you can make your append button by jquery with event in your append function.
const btn = $('<input id="orderFilterInput" type="text" placeHolder="Enter IMEI">')
.on('copy paste', function() { .. });
$container.append(btn);
Event handlers are bound only to the currently selected elements; they
must exist at the time your code makes the call to .on(). To ensure
the elements are present and can be selected, place scripts after the
elements in the HTML markup or perform event binding inside a document
ready handler. Alternatively, use delegated event handlers to attach
event handlers.
Delegated event handlers 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 event handlers 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.
Here is the api reference:
https://api.jquery.com/on/
, So as suggested by #daremachine you need to use the delegated event handler
as:
$(document).on("change paste","#orderFilterInput", function(){
//DO THE MAGIC
//...
});

Remove jQuery delegated event handler on specific object

I've attached delegated event handlers to a number of elements on the page using a single selector. As the events are triggered for individual elements, I'd like to turn off only that element's event handler based on some conditional logic. That means I won't necessarily want to disable the event on the very first click. But I can't figure out how to do it without turning off all of them.
HTML:
<button>One</button>
<button>Two</button>
<button>Three</button>
JS:
$(document).on('click', 'button', function(ev) {
// doesn't work because argument needs to be a string
$(document).off('click', $(ev.target));
// doesn't do what I want b/c turns off events on all buttons, not just this one
$(document).off('click', 'button');
// doesn't work because event is on document, not button
$(ev.target).off('click');
});
jQuery's off documentation says I need to provide a string as the second argument, not a jQuery object ($(ev.target)), but if I provide a string, there's no value that refers only to the item clicked.
From jQuery's off documentation:
To remove specific delegated event handlers, provide a selector
argument. The selector string must exactly match the one passed to
.on() when the event handler was attached. To remove all delegated
events from an element without removing non-delegated events, use the
special value "**".
So how do I turn off a delegated event handler for a specific element?
Here's a JSFiddle of the code above
UPDATE: Added a few examples of options that don't work, based on initial answers provided.
After having read thru on the web, the answer is you can't! You can either remove all or none. A workaround could be something like the following.
$(document).on('click', '.btn', function (ev) {
alert('pressed');
$(this).removeClass("btn");
});
Demo#Fiddle
Sample HTML:
<button class="btn">One</button>
<button class="btn">Two</button>
<button class="btn">Three</button>
In addition to what lshettyl said (the current top post) - an additional work around is to bind a new event listener directly to the element that you're trying to remove the listener and call stopPropagation() therein.
What this will do is prevent the event from traveling up the DOM and reaching the event handler that is initially bound to the document. Also this will allow you to keep some functionality on the button click, such as an alert to the user that this button has already been clicked - or something to that effect.
$(document).on('click', 'button', function(ev) {
// Your logic to occur on button click
// Prevent further click on just this button
$(this).click(function(event) {
event.stopPropagation();
}):
});
Question: Do you have to use the delegated events? LIke LShetty said, it is not possible to remove a delegated event for a single element. You either remove the entire event delegation, or leave it. You could try using a different selector instead like in this example
$('button').on('click', function(ev) {
$('#output').append('Clicked! ');
$(this).off('click');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<button>One</button>
<button>Two</button>
<button>Three</button>
<div id="output"></div>

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!

Is binding a click event to a null selector dangerous?

Is there anything wrong that can happen if I bind a null selector using on? It would simplify my code and allow me to chain a few things if I didn't have to explicitly check if the selector is null myself.
Any performance, security, or memory-leak implications if I do this a dozen times on my page?
$(document.body).on('click', null, function () { ... }
If you plan on dynamically adding elements, there is nothing wrong by binding on a higher element using the .on() method.
Keep in mind though you have to specify a selector that will ultimately define the dynamically added elements.
The code below will fire when a label is clicked.
$(document).on('click', 'label', function(e) {
alert('dynamically added label clicked');
});
This code will fire when any element is clicked.
$(document).on('click', null, function (e) {
alert('fired regardless what element you clicked');
});
From the jQuery docs:
A selector string to filter the descendants of the selected elements
that will call the handler. If the selector is null or omitted, the
handler is always called when it reaches the selected element.
If your problem is that the elements that raise the click event are dynamically added you can still use a direct event handler on body and catch those events.
The delegated event handler gives you the opportunity to filter out some of those click events, but it seems that's not the case since you are setting the selector to null.
For example, if you have a div and add buttons inside and add an event handler to the click event on the div you'll catch all the click events from all the buttons, even the ones added dynamically.
<div>
<input type="button" value="add button" id="buttonAddMore"/>
<span id="whatClicked"></span>
</div>
$('div').on("click", function(event){
$('#whatClicked').text("the id of the clicked element inside the div is: " + event.target.id);
});
This fiddle demonstrates this.
The delegated events have other subtleties, such as, they won't respond to events raised in the elements they are registered in, in this example that would be a click on the div, and that might be important.
Either way if you look at how the events are registered, in your case you can have a look by calling in the console $._data(document.body, "events") and have a look at the click event handler with your method and registered using the shorthand version (i.e. .click or on("click", function() {...})) you'll see that they produce the same object, except for the selector being null (.on("click", null...) in one case and undefined in the other (.click)

Does attaching event handler with a class selector affects dynamically added elements of that class?

I am using jQuery to attach a function to my click event for an entire class. For example:
$(".clickDiv").click(function(){
$(this).hide();
});
On my client-side javascript, I create more .clickDiv instances dynamically.
Do I need to call the $(".clickDiv).click(function...) again, or will the new instances automatically have that function bound to the click event?
Yes you do, unless you use a delegate event
like this:
$('#container').on('click', '.clickDiv', function() {
$(this).hide();
});
on docs:
If selector is omitted or is null, the event handler is referred to as direct or directly-bound. The handler is called every time an event occurs on the selected elements, whether it occurs directly on the element or bubbles from a descendant (inner) element.
When a selector is provided, the event handler is referred to as delegated. The handler is not called when the event occurs directly on the bound element, but only for descendants (inner elements) that match the selector. jQuery bubbles the event from the event target up to the element where the handler is attached (i.e., innermost to outermost element) and runs the handler for any elements along that path matching the selector.
Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to .on(). To ensure the elements are present and can be selected, perform event binding inside a document ready handler for elements that are in the HTML markup on the page. If new HTML is being injected into the page, select the elements and attach event handlers after the new HTML is placed into the page. Or, use delegated events to attach an event handler, as described next.
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.
Just because too much people here suggested you should use live, live is deprecated since version 1.7 by on and was replaced in version 1.4.3 by delegate
$(selector).live(events, data, handler); // jQuery 1.3+
$(document).delegate(selector, events, data, handler); // jQuery 1.4.3+
$(document).on(events, selector, data, handler); // jQuery 1.7+
I am attaching an event like :
$('body').on('click', 'button[data-tracking], a[data-tracking]',
function(event) { console.log($(event.target));
});
and want to get to the target of element which is set up as :
<pre> <[]a data-tracking="hello" href="hello">
\<\span\>test now\<\/span\>
\<\/a\>
</pre>
it does work perfectly, but event.target gives me "span" element but what i want is "a" element so that I could get to value of data-tracking attribute.
This will bind the event to all new instances
$('.clickDiv').live('click', function() {
$(this).hide();
});
http://api.jquery.com/live/

Categories

Resources