I'm building some dynamic select lists with jQuery. When they are changed, I want the event to trigger a function to get a data refresh.
var selector = $('<select id="myid" />');
selector.append($('<option value>Option Placeholder</value>'));
// attach onChange event to select list
selector.bind('change', doUpdate(this));
My problem is that the change event gets fired every time the select list is built. I'm not sure how the trigger is happening-- I'd expect it to only trigger the change event when it, well, changes!
http://jsfiddle.net/TPuwc/
When you do this:
selector.bind('change', doUpdate(this));
what you're expecting to happen is to bind the event handler to execute the doUpdate function, passing this as an argument.
That isn't what's happening. Instead, what it's doing is calling doUpdate(this) immediately, and then attempting to set the value returned by that function call as the event handler for the change event.
You can simply do:
selector.bind('change', doUpdate);
jQuery will handle the value of this for you (it will be the element triggering the event), so you don't need to pass it in to the function as an argument.
You'll have to understand the difference between function calls and function references. Every callback should be provided as a function reference (or an anonymous function) and not a function call.
The difference is the parentheses () after the function name.
selector.bind('change', doUpdate);
EDIT: Be sure to update the doUpdate function. It will automatically have access to the element that triggered the change using the this keyword, so you don't need to pass it as a parameter.
Your event arrachment method is wrong. for event attachment you should pass function. while here you are executing function and passing return value.
var selector = $('<select id="myid" />');
selector.append($('<option value>Option Placeholder</value>'));
// attach onChange event to select list
selector.bind('change', function(){ doUpdate(this) });
Related
I have some JavaScript/jQuery code that needs to call the checkbox's click handler after it completes.
I can use trigger() to call that handler; however, I see that this also causes the checkbox's checked state to toggle (as though it had been clicked).
Is there any way to call a click handler without actually performing a click on the checkbox?
Is there any way to call a click handler without actually performing a click on the checkbox?
Yes
The handler is just a function. Call the function:
function example() {
$(this)...do something...
}
$(...selector...).on('click', example);
...elsewhere...
$(...another selector...).each(example)
If you don't have a reference to the function, and you want to trigger all handlers on the element without triggering the native behaviors, you can use jQuery's .triggerHandler() method.
$(...selector...).on('click', function () {...})
...elsewhere...
$(...another selector...).triggerHandler('click')
I wanting to get the currentTarget to pass to a function, once I have changed the value of a select programmatically.
Is this possible? Something like,
$('input[name="client_id"]').val(model.get('id')) //Change the value of select
this.doSave( $('input[name="client_id"]')); //Do save expects event(e) as parameter
function doSave(event){
console.log($(event.currentTarget);
}
I have simplified this down massively, basically I am changing a select programmatically, and then want to fire my save event, which normally gets triggered on a change event, and as a result takes an event as a parameter, but all I have is the DOM element? Is there a way to send it an event?
Use the change event handler as below :
$('input[name="client_id"]').on('change', function(event) {
console.log($(event.currentTarget);
});
or
$('input[name="client_id"]').on('change', doSave);
function doSave(event){
console.log($(event.currentTarget);
}
First of all,
This
$('input[name="client_id"]')
apparently, changes the value of an input and not select.
This
$('select[name="client_id"]').val(model.get('id'))
changes the selected option in a select.
You can bind the change event on a select like
$('select').change(function(event){
//use event here
//or pass to doSave(event)
});
and it will be fired when call
$('input[name="client_id"]').change();
Ok lets say I have
<div id="container"/>
and I put a button in this container with id = "button". Then I make .click handler for it
$("#button").click(function() {
foo();
}
Then I change the innerHTML of the div like this:
$("#container").html = "<h1> Foo </h1>";
Then I set timer for let's say 5 seconds that after that will execute the following code :
function(){
$("#container").html = "<button id="button" type="button">Click Meh!</button>"
$("#button").click(function() {
foo();
}
}
My question is: The first button was "destroyed", so was the first .click() handler for it destroyed too? Or the second .click() will just make a second handler for the same button and if I want to have only 1 handler I have to use $("#button").off("click") before calling the second .click() ?
Yes, when you removed the element (by overwriting the html of the element), you've disassosciated the click handler with the element.
Instead, we should just be looking at delegating the event. We target a static parent element (like container), and delegate the event to it:
$('#container').on('click', '#button', foo);
Now when the button is clicked, we'll fire off the foo function. Even if you remove the button and add it later, the event will still be delegated to '#container'.
Yes once you deleted the button the first handler will also destroyed because you are using ".click()" function. You no need to explicitly remove that click handler.
or else use the below ".on" function then you no need to write the function again and again. it will check dynamically adding elements and attach the events.
$( "body" ).on( "click", "#button", function() {
foo();
});
If your question is if you have to re-bind the onclick handlers when the dom changes, the answer is yes.
If you're asking what happens to the handler function, my guess is it will get garbage collected when the node gets deleted, if you want to avoid the creation of several functions, just write the handler as named function, and use that instead of anonymous one..
If you're asking whether the handler will get bound twice: it will get bound to whatever is in the selection result, if the first button exists when you run the .click then it will, though #id only returns 1 node so, it will bind to the first #button it finds, regardless of if it's already bound...
I have this event handler that looks something like:
$(document).on('click', 'a.close, #mask', Popup.close);
and I can't figure out how to change the function (Popup.close) dynamically for this event. The Popup.close variable is a local function that can be set by calling Popup.setClose(func), and I was hoping that this would then change the function that is called when this event is fired. I then realized that I may have to unbind the event, and bind the new function every time I want to change the Popup.close() function. Regardless, I could not figure out how to unbind and event that was previously bound using the .on('click',...) method.
So what I am asking is, what is the best way to change the executing function for a jQuery event bound using the .on() method?
I appreciate your help.
You can use .off("click") to remove the event and then attach the new event, but this will remove all click events.
$(document).off('click');
Or to preserve other events that may have been attached:
$(document).off('click', 'a.close, #mask');
JS Fiddle: http://jsfiddle.net/3Xzjj/
I've got a bunch divs which each contain a remove link attached with the click event below:
var observeRemoveRoom = function
$('.remove_room').click(function(){
$(this).parent().removeClass('active');
});
}
Clicking it removes the 'active' class of the parent (the div). I call this observeRemoveRoom function on window load which works fine.
The thing is, I have another function which adds more of the same divs. Since the a.remove_room links contained within the new divs weren't around on window.load I need to call observeRemoveRoom.
Am I somehow duplicating the event handlers? Does jQuery overwrite them? If so should I unbind the handlers?
Each time you call observeRemoveRoom jQuery will add a new unique event handler function for a click event.
So yes, you need to .unbind() either all currently bound handlers by just calling .unbind() without arguments, or be specific and pass in a function reference.
You can try a live query to keep them updated: http://docs.jquery.com/Plugins/livequery
Yes, you will be duplicating the event-handlers if you call observeRemoveRoom again, but it might not be noticeable since you are only calling the removeClass method which does nothing if the class is not found, which would be the case after the first listener is triggered.
Instead you can un-bind and re-bind the click event each time, like:
var observeRemoveRoom = function(){
var remove_class = function(){
$(this).parent().removeClass('active');
};
$('.remove_room').off('click', remove_class).on('click', remove_class);
}
But that said, it is recommended that you do this outside this function`, rather than binding and unbinding the event every time, like:
$(document).ready(function(){
var remove_class = function(){
$(this).parent().removeClass('active');
};
// If the element exists at dom ready, you can bind the event directly
$('.remove_room').on("click", remove_class);
// If the element is added in dynamically, you can [delegate][1] the event
$('body').on("click", '.remove_room', remove_class);
// Note: Although I've delegated the event to the body tag in this case
// I recommend that you use the closest available parent instead
});
http://api.jquery.com/on/#direct-and-delegated-events : [1]