Get click handler from element in JQuery - events

How can I get a reference to the click handler of an element in JQuery?
Here is what I am trying to do:
Store the click handler,
Change the click handler for the next click,
Restore the original click handler
var originalClick = $(settings.currentTarget).click;
$(settings.currentTarget).off("click");
$(settings.currentTarget).click(function (e) {
e.preventDefault();
settings.model.modal.close();
$(settings.currentTarget).off("click");
$(settings.currentTarget).click(originalClick);
});
The above code works the first time, however, when I click on the element again it fails:
Uncaught TypeError: Object [object HTMLAnchorElement] has no method 'on'
Update:
I now realize that this is a really bad design that I am trying to do. I have resolved this issue by maintaining a visibility boolean in my viewmodel, if it is true, don't re-open the modal.

$(...).click is the jQuery click() method, not your event handler.
You can use an undocumented internal API to get the list of event handlers:
jQuery._data( elem, "events" );

What happens if you try it this way?
var originalClick = $(settings.currentTarget).click;
$(settings.currentTarget).off("click");
$(settings.currentTarget).on("click",function (e) {
e.preventDefault();
settings.model.modal.close();
$(settings.currentTarget).off("click");
$(settings.currentTarget).click(originalClick);
});

Related

ajax loaded content issue with chrome

I have a problem when I dynamically load content with the following code.
$(document).ready(function() {
$("#tags").keyup(function(){
var q = $(this).val();
$.ajax({
url: '/AnswerMedia/utilities/autoSearch/model/suggest.php?q='+q,
success: function (data) {
$("#ajaxDiv").html(data);
},
error: function (request, status, error) {
alert(request.responseText);
}
});
});
});
After the content loads, this code was intended to trigger an event when one of the loaded div tags is clicked, but did not.
$(".pdiv").click(function(){
var val = $(this).text();
$('#tags').val(val);
$('.mncontr').hide();
});
$("#closeSearch").click(function(){
$('.mncontr').hide();
});
Then I tried the following code:
$("body").delegate(".pdiv", "click", function(){
var val = $(this).text();
$('#tags').val(val);
$('.mncontr').hide();
});
$("body").delegate("#closeSearch", "click", function(){
$('.mncontr').hide();
});
It works well in Firefox, but in Chrome the problem persists. Please help me.
From this SO post:
If you want the click handler to work for an element that gets loaded
dynamically, then you set the event handler on a parent object (that
does not get loaded dynamically) and give it a selector that matches
your dynamic object like this:
$('#parent').on("click", "#child", function() {});
The event handler
will be attached to the #parent object and anytime a click event
bubbles up to it that originated on #child, it will fire your click
handler. This is called delegated event handling (the event handling
is delegated to a parent object).
It's done this way because you can attach the event to the #parent
object even when the #child object does not exist yet, but when it
later exists and gets clicked on, the click event will bubble up to
the #parent object, it will see that it originated on #child and there
is an event handler for a click on #child and fire your event.

jQuery unable select element from getJSON

I'm using the .each method with the .getJSON method to print out objects in a JSON file. This works fine, however I am unable to add a click function to an element that has been printed out. I am trying to bind a function to the div with 'click' ID.
var loadData = function () {
$.getJSON("profiles2.json", function (data) {
var html = [];
html.push("<div id='click'>Click here</div>");
$.each(data.profiles, function (firstIndex, firstLevel) {
html.push("<h2>" + firstLevel.profileGroup + "</h2>");
});
$("#data").html(html.join(''));
});
};
$(document).ready(function () {
loadData();
$("#click").click(function () {
console.log('clicked');
});
});
$.getJSON() (like other Ajax methods) is asynchronous, so it returns immediately before the results have come back. So your loadData() method also returns immediately and you then try to bind a handler to an element not yet added.
Move the .click(...) binding into the callback of $.getJSON(), after adding the element(s), and it will work.
Alternatively, use a delegated event handler:
$("#data").on("click", "#click", function() {
console.log('clicked');
});
...which actually binds the handler to the parent element that does exist at the time. When a click occurs it then tests whether it was on an element that matched the selector in the second parameter.
And as an aside, don't bind click handlers to divs unless you don't care about people who are physically unable to (or simply choose not to) use a mouse or other pointing device. Use anchor elements (styled as you see fit) so that they're "click"-accessible via the keyboard and the mouse.
$.getJSON is an asynchronous call and probably hasn't finished by the time you are trying to bind to the element that it injects into your DOM. Put your binding inside the $.getJSON call after you append the element to the page at the bottom.

jQuery: toggleClass event handling function for ajax function

I was wondering if someone can help guide me how I can write a event when I'm using toggleClass in jQuery?
I have a list of items and when I click on an item, it highlights it, and when someone clicks another item from the list, the previous highlighted item goes away and highlights the current click. Also, if I click the same item that has been highlighted, it goes away.
Now I'm trying to write a function to call ajax when only its been highlighted. So it won't run the ajax function again when its being pressed again (when highlight is removed).
$(".media").on('click',function(){
var $this = $(this);
// highlighting the object
$this.toggleClass('selectMedia').siblings().removeClass('selectMedia');
// saving the id
var selId1 = $this.data('id');
$.post("ajax/ajax_sessions.php", {"sel_1":selId1}, function(data) {
alert(data); // alerts 'Updated'
});
});
Thank you for help!
Just check for the existance of the class before doing your AJAX request:
if ( ! $this.hasClass('selectMedia') ) return;
// Now do your AJAX request...

Dojo Dialog onEnd() animation exception

I have a problem with the Dojo Dijit Dialog .hide() method during the animation sequence. I am using Dojo 1.7 with Tundra theme. I have a cancel button in my dialog that closes the dialog.
var global_welcome = new Dialog({
id: 'global_welcome',
style: "width: 750px",
draggable: false,
content: '<button type="button" id="global_welcomeCancel"> Cancel </button>',
onShow : function () {
on(dojo.byId('global_welcomeCancel'), "click", function (evt) {
dojo.stopEvent(evt);
global_welcome.hide();
});
});
}
});
This produces the following error on Firebug:
exception in animation handler for: onEnd fx.js (line 152)
TypeError: this._fadeOutDeferred is undefined
this._fadeOutDeferred.callback(true);
Previous answers to this error but with destroyRecursive instead of hide suggests it has to do with the dialog being destroyed before the animation finishes. I tried using dojo.hitch() and setTimeOut but that didn't seem to work. Also what is puzzling is that the first time I open this dialog using global_welcome.show() (called by another button), and press the cancel button, it works without error. The second time and afterwards, it produces the above error message. Additionally, the default close button for dojo dialogs on the top right corner never causes this error. Perhaps I could just have onShow call the methods that the close button calls?
Can someone help me out please? Thanks in advance!
The problem is in your onShow method. You wire up to the click event to hide, but never disconnect it. When you open the dialog the again, you wire the click method to hide the dialog again. The result is that hide will be called twice when you try to close the dialog for the second time. The error gets thrown with the second call to hide because the animations have already been destroyed.
Try this:
var signal = on(dojo.byId('global_welcomeCancel'), "click", function (evt) {
dojo.stopEvent(evt);
signal.remove();
global_welcome.hide();
});

how to fake a click on a dynamic element?

On a static element, to fake a click, I use
$(selector).click();
But how can I do the same thing on a dynamic element (resulted from an ajax call)?
The same...:
$(selector).click();
Why didn't you try it first?
P.S. it is not called fake a click, it's called trigger the click event.
$(selector).trigger('click'); == $(selector).click();
Update
You need to bind that element a callback to the event in order it to work:
$(selector).click(function(){...});
$(selector).click();
If you want it to have the the click callback you assigned to the static elements automaticlly, you should use on\ delegate (or live but it's deprecated) when you attach the click callback.
$('body').on('click', 'selector', function(){...})
instead if body use the closest static element the holds that selector elements.
See my DEMO
within your ajax success function try your code:
$(selector).click();
Basing this on your previous question : How can I select a list of DOM objects render from an AJAX call?
$(document).ready(function(){
var listItems = $('#myList li a');
var containers = $('#myContainer > div');
listItems.click(function(e){//do someting
});
etc...
If the elements you are trying to attach a click handler to are supposed to be inside any of the two variables above then you WILL have to update those variables after the elements are inserted into the DOM, as it is right now only elements that exists during first page load will be inside those variables.
That is the only reason I can think of why something like :
$(document).on('click', listItems, function(e) {//do something
});
will not work!
Don't know if I understand (I'm french sorry...)
But try :
$(selector).live('click',function(){}); // deprecated it seems
Demo of gdoron with live() : http://jsfiddle.net/Rx2h7/1/
use on() method of jquery,
staticElement.on('click', selector, function(){})
on method generates click event on dynamically created element by attaching it to the static element present in the DOM .
For further reference check this out -- https://api.jquery.com/on/

Resources