I'm having problems with updating elements that are not ready after an ajax request.
If I run my myFunction() function on page load like so:
$(function() {
myFunction();
}
I have no problems at all. But if I then use something like
$.ajax({
url: this.href,
dataType: "script",
complete: function(xhr, status) {
myFunction();
}
});
which returns $(".myElement").replaceWith("htmlHere"). The elements are simply not ready when the complete event fires. If I set a delay in there it works fine again.
Is there any other event that gets fired other than 'complete' when the DOM is ready?
Update:
Here's the actual code:
$(function() {
$("a.remote").live("click", function(e) {
$.ajax({
url: this.href,
dataType: "script",
success: function(xhr, status) {
myFunction();
}
});
e.preventDefault();
return false;
});
myFunction();
});
function myFunction() {
// Modify the dom in here
}
The missing ); was just a typo on my part.
Ive tried using success now instead of complete and it doesn't appear to make any difference.
I have set up a jsfiddle based on your code, and it seems to be working.
This is the current code:
$(function() {
$("a.remote").live("click", function(e) {
$.ajax({
url: this.href,
dataType: "script",
success: function(xhr, status) {
myFunction();
}
});
e.preventDefault();
return false;
});
});
function myFunction() {
$("span").replaceWith("<p>test</p>");
}
And it replaces span tag with a paragraph. Please check it and compare with your code. If it is the same, then your problem somewhere other than this function (maybe in myFunction?).
You can use $(document).ready(function() { ... }); to wrap up anything you want fired when the DOM has loaded. Your ajax request could be placed inside the document.ready if you want this to wait until the dom has loaded.
If you want to wait until the ajax has loaded its resource then you should use ajax.success rather than complete.
Just change complete: to success: in your $.ajax() call:
$.ajax({
url: this.href,
dataType: "script",
success: function(xhr, status) {
//make your DOM changes here
myFunction();
}
});
The success function will run once the AJAX request receives a successful response. So make your DOM changes within that function, and then run myFunction().
Edit
You seem to be trying to make the DOM changes using your myFunction(). But if you don't first insert the HTML received in the AJAX response into the DOM, then there will be nothing for myFunction() to modify. If this is indeed what's happening, then you have two options:
Insert the response HTML into the DOM, then call myFunction() (and all of this should happen within the success callback function).
Pass the AJAX response to myFunction() as an argument, so that myFunction() can handle the DOM insertion and then do the necessary modification.
There is a event that triggers after every ajax call. It is called ajaxComplete.
$( document ).ajaxComplete(function() {
$( ".log" ).text( "Triggered ajaxComplete handler." );
});
So you can
function Init(){
// stuff here
}
$(document).ready(function()
Init();
});
$(document).ajaxComplete(function()
Init();
});
You are missing the closing parenthesis of the document ready wrapper function.
$(function() {
myFunction();
});
Note the }); at the end.
$(function() {
myFunction();
}
should be
$(document).ready(function() {
myFunction();
});
Or incase you want the ajax to run on load. Do
$(document).ready(function() {
$.ajax();
});
Related
I have this click handler which has an ajax call to get back some data and I set a flag in before send and clears it in complete. The problem that I am facing is that. When I tired to click this twice, the process goes like the following. I wondered what would be a better way to solve this issue. I thought about doing $.active to find out the numbers of ajax calls that's active but that doesn't seem like that right way
1 remove initiated, set flag,
2 remove initiated, set flag.
1 remove response completed, reload and clear the flag.
2 remove response completed, reload (Since the flag was clear by the 1 response, it adds the default which I don't want ).
$(document).on('click', '#remove', function () {
$.ajax({
type: 'POST',
url: '/remove'
data: {
fruits: $(this).val()
},
beforeSend: function () {
$('#fruit-table').addClass('loading');
},
success: function (data) {
loadFruitTable(data);
},
complete: function () {
$('#fruit-table').removeClass('loading');
}
};
loadFruitTable = function (data) {
$('#fruit-table').html(data);
if ($('.processing').length) {
preLoadDefault();
}
};
Just an idea: disable the remove button on click and enable it in the complete-part?
You could use .ajaxStart to show the loading object and .ajaxComplete to handle the event of all data being loaded:
$( document ).ajaxStart(function() {
$( ".log" ).text( "Triggered ajaxStart handler." );
});
$( document ).ajaxComplete(function() {
$( ".log" ).text( "Triggered ajaxComplete handler." );
});
http://api.jquery.com/ajaxComplete/
$(document).on('click', '#remove', function () {
var $fruitTable = $('#fruit-table');
if ($fruitTable.hasClass('loading')) {
return;
}
$fruitTable.addClass('loading');
$.ajax({
type: 'POST',
url: '/remove'
data: {
fruits: $(this).val()
})
.then(loadFruitTable, function () {})
.then(reinitFruitTableStatus);
};
var reinitFruitTableStatus = function () {
$('#fruit-table').removeClass('loading');
};
loadFruitTable = function (data) {
$('#fruit-table').html(data);
if ($('.processing').length) {
preLoadDefault();
}
};
If the element #fruit-table is not dynamically created, you should store it once in a variable available in the whole code above.
Actually... Instead of adding a class, I added a count which increments in beforeSend and decrement in complete. So that way, i can always check if there is any process that's active.
I am making few ajax requests in my jQuery file. On success of these jQuery requests, I wrote few on click events which are not working.
This is my code
$(document).ready(function (){
$.ajax ({
type: "POST",
url: 'myServlet',
async: false,
success: function (response) {
id = parseInt(response);
setOutputEvents();
}
});
function setOutputEvents() {
for (var queryNumber = 0; queryNumber <= id; queryNumber++) {
$.ajax({
type: "POST",
url: 'myOtherServlet',
data: {queryNumber: queryNumber},
success: success,
async: false
});
var success = function (response) {
//some code here
generateTable();
}
}
}
function generateTable () {
//some code here
pagination();
}
function pagination(){
$(".class").click(function(event) {
alert();
});
}
$("#me").on("click", function(){
alert("me is triggered");
});
});
I understand making multiple ajax requests is a bad programming practice but what could be the reason for on click events not getting triggered?
These are the onclick events which are not working.
function pagination(){
$(".class").click(function(event) {
alert();
});
}
$("#me").on("click", function(){
alert("me is triggered");
});
I am using Google Chrome Version 39.0.2171.95 on Windows 7.
Please do let me know if any further information is necessary.
Since you use ajax to load even the initial content it seems, .class / #me html elements likely do not exist on initial page load of the DOM. As you didn't post html, i'm guessing this is the case.
Thus, you need to use a delegated event click handler to respond to it
so, you would change
$("#me").on("click", function(){
to
$(document).on("click", "#me", function(){
and so forth to link it to the parent element that does exist, the document itself.
This would work:
$(".class").on("click", function(){
alert("me is triggered");
});
function generateTable () {
//some code here
pagination();
}
function pagination(){
$(".class").trigger("click");
}
Some notes:
Event handler must be registered before triggering click.
Triggered click selector must match the class which has the click event registered.
Functions must be defined before the usage.
I have this ajax request:
$.ajax({
type: "POST",
dataType: "json",
data: dataString,
url: "app/changeQuantity",
success: function(data) {
$('#table').append('<tr><td><a id="uid">click</a></td></tr>');
});
as you can see it makes new row in #table. But this new objects made by ajax are not accessible from next functions. Result from ajax is not a regullar part of DOM, or what is the reason for this strange behavior?
$('#uid').on('click', function () {
alert('ok');
});
Use event delegation:
$(document).on('click','#uid', function () {
alert('ok');
});
Note that ajax calls are asynchronous. So whatever you do with the data you need to do it in a callback within the success function (that is the callback which is called when the ajax call returns successfully).
Jquery on doesn't work like that. Use have to give a parent which not loaded by ajax, and the specify ajax load element like this
$('#table').on('click','#uid' ,function () {
// what ever code you like
});
Is simple and complex at the same time. Simple to solve but complex if you are getting started with javascript...
Your event handler - onclick is being fired and bound to an object that doesnt yet exist.
So when you append the object to the #table, you need to set up your click handler as the object now exists.
So in your success part of the ajax return add the click handler event there.
success: function(data) {
$('#table').append('<tr><td><a id="uid">click</a></td></tr>');
$('#uid').on('click', function () {
alert('ok');
});
});
Or how about you make it dynamic and create a function to do it for you.
function bindClick(id) {
$('#' + id).click(function() {
//Do stuff here
console.log('I made it here' + id);
});
}
Then:
success: function(data) {
$('#table').append('<tr><td><a id="uid">click</a></td></tr>');
bindClick(uid);
});
}
This is a super contrived example but you get the idea you just need to make the rest of it dynamic as well. for example some name and counter generated id number: id1, id2, id3...
Try it like this, add this $('#uid').on('click', function () { into the success
$.ajax({
type: "POST",
dataType: "json",
data: dataString,
url: "app/changeQuantity",
success: function(data) {
$('#table').append('<tr><td><a id="uid">click</a></td></tr>');
$('#uid').on('click', function () {
alert('ok');
});
});
});
I want to check if element is already loaded.
HTML
<button>load</button>
JS
$(document).on('click','button',function () {
$.ajax({
url: 'additional.html',
context: document.body,
}).done(function(html) {
$('body').append(html);
});
});
//My incorrect suggestion
if ($('input').is(':visible')) {
alert('I see loaded element!');
}
I could move alert to .done() block, but I am not allowed to change it.
So what event listener should I use for if statement in order to show alert when element appears?
you can do something like this:
$('body').bind("loaded", function () {
alert('I see loaded element!');
});
$(document).on('click','button',function () {
$.ajax({
url: 'additional.html',
context: document.body,
}).done(function(html) {
$('body').append(html);
$('body').trigger("loaded");
});
});
Or you can set jquery ajax to be sync, because it async as default.
I want to execute a piece of javascript after the ajax response has been rendered. The javascript function is being generated dynamically during the ajax request, and is in the ajax response. 'complete' and 'success' events to not do the job. I inspected the ajax request in Firebug console and response hasn't been rendered when the complete callback executes.
Does not work:
function reloadForm() {
jQuery.ajax({
url: "<generate_form_url>",
type: "GET",
complete: custom_function_with_js_in_response()
});
};
ajaxComplete does the job, but it executes for all the ajax calls on the page. I want to avoid that. Is there a possible solution?
$('#link_form').ajaxComplete(function() {
custom_function_with_js_in_response();
});
you can also use $.ajax(..).done( do_things_here() );
$(document).ready(function() {
$('#obj').click(function() {
$.ajax({
url: "<url>"
}).done(function() {
do_something_here();
});
});
});
or is there another way
$(document).ready(function() {
$('#obj').click(function() {
$.ajax({
url: "<url>",
success: function(data){
do_something_with(data);
}
})
});
});
Please, utilize this engine for share your problem and try solutions. Its very efficient.
http://jsfiddle.net/qTDAv/7/ (PS: this contains a sample to try)
Hope to help
Checking (and deferring call if needed) and executing the existence of the callback function might work:
// undefine the function before the AJAX call
// replace myFunc with the name of the function to be executed on complete()
myFunc = null;
$.ajax({
...
complete: function() {
runCompleteCallback(myFunc);
},
...
});
function runCompleteCallback(_func) {
if(typeof _func == 'function') {
return _func();
}
setTimeout(function() {
runCompleteCallback(_func);
}, 100);
}
Can't help a lot without code. As an general example from JQuery ajax complete page
$('.log').ajaxComplete(function(e, xhr, settings) {
if (settings.url == 'ajax/test.html') {
$(this).text('Triggered ajaxComplete handler. The result is ' +
xhr.responseHTML);
}
});
In ajaxComplete, you can put decisions to filter the URL for which you want to write code.
Try to specify function name without () in ajax options:
function reloadForm() {
jQuery.ajax({
url: "<generate_form_url>",
type: "GET",
complete: custom_function_with_js_in_response
});
};