Callback failing if contains ajax - javascript

I'm trying to add a callback to a pre existing function in the jquery plugin nitelite https://github.com/premasagar/nitelite - The callback works fine http://jsfiddle.net/HPc4e/2/ - unless I have ajax in the callback?
Appropriate section of close function:
// Blah blah ...
else {
showFlash();
this.overlay.remove();
this.container
.empty()
.remove();
$(this).triggerHandler('close');
// Add callback
if (typeof callback == "function") {
callback();
}
}
return this;
Callback:
lb.close(undefined, 'click', function() {
$.ajax({
type: 'POST',
url: url,
data: {submit: $(this).val()},
dataType: 'json',
success: function(data) {
lightbox('Lightbox 2', '<p>Oh hi</p>', 'lightbox2');
}
});
});
Thanks

I suspect that your callback is throwing an exception.
What is the value of this supposed to be when it's invoked? Are you sure it's pointing at a jQuery compatible element that has a .val() method?

Related

jQuery: using $(this) inside of $.ajax success function

I'm making an $.ajax call, and the following code does not work as intended. The alert results in 'undefined'
$(document).ready( function {
$(".elem").on("click", function(e) {
e.preventDefault();
$.ajax( {
url: 'index.php',
data: {
'action': 'something'
},
success: function() {
alert($(this).data("foobar"));
}
});
});
)};
However, I was able to get it working by adding an alias to $(this) before entering the ajax function.
$(document).ready( function {
$(".elem").on("click", function(e) {
var old_this = $(this);
e.preventDefault();
$.ajax( {
url: 'index.php',
data: {
'action': 'something'
},
success: function() {
alert(old_this.data("foobar"));
}
});
});
)};
I can't assign unique IDs to the element being clicked, so accessing it via $("#id") isn't an option.
Is there a more standardized approach to accessing the $(this) that existed before entering the success function or does this way work just fine?
The way that you have it is just fine. By default this in jQuery ajax callbacks is the ajax settings object (you can set via $.ajaxSettings). $.ajax also has a context property that you can set:
$.ajax({
url: url,
data: data,
context: this,
success: success
});
Then you could use $(this) as expected, but personally I find the reassignment of this easier to understand. You may want to pick a better variable name than old_this, though.

Can't access object made by ajax call

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');
});
});
});

JQMIGRATE: Global events are undocumented and deprecated

We're trying to upgrade our jquery using jquery migrate.
We get the "JQMIGRATE: Global events are undocumented and deprecated" on this code (a wrapper for jquery.ajax):
ajaxPost: function (url, jsonData, successCallback, async) {
if (async == null) {
async = true;
}
var ajaxSettings = {
url: url,
type: 'POST',
async: async,
data: JSON.stringify(jsonData),
contentType: 'application/json; charset=UTF-8',
success: function (data, code, xht) {
successCallback(data, code, xht);
},
error: function (xht, errorType, exception) {
console.log(...);
}
};
$.ajax(ajaxSettings);
}
The "error" occurs for this line:
successCallback(data, code, xht);
We're not sure how to fix it?!
This is a piece of code from JQMIGRATE responsible for warning
// Turn global events into document-triggered events
jQuery.event.trigger = function( event, data, elem, onlyHandlers ){
if ( !elem && !rajaxEvent.test( event ) ) {
migrateWarn( "Global events are undocumented and deprecated" );
}
return eventTrigger.call( this, event, data, elem || document, onlyHandlers );
};
Looks like this warning is popping on trigger() calls in two cases:
1) no element is specified as trigger context
2) event is global ajax event
Global ajax event example:
$(document).bind("ajaxSend", function(){
$("#loading").show();
}).bind("ajaxComplete", function(){
$("#loading").hide();
});
But if you say you had disabled global events by setting jQuery.ajaxSetup({global: false}), then
problem could be caused by case 1, but i dont see any code releavant to it in the provided fragment.
Probably you need to check implementation of method successCallback for case 1.

Execute Javascript after ajax response has been rendered

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
});
};

JQuery $(this) not accessible after ajax POST?

Let's say I have a bunch of links that share a click event:
Click me
Click me
Click me
Click me
and in the $('.do-stuff').click function I execute a JQuery ajax POST request that updates the database with stuff and I get a successful response. After the ajax is completed, I simply want to change the value of the link text to be whatever I send back from the server...
$('.do-stuff').click(function () {
$.ajax({
type: "POST",
url: "MyWebService.asmx/DoSomething",
data: '{CurrentLinkText: "'+ $(this).text() +'"}',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) {
$(this).text(result.d);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus);
}
});
});
This invoked just fine and I verified that "result.d" is indeed the text from the server but the text is not changing. I think that the $(this) element is no longer accessible after the AJAX post? What can I do to work around this?
In general when you lose context like that, you can save a reference to the object. Like this:
function clickHandler() {
var that = this;
$.ajax( { url: '#',
success: function (result) {
$(that).text(result.d);
}
);
}
See here:
$(this) inside of AJAX success not working
You can set the context option:
This object will be made the context of all Ajax-related callbacks. By default, the context is an object that represents the ajax settings used in the call ($.ajaxSettings merged with the settings passed to $.ajax). (...)
Example:
$.ajax({
//...
context: this,
success: function(json) {
//...
}
});
or use $.proxy:
$.ajax({
//...
success: $.proxy(function(json) {
//...
}, this)
});
Try:
success: $.proxy(function(result) {
//...
}, this)
There are lots of ways to do this, as you can see from the answers here. Personally, I prefer to construct a function bound to the current value of this:
success: (function(target) {
return function(result) {
$(target).text(result.d);
}
})(this)
It's neat, clean, and $(this) will remain the same as it is in the outer context; i.e. it will be the element that raised the event.
jQuery('#youridvalue').html(result.d);
jQuery('.yourclassvalue').html(result.d);
Use it

Categories