jQuery live confirm - javascript

I'm having problems with .live() and confirm. It's multiplying the confirm dialogs for every click. I know about .die() but i can't get it to work.
$("button.del").live("click", function(){
if(!confirm("Are you sure?")) {
//close
}
});
I've tried $("button.del").die("click"); right after the above code, in which case the confim doesn't even fire.

Does the dialog box appear multiple times if you just run that code by itself?
If the dialog box is appearing multiple times, one likely explanation is that you are accidentally running this .live() binding more than once. If that happened, you would see one dialog box for each time you bound an event to the button.
Make sure you are only attaching this function to the button once.
If you take a look at this standalone example, you can see that your code is fine.

Can you post the HTML as well.
One cause I can speculate for this is that the .del class is specified into some child class, and the event is firing on both parent and child. This would happen for the following:
<div class="testclass">
test
<div class="testclass">
test2
</div>
</div>
...
$(".testclass").click(function() { alert("test"); });
Another reason would be if you accidentally bound it twice, i.e. the following would cause the same problem
$(".testclass").click(function() { alert("test"); });
$(".testclass").click(function() { alert("test"); });
We really need to see more of your code. You must utilise live for a reason. Do you get the same result with a simple click() binding?

Thank you all for your replies...turn out it was a bug in my code... Sorry...
I didn't see it... the part of the code with confirm was reloading on every click...hence the multiplying...

Related

If div changes content

if a div changes its content after a button click, is there some way to hide another div.
for example after i hit on submit button <div id="dynamic">1</div> changes to <div id="dynamic">2</div> once it shows 2 i would like to hide the submit button completely.
i was trying to work something with the below, hope it makes sense.
$(document).ready(function(){
$('#dynamic').bind('DOMNodeInserted DOMSubtreeModified DOMNodeRemoved', function(event) {
$("#submitbutton").hide();
})
})
thanks in advance.
If there is some async action involved and you don't know the exact timing when the content will be changed you could use a MutationObserver to observe a specific DOM element and execute logic if the condition within the MutationObserver is met: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
If the change of your div content is based on an API call that returns the change you could run a callback function to hide the submit button once the promise is fullfilled: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
If it is really as simple as in your example, that you click on submit and then logic to change the div is executed, you could just write the logic to hide your submit button on the next line or as a callback function after click execution.
If you are using newer version of jQuery, bind is deprecated and you should use on instead. This works for me, though as mentioned in another answer this might not be fully cross browser compatible.
$(document).ready(function(){
$('body').on('DOMSubtreeModified', '#dynamic', function(event) {
$("#submitbutton").hide();
});
});
Here's a link to a working example: https://jsfiddle.net/ky43hx6q/

Trying to change jQuery click handler of parent fires off new click event

I'm experiencing some (to me) unexpected behavior from event listeners using jQuery, but I expect it's just the underlying Javascript functionality that's confusing me. I think there's a good chance that the answer to my problem is fairly simple, but I can't figure it out.
I have a <div> with a status in it, which is 'New' by default. I want to be able to click on that <div> and bring up a pair of buttons, one which allow you to replace the 'New' status text with 'Complete', and another which will cancel the action, removing the buttons and displaying the 'New' status text again.
I can get everything to work, and it all works fine if I use a different element to display the buttons, but when I try to temporarily replace the text in the <div>, something strange happens.
When I try to reset the original click event for the <div>, what appears to happen is that the click on the cancel button also triggers the just-set click event as well. This re-displays the buttons, so it looks like the cancel button just didn't work. (I was stuck on that for a while...)
I've made a very simple JSFiddle that shows the problem I'm having:
https://jsfiddle.net/pn1q658w/4/
And there's also a slightly modified version that shows things working as long as I've got the cancel button in a different element than the element where I'm resetting the original click function:
https://jsfiddle.net/pn1q658w/3/
I assume this has something to do with the fact that I don't completely understand the way that the timing of these events works. The same click appears to be firing off an event that is set during an action taken because of that click, which I didn't expect, but may very well be how things are supposed to work.
My question is how can I have a click event which is trying to set a click listener on a parent element not fire off the new click at the same time?
Or, if I've completely misunderstood the nature of my mistake, an indication of what I have done wrong would be much appreciated. Thank you!
UPDATED
Just like #charlietfl said, I bleive that the simplest way is to separe the elements everyone with his own class, See WORKED FIDDLE HERE :
HTML :
<div id="elementId">
<span class='text'>New</span>
</div>
JS :
$(function(){
var newBtn = '<button class="btn btn-default complete">Complete?</button><button class="btn btn-default cancel">X</button>';
//Handle the click in the text span
$("#elementId").on("click","span.text",function(e){
$(this).html(newBtn);
});
//Handle the click in the complete button
$("#elementId").on("click","button.complete",function(e){
$('#elementId').html("<span class='text'>Completed</span>");
});
//Handle the click in the cancel button
$("#elementId").on("click","button.cancel",function(e){
$('#elementId').html("<span class='text'>New</span>");
});
});
I hope that this code help you.
The problem is you rewrite alaways content of div because you don't stop propagations.
I fix your problem with this code:
var oldCellContent = $('#elementId').text();
var newButtons = '<button class="btn btn-default complete">Complete?</button><button class="btn btn-default delete">X</button>';
$("#elementId").click(function(){
$(this).html(newButtons);
});
$("#elementId").on("click","button.complete",function(e){
console.log('The complete function fired.');
$('#elementId').text('Completed');
e.stopPropagation();
});
$("#elementId").on("click","button.delete",function(e){
console.log('The cancel function fired.');
$('#elementId').text(oldCellContent);
e.stopPropagation();
});
Need to understand that when you click on an element inside another element...you are still clicking on the parent as well.
Events "bubble" or "propagate" up the DOM tree all the way to the document...unless told to stopPropagation()
What you are seeing is expected behavior.
You can prevent that bubbling by:
$(selector).click(function(event){
event.stopPropagation();
});
There are some oddities in your code that could defintiely be streamlined
First you pass an element to the handler...then take properties of that elemnt to create a selector to find exactly the same element again in the DOM
var cellId = element.id;
$('#' + cellId)
Can be simplified to
$(element);// doesn't require searching for the ID
And can also be stored as a variable instead of doing the same selector over and over
var $el = $(element);
$el.off('click');
var oldCellContent = $el.text();
These simplifications are more efficient and easier to read
The simplest solution to all of this is wrap the "New" text in it's own element and put the "show buttons" click handler on that element and simultaneously hide "new".
Code will be much simpler and there won't be any propagation issues or need to use off() and then add same handler again.

Strange behaviour using .on() for click event - Fired twice

I already checked answers about click events fired twice. But I have a question about using .on().
Usually, I use it like this on dynamically added elements, and it always worked fine:
$(document).on("click", "dynElement", function(){})
In the current website I'm working on, I use it several times. But in the function that I'm trying to achieve, let's say, a dynamic "jump to page", click on page number is triggered twice:
$(document).on("click", ".jumpTo .number", function(){
console.log("Jump");
});
Trying to find the origin of this behaviour, I tried this syntax that works fine:
$(".jumpTo").on("click", ".number", function(){
console.log("Jump");
});
Can anyone explain what is the difference between these two different syntaxes (which look quite similar to me)?
And optionally, why is $(document).on("click", ".jumpTo .number", function(){}) triggered twice? (Optionally because I am not able to reproduce this behaviour in a Fiddle, everything works as it is supposed to).
$(document).on("click", ".jumpTo .number", function(){
console.log("Jump");
});
In this case the click handler is set on the document object. So whenever you click somewhere on the page, it will fire and look for a ".jumpTo .number" element inside it. If it finds it, it will check if the click was on it and your function will execute.
$(".jumpTo").on("click", ".number", function(){
console.log("Jump");
});
Here the click handler will be on .jumpTo
As Al.G said probably this code gets executed multiple times, so you actually add that handler multiple times, hence the double firing.
One way to solve it is to do something like this:
$(".jumpTo").unbind("click").on("click"...
Another is to change your code to make sure the .on() call doesn't get executed twice.

Event handlers not working correctly in jsfiddle

Trying to make a jsfiddle so I can post it on here and get some help with a problem; however, I'm having a problem getting jsfiddle to act as expected, so I'm having a problem trying to document my problem!
http://jsfiddle.net/eidsonator/he4Vc/#base
I'm trying to add a blur event handler to a input with id of "part". My alert fires as soon as the page loads (which it shouldn't) and doesn't fire when focus is lost. This behavior persists in chrome and in firefox (I'm coding for an internal web app, so I can ignore ie!)
$("#part").on('blur', alert('lost focus'));
I've changed the load method, and tried wrapping it in my own $(document).ready(function() {}); as well as using .blur() and different versions of javacript... any clues?
Thanks!
You are calling alert straight away, and passing the return value of it to the .on() method. Instead, you need to pass a reference to a function that can be invoked when the event is received:
$("#part").on('blur', function () {
alert('lost focus')
});
Here's an updated fiddle.
you have written a wrong syntax .see the docs for more info,and change your code to
$("#part").on('blur', function(){
//do something
});

jQuery late binding of Ajax elements doesn't work

I'm really stuck with a jQuery issue and I hope someone can help me out...
So I have a list of options on the left, and when you click on one, a form is generated via Ajax on the right. There's this element in the form:
<input type="text" class="value" value="something">
And what I want to do is to call
$(".value").tagsInput();
which is a jQuery plugin that works pretty much like Stack Overflow's 'Tags' input field when you ask a question.
So I tried this:
$(document).ready(function() {
$(".value").on("load", function () {
console.log("Tags Input");
$(".value").tagsInput();
});
});
and nothing is printed out. I've also tried this:
$(document).on("change", ".value", function () {
console.log("Tags Input");
$(".value").tagsInput();
});
and it doesn't work either. I'm wondering where I did wrong. Can anyone help me out?
As pointed out by Shabnam, the "change" event is not what you want, as it is fired only once the field is blurred.
Anyways, from the plugin documentation, it looks like you don't have to call that function every time a key is pressed, but it attaches its own event handlers autonomously.
So, probably you should be fine with just:
$(document).ready(function() {
$(".value").tagsInput();
});
Your .on handler will never work, as the load event is fired only by document when the page is ready.
If you want to debug things a bit, have a look at the supported callbacks, such as onChange.
SIDE NOTE
I don't like how that plugin is written, as it clogs the "global" jQuery.fn namespace with lots of functions, while jQuery documentation recommends not doing so (see: Namespacing).
UPDATE
See here: http://jsfiddle.net/aFPHL/ an example of this working (the .load() was monkeypatched to avoid having to call an actual URL, but its behavior is pretty much the same as the real one).
"change" event gets fired when the input element loses focus. If you want ajax call at the end of each key input, try using keyboard events

Categories