I have an ajax function for saving a forms data. I want it to remain asynchronous because the users can hit save any time. However, I have another function that converts the form to a PDF and I want it to run the save function before creating the PDF (in case the users have added more data). Is there a way to make $('input.submit') wait for save to finish before opening the pdf? Below is the jQuery I am using:
$("button#save").on('click', function (){
$.ajax({
type: 'POST',
url: '<?php echo matry::base_to('utilities/crm/field_day_save');?>',
data: $("form#trip_form").serialize(),
dataType: 'json',
success: function (data)
{
$("#alerts").html(data.alert);
$("#form_id").val(data.id);
}
});
});
$("input.submit").on('click', function(event){
event.preventDefault();
$("button#save").trigger('click');
window.open('<?php echo matry::base_to('custom_worddocs/field_day');?>' + '&fd_id=' + $("#form_id").val());
});
In short, I want $('button#save').click() to remain asynchronous, but I want $(input.submit) to wait for button save to complete before opening new window.
jQuery's ajax function returns a jqXHR object which, among other things, behaves like a deferred.
By only calling window.open from within the then function, it'll wait for the AJAX to complete:
$("button#save").on('click', function () {
var jqXHR = $.ajax({ /* your config... */ });
$("input.submit").one('click', function(event) {
event.preventDefault();
$("button#save").trigger('click');
jqXHR.then(function () {
window.open('<?php echo matry::base_to('custom_worddocs/field_day');?>' + '&fd_id=' + $("#form_id").val());
});
});
}
Have your click handler return a promise object, then use triggerHandler() to trigger the click event and get it's return value.
$("button#save").on('click', function (){
return $.ajax({
...
and
...
$("button#save").triggerHandler('click').done(function(){
window.open(...);
});
...
Proof of concept: http://jsfiddle.net/SRzcy/
Related
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');
});
});
});
Hello guys here's my code:
var ajax={
chiamata:function(target,url,opzioni){
if (!tools.array_key_exists('caricamento',opzioni)){
opzioni['caricamento']=1;
}
var dati=url.split('?');
$.ajax({
type: opzioni['type'],
url: url,
contentType:"application/x-www-form-urlencoded; charset=UTF-8",
data: dati[1],
dataType: "html",
success: function(msg){
if (opzioni['caricamento']!=0){
ajax.printLoading();
}
$(target).html(msg);
},
error: function(){
alert("Chiamata fallita!");
}
})
},
printLoading:function(){
var body="#colonnaDX";
$(body).ajaxStart(function(){
$(body).append('<div id="loading"><img src="graphic/IMAGE/spinner.gif"/>Loading...</div>');
})
.ajaxStop(function(){
$('#loading').remove();
});
}
},
//Recursive function
var object={
checkAzione:function(target,url,opzioni,interval){
if (!interval)
interval=60000;
ajax.chiamata(target,url,opzioni);
setTimeout(function() {
this.checkAzione(target,url,opzioni,interval);
}, interval);
}
}
$(document).ready(function(){
object.checkAzione(
'#colonnaDX',
'someactions.php',{
'caricamento':0
},
10000
);
})
I'll try to explain the problem as better as i can, When the document is ready, the function "checkAzione" starts and it makes some stuff like DB calls etc, this kinds of ajax calls don't need any visual loading like spinner etc so in the array "opzioni" i set a flag 'caricamento':0 (same of 'loading':0) just check my ajax object to see what i mean, it works until i make some ajax calls that using 'caricamento':1, from that moment every ajax calls in my recursive function makes the "printLoading"... Any tips????
ajaxStart and ajaxStop are global, you add them to the body. You probably shouldn't use ajaxStart/Stop in this case, just add the functionality to your ajax listeners (success and error).
I have a nifty little piece of Ajax code that loads in PHP.
http://www.moneyworrier.com/client-stories/
What happens is that when you click on a menu item on the left-hand navigation, it reloads a Div with content appropriate.
What it does however is loop through previous requests, which is bothersome (Click on any left hand item 3x and you will see what I mean). I think I need to find a function that does the equivalent of exit; and clears any post data.
My call in code is:
Video
And my JS looks like:
$(document).ready(function () {
$('a.media').click(function () {
var usr = $(this).attr('rel');
$("#displaystories").html('Retrieving..');
$.ajax({
type: "POST",
url: "/client-stories/media.php",
data: "showcode=" + usr,
success: function (msg) {
$("#displaystories").ajaxComplete(function (event, request, settings) {
$(this).html(msg);
});
}
});
});
});
You're binding a new listener to ajaxComplete on every click. Your success callback should just be:
success: function(msg) {
$("#displaystories").html(msg);
}
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
});
};