I have some weird problems with jQuery ajax. I am calling jQuery ajax function by .hover event and it is working fine.I am getting some response and I am displaying that response in div.
But if I want to call jQuery on <a> which has come as response from previous jQuery ajax call by .click event, I can not call it.
Can anyone help me out in this?
This is jQuery ajax function ..
function call_jqry_ajx(file_name,show_div_id,function_name,parameter){
$.ajax({
type: "POST",
url: file_name,
data: parameter,
success: function(msg){
alert( "Data Saved: " + msg ); //Anything you want
$("#show_div").html(msg);
alert("Done with div..");
}
});
}
$(document).ready(function ()
{
$(".a_class").click(function(){
alert("double times called but still getting alert.. :)");
return false;
});
});
in my div I get response like this ..
<div id="show_div">
<a class="a_class" id="a_id">Call Anchor</a>
</div>
I can not execute my jQuery function a tag's link
You are registering for the click event before the object is actually present in the page. Thus, it doesn't get an event handler assigned to it.
To remedy that, you should use either .delegate() (for pre-jQuery 1.7) or .on() (for jQuery 1.7+) to use delegated event handling. This registers for the event on a parent object of the actual content that will generated the event. You pick a parent object that is there at the beginning when you register the event and then event bubbling allows events in newly created objects to be captured.
You can change your code to this:
$(document).ready(function () {
$('#show_div').on('click', '.a_class', function(){
alert("double times called but still getting alert.. :)");
return false;
});
});
This registers for the click event on the #show_div object, but only triggers the event handler if the event originated on an object that matches the .a_class selector. Thus objects inside of #show_div can come and go and the event handler will stay in place.
See the jQuery doc for more info on .on(). This replaces .live() which is now deprecated, but used to be the preferred way of doing this.
Related
My page looks like:
<a class="myClass">1</a>
<a class="myClass">2</a>
<a class="myClass">3</a>
<a class"add_anchor">Add Anchor</a>
When the page is fully loaded, I bind a listener to a.myClass that executes a certain function f.
The click on Add Anchor adds via AJAX a new a.myClass to the list. So, to listen to all a.myClasss (the newly added and the initial ones), I should call the listener twice, the overall code looks like:
function listenToMyClassClick{
$('.myClass').click(function(e){
e.preventDefault();
f();
});
}
listenToMyClassClick();
$('.addAnchor').click(function(e){
$.ajax({
type: "POST",
url: url,
cache: false,
success: function(data){
listenToMyClassClick();
}
});
});
As a result, f is executed two times. How can I check with jQuery that a listener is already executing so that I don't execute it another time?
Thank you for your help.
Create a delegated event, like Sergiu suggests. Instead of binding a click event to an element that exists in a dynamic list of elements, bind a click event to the element's parent, which will still raise a click event even when you click one its children. This is called event bubbling. Here's a snippet of code showing how to do it using jQuery:
// Attach a delegated event handler
$( "#list" ).on( "click", "a", function( event ) {
f();
});
You bind the click event directly to "#List", being the parent and tell it to specifically listen for events from "a" elements, which is defined in the second parameter.
I have some JavaScript code that binds a click event to certain elements click events as seen below.
$(".alert-message .close").click(function(e) {
$(this).parent().fadeTo(200, 0, function() {
$(this).slideUp(300);
});
e.preventDefault();
});
This is called in the document ready event so normally it works fine until i fire an ajax request that updates parts of the page. This newly created part doesn't have the click event added and i end up having to recall this code for every ajax request, resulting in a lot of duplication.
I am looking for a way to write this JavaScript code once and it to be called in any scenario. Is there some event handler that will be called after any ajax or normal request?
Bootstrap dismissable alert message work after any ajax request so there must be a way.
Depending on which version of jQuery you're using you should use either delegate or on instead of directly binding click. Try something like
$(document).on('click', '.alert-message .close', function(e) {
$(this).parent().fadeTo(200, 0, function() {
$(this).slideUp(300);
});
e.preventDefault();
});
http://api.jquery.com/on/
Use event delegation and bind the event to a parent of .alert-message .close that doesn't get recreated:
$(document).on('click', ".alert-message .close", function(e) {
Instead of that, you can use on:
$(parentDivOrContainer).on('click', ".alert-message .close", function(){...});
parentDivOrContainer can be any container element that is not affected by ajax call.
I currently have a quite big issue here, which I've been trying to figure out since yesterday, but I really don't know what could be the problem here.
So I basically made a jQuery Ajax call in my code, something like this:
var ajaxCall = function(id, token)
{
var datap = { "id": id, "token": token };
$.ajax({
type: "POST",
url: "ajax.php",
data: datap,
dataType: "json",
beforeSend:function()
{
// loading image
},
success: function(data)
{
setting(data);
},
error: function()
{
alert('error');
}
});
As for the success function you can see the setting function, which looks like this:
var setting = function(data)
{
$('#testDiv').html(data.country);
}
Basically, this ajax call is made, once someone clicks on an item like:
$('#popup').on("click", function(){
ajaxCall();
});
So when someone clicks in the popup button, they will have a popup window open with the loaded Ajax content.
This is actually working flawlessly. My only problem happens, if I want to make another event within the Popup window (like: on click).
var load = function()
{
$('#testDiv #button').on("click", function(){
alert(1);
}
}
So if I place it in the above Ajax call function, it looks like the following:
$('#popup').on("click", function(){
ajaxCall();
load();
});
Problem:
When I click on the opoup button, to load the popup window, it loads the Ajax content. When I try to click on #button within the popup window at the first time, after loading the page, it gives me the alert box with 1.
However! If I just close the opoup window and click on it again, to load the popup, than click on the #button again, now I got the alert(1) 2 times! If I do the above again, I got it 3 times, 4 times, and so on.
So basically I've found out, that if I use the on Click function (within the popup window, after ajax has loaded), the contents within the on Click function got called more times, if I load the popup window more times (without refreshing the page - after refresh, everything strats from the beginning).
So the first popup load and click is normal, but the others seems to get called more times. I have also checked that the Ajax call is called multiple times, but it's NOT. I have placed an increment number inside each part of the code and I only got it incremented multiple times when the #button was clicked.
I know that this is quite hard to understand, but I would really need someone's help here, as I'm completely lost. Any solutions would be really appreciated.
I suggest you to do this:
Bind your click event outside of that function and put it in doc ready:
$('#testDiv #button').on("click", function(){
alert(1);
});
and do this in the #popup click event:
$('#popup').on("click", function(){
ajaxCall();
$('#testDiv #button').trigger('click');
});
You are binding the click event whenever load is called, to fire it once, you should bind it once. Either unbind it every time you call load before binding it or use on for event delegation. If you have to bind event with ids then you should directly bind as id are supposed to be using do not use descendant selector.
var load = function()
{
$('#testDiv #button').off("click");
$('#testDiv #button').on("click", function(){
alert(1);
}
}
I would recommend you to use event delegation for dynamically added elements
$(document).on("click", '#testDiv #button',function(){
alert(1);
});
Delegated events
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, jQuery docs.
Edit based on comments
As both elements are present in dom and not loaded dynamically you simply need click event. As ids are supposed to be unique do not use parent child selector
$('#testDiv').on("click", function(){
alert(1);
});
So i have some data on a page (a table) which based on some options elsewhere may get ajax reloaded from the server.
This table has buttons in it that can be clicked to make other things happen to the records in the table.
I notice that this ...
http://api.jquery.com/on/
... is the recommended approach for attaching simple event handlers to elements but that only attaches to elements that exist right now, and when I do my ajax load I lose the attached handlers.
So I started using this ... http://api.jquery.com/live/ ... and guess what, jquery team did their usual and deprecated it saying I should be using "on".
These functions behave very differently yet jquery docs say i should be using them interchangably so ...
Can someone explain the "on" equivelent of this and how I can get it to work with elements after an ajax call replacing the elements that hae previously been attached to ...
$("some selector").live('click', function (e) {
// some code code
e.preventDefault();
return false;
});
My understanding is that you would do something like ...
$("some selector").on('click', function (e) {
// some code code
e.preventDefault();
return false;
});
My guess is that I then have to re-run this code after performing my ajax call by putting this in to some sort of "initClicks" function and calling it both on page load and after the ajax call.
This seems to be a bit of a back step to me ... or have i missed something here?
Since the elements are added dynamically, you need to use event delegation to register the event handler
// New way (jQuery 1.7+) - .on(events, selector, handler)
$(document).on('click', 'some selector', function(event) {
// some code code
e.preventDefault();
return false;
});
Also, either use e.preventDefault() or return false, as:
return false = e.preventDefault() + e.stopPropagation()
So, there is no need to use both of them at same time.
When you use .on('click', function (e) {}) function, it works only for existing elements.
To handle click event on all selector elements, even for elements which will be added in future, you can use one of these functions:
$(document).on('click', "some selector", function (e) {
// some code code
e.preventDefault();
return false;
});
or:
$("body").delegate("a", "click", function () {
// your code goes here
});
For more information read article about Understanding Event Delegation
live() is not magic, it cannot see future elements, what it was doing is to attach a listener to the first root element of your page document and checks every bubbled event if it match your target selector, and when it find a match, it executes your function.
this is called event delegation
live() has been deprecated for good reasons, mainly the performance hit caused by using it.
then the jQUery team introduced the delegate() function which gave us a new way to achieve the exact result, but it has addressed the performance hit very cleverly by limiting the scope in which it will listen to bubbled events to the possible nearest parent of your now & future elements.
when they introduced the On() function, they gave you the ability to use it as normal event handler, or as a delegated handler for future elements.
so I believe they did a good job for this, giving us the flexibility to use it as we wish according to the specific scenario.
Code Examples:
using delegate():
$( "#TAGERT_ID" ).delegate( "a", "click", function() { // your code goes here}
using on() (for delegated events)
$( "#TAGERT_ID" ).on( "click", "a", function() { // your code goes here}
both ways are the same, and will handle future clicks on a which will be added in the future inside your TARGET_ID element.
TARGET_ID is an example for using ID for your selector, but you can use whatever selector according to your specific need.
The equivalent of said live is
$(document).on('click', "some selector", function (e) {
// some code code
e.preventDefault();
return false;
});
The on() is a single stop for all event handler formats, the model you used is the same as
$("some selector").click(function (e) {
// some code code
e.preventDefault();
return false;
});
which does work based event delegation.
You can never actually attach event listener to an element which does not exist in DOM yet. What live and on method do is attach listener on a parent which exists right now. live is nothing but an on attached on document itself.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Use variable outside the success function from an ajax/jquery call
I have this code and i don't understand why the accessing of the html elements is only working inside the ajax success function. the form is pulled in from ajax either way but i can only access it when i put all the selects for elements of it inside the ajax function.
The console.log('submit clicked'); gets not triggered this way, but inside the "ajax success" it does, i thaught everything pulled in with ajax is part of the DOM?
jQuery(document).ready(function($) {
console.log('ready');
$.ajax({
type: 'GET',
url: 'admin-ajax.php',
data: { action: 'get_arve_form' },
success: function(response){
// var table = $(response).find('table');
$(response).appendTo('body').hide();
console.log('response');
[ if i move the code below this ajax function in here its workign fine why not outside of it?]
}
});
// handles the click event of the submit button
$('#mygallery-submit').click(function(){
console.log('submit clicked');
[...]
});
Ajax is asynchronous so your elements don't exist until the ajax call finishes.
That being said, there are two ways to fix it:
1) Move your code into the success handler
2) Use event delegation to bind your event handler to all current and future elements.
An example of #2:
$(document).on('click', '#mygallery-submit', function(){
console.log('submit clicked');
});
Check out jQFundamentals to learn more about event delegation.
That's how ajax works.
When the external page is loaded, you have it available only on the success handler.
If you want it to be available elsewhere, you have to save it somehow, like you are doing.
But, the .click function gets executed before the ajax call returns successful. When you select $('#mygallery-submit'), it most likely is empty (you probably load this via ajax). So what you have to do if you want to declare the click function on document ready, rather than when the ajax page gets loaded, is to use the .on function:
$('body').on('click', '#mygallery-submit', function() {
console.log('submit clicked');
});
Because .click() is not a delegated handler. If the element you're trying to bind the event to doesn't exist at the time of execution, the event won't get bound. Try .on() instead.
$('body').on('click', '#mygallery-submit', function() {
// etc.
});