jquery.validate plugin accessing the form in ajax success callback - javascript

I'm confused on how to access the submitted form using the jQuery.validate plugin.
In the "success" option of the API options: http://jquery.malsup.com/form/#options-object
it says that the 4th parameter in the success function is the jquery wrapped form object but my attempts to access it with jQuery keep saying its undefined.
here's how the success function looks on their examples page: http://jquery.malsup.com/form/#ajaxSubmit
function showResponse(responseText, statusText, xhr, $form) {
var id=$form.attr('id');
console.log('id:'+id);
}
unfortunately, console.log says Uncaught TypeError: Cannot call method 'attr' of undefined.
any thoughts?
thanks,
tim

the variable cannot start with $ I suppose. Remove the $ and try again?
function showResponse(responseText, statusText, xhr, form) {
var id = form.attr('id');
console.log('id:'+id);
}
Or this might be another solution, if not a jQuery object:
function showResponse(responseText, statusText, xhr, form) {
var id = $(form).attr('id');
console.log('id:'+id);
}
Other possibilities
function showResponse(responseText, statusText, xhr, form) {
var id = $(form).attr('id');
console.log('id:'+id);
}
function showResponse(responseText, statusText, xhr, form) {
var id = form.attr('id');
console.log('id:'+id);
}
function showResponse(responseText, statusText, xhr, $form) { // Won't work
var id = form.attr('id');
console.log('id:'+id);
}
function showResponse(responseText, statusText, xhr, $form) { // High chance
var id = $($form).attr('id');
console.log('id:'+id);
}
Hope this helps! :)

I solved this problem by explicitly writing out the jQuery form selector every time and not trying to pass it as an object.
So rather than trying to pass around $form I used this:
$('#myForm').attr(...)
It is more verbose but at least it works!

Related

How to get HTTP-StatusCode in ajaxError?

I try to get the HTTP error code in the generic $(document).ajaxError() method. How can I read it out? I found this jQuery: How to get the HTTP status code from within the $.ajax.error method? but I don't manage to adapt it to my function.
JQuery version is 2.1.3.
$(document).ajaxError(function (jqXHR, textStatus, errorThrown) {
if (jqXHR.statusCode != "500") {
$("#global-error-wrapper").show();
$(".global-error-message-inner-text").text(trans("noconnectionerror"));
}
});
You are using ajaxError which seems to be a bit different than the ajax event error handler defined in the settings in the link you posted. For ajaxError(), it looks like the first parameter in the callback is the event and the second is the jqXHR object you want. Also it should be jqXHR.status and not statusCode Try the below
$(document).ajaxError(function (event, jqXHR, settings, thrownError) {
if (jqXHR.status != 500) {
$("#global-error-wrapper").show();
$(".global-error-message-inner-text").text(trans("noconnectionerror"));
}
});
The statusCode object on the jqXHR object in your ajaxError method refers to an object mapping that you can create when you build your ajax call. If you have an idea of what status codes to expect, you could build out this mapping and send it along with your ajax calls which could help you identify what status code was returned:
var statusCodeMapping = {
404: function() {
$notFound = true;
}
}
$.ajax({
statusCode: statusCodeMapping
});
You could then examine the $notFound object to see if that was the status code returned from your Ajax call:
$(document).ajaxError(function (jqXHR, textStatus, errorThrown) {
if ($notFound) {
$("#global-error-wrapper").show();
$(".global-error-message-inner-text").text(trans("noconnectionerror"));
}
});
The $notFound object should be global to your script

jQuery form plugin - no response, no errors

I'm using this plugin.
I've rewritten my code to work with the example:
function showRequest(formData, jqForm, options) {
var queryString = $.param(formData);
return true;
}
function showResponse(responseText, statusText, xhr, $form) {
$(".afterSend").removeClass("preloader");
$(".afterSend").empty().append(responseText);
}
$(function() {
$('form.wycena').bind("submit", function(e){
e.preventDefault();
if($('.formBox').hasClass('lightBox')) {
$(".afterSend").empty().addClass("preloader");
$("form.wycena").ajaxForm({
target: '.afterSend',
beforeSubmit: showRequest,
success: showResponse
});
}
else {
/* verify before sending */
toggleLightBox(true);
}
});
});
My code works, but ajaxForm and its callback functions (showRequest, showRespons) seems to do nothing at all. It is supposed to run the script defined in form's action field and show response in the .afterSend div, but I get nothing. Not even a single error in console.

Uncaught TypeError: Cannot read property 'toLowerCase' of undefined

I'm getting this error and it is originating from jquery framework.
When i try to load a select list on document ready i get this error.
I can't seem to find why i'm getting this error.
It works for the change event, but i'm getting the error when trying to execute the function manually.
Uncaught TypeError: Cannot read property 'toLowerCase' of undefined -> jquery-2.1.1.js:7300
Here is the code
$(document).ready(function() {
$("#CourseSelect").change(loadTeachers);
loadTeachers();
});
function loadTeachers() {
$.ajax({
type: 'GET',
url: '/Manage/getTeachers/' + $(this).val(),
dataType: 'json',
cache: false,
success:function(data) {
$('#TeacherSelect').get(0).options.length = 0;
$.each(data, function(i, teacher) {
var option = $('<option />');
option.val(teacher.employeeId);
option.text(teacher.name);
$('#TeacherSelect').append(option);
});
},
error: function() {
alert("Error while getting results");
}
});
}
When you call loadTeachers() on DOMReady the context of this will not be the #CourseSelect element.
You can fix this by triggering a change() event on the #CourseSelect element on load of the DOM:
$("#CourseSelect").change(loadTeachers).change(); // or .trigger('change');
Alternatively can use $.proxy to change the context the function runs under:
$("#CourseSelect").change(loadTeachers);
$.proxy(loadTeachers, $('#CourseSelect'))();
Or the vanilla JS equivalent of the above, bind():
$("#CourseSelect").change(loadTeachers);
loadTeachers.bind($('#CourseSelect'));
I had the same problem, I was trying to listen the change on some select and actually the problem was I was using the event instead of the event.target which is the select object.
INCORRECT :
$(document).on('change', $("select"), function(el) {
console.log($(el).val());
});
CORRECT :
$(document).on('change', $("select"), function(el) {
console.log($(el.target).val());
});
This Works For me !!!
Call a Function without Parameter
$("#CourseSelect").change(function(e1) {
loadTeachers();
});
Call a Function with Parameter
$("#CourseSelect").change(function(e1) {
loadTeachers($(e1.target).val());
});
It causes the error when you access $(this).val() when it called by change event this points to the invoker i.e. CourseSelect so it is working and and will get the value of CourseSelect. but when you manually call it this points to document. so either you will have to pass the CourseSelect object or access directly like $("#CourseSelect").val() instead of $(this).val().
It fails "when trying to execute the function manually" because you have a different 'this'. This will refer not to the thing you have in mind when invoking the method manually, but something else, probably the window object, or whatever context object you have when invoking manually.
your $(this).val() has no scope in your ajax call, because its not in change event function scope
May be you implemented that ajax call in your change event itself first, in that case it works fine.
but when u created a function and calling that funciton in change event, scope for $(this).val() is not valid.
simply get the value using id selector instead of
$(#CourseSelect).val()
whole code should be like this:
$(document).ready(function ()
{
$("#CourseSelect").change(loadTeachers);
loadTeachers();
});
function loadTeachers()
{
$.ajax({ type:'GET', url:'/Manage/getTeachers/' + $(#CourseSelect).val(), dataType:'json', cache:false,
success:function(data)
{
$('#TeacherSelect').get(0).options.length = 0;
$.each(data, function(i, teacher)
{
var option = $('<option />');
option.val(teacher.employeeId);
option.text(teacher.name);
$('#TeacherSelect').append(option);
});
}, error:function(){ alert("Error while getting results"); }
});
}

jQuery: How to apply a function to all elements including some which are loaded later via Ajax?

I have a simple jQuery function that resizes text areas, and I want it to apply to all text areas.
For the most part, this works great:
$(document.ready(function(){$("text_area").resizer('250px')});
However, because it is only called once when the document is ready, it fails to catch text areas that are later added onto the page using Ajax. I looked at the .live() function, which seems very close to what I'm looking. However, .live() must be bound to a specific event, whereas I just need this to fire once when they're done loading (the onLoad event doesn't work for individual elements).
The only thing I can get working is a really obtrusive inclusion of the JavaScript call directly into the Ajax. Is that the recommended way to be doing this?
Edit: Here is the rails source code for what it does for Ajax requests:
$('a[data-confirm], a[data-method], a[data-remote]').live('click.rails', function(e) {
var link = $(this);
if (!allowAction(link)) return false;
if (link.attr('data-remote') != undefined) {
handleRemote(link);
return false;
} else if (link.attr('data-method')) {
handleMethod(link);
return false;
}
});
// Submits "remote" forms and links with ajax
function handleRemote(element) {
var method, url, data,
dataType = element.attr('data-type') || ($.ajaxSettings && $.ajaxSettings.dataType);
if (element.is('form')) {
method = element.attr('method');
url = element.attr('action');
data = element.serializeArray();
// memoized value from clicked submit button
var button = element.data('ujs:submit-button');
if (button) {
data.push(button);
element.data('ujs:submit-button', null);
}
} else {
method = element.attr('data-method');
url = element.attr('href');
data = null;
}
$.ajax({
url: url, type: method || 'GET', data: data, dataType: dataType,
// stopping the "ajax:beforeSend" event will cancel the ajax request
beforeSend: function(xhr, settings) {
if (settings.dataType === undefined) {
xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script);
}
return fire(element, 'ajax:beforeSend', [xhr, settings]);
},
success: function(data, status, xhr) {
element.trigger('ajax:success', [data, status, xhr]);
},
complete: function(xhr, status) {
element.trigger('ajax:complete', [xhr, status]);
},
error: function(xhr, status, error) {
element.trigger('ajax:error', [xhr, status, error]);
}
});
}
So in my particular case, I've got a link, that has data-remote set to true, which points to a location that will return JavaScript instructing a form containing a text area to be appended to my document.
A simple way to do this would be to use ajaxComplete, which is fired after every AJAX request:
$(document).ajaxComplete(function() {
$('textarea:not(.processed)').resizer('250px');
});
That says "every time an AJAX request completes, find all textarea elements that don't have the processed class (which seems to be added by the resizer plugin -- terrible name for its purpose!) and call the resizer plugin on them.
You may be able to optimise this further if we could see your AJAX call.
Generally speaking, I would do it this way..
$.ajax({
type : "GET",
url : "/loadstuff",
success: function(responseHtml) {
var div = $("#containerDiv").append(responseHtml);
$("textarea", div).resizer("250px");
}
});
Wondering if you could use .load for this. For example:
$('text_area').load(function() {
$("text_area").resizer('250px');
});

Abort all jQuery AJAX requests globally

Is there a way to abort all Ajax requests globally without a handle on the request object?
The reason I ask is that we have quite a complex application where we are running a number of different Ajax requests in the background by using setTimeOut(). If the user clicks a certain button we need to halt all ongoing requests.
You need to call abort() method:
var request = $.ajax({
type: 'POST',
url: 'someurl',
success: function(result){..........}
});
After that you can abort the request:
request.abort();
This way you need to create a variable for your ajax request and then you can use the abort method on that to abort the request any time.
Also have a look at:
Aborting Ajax
You cannot abort all active Ajax requests if you are not tracking the handles to them.
But if you are tracking it, then yes you can do it, by looping through your handlers and calling .abort() on each one.
You can use this script:
// $.xhrPool and $.ajaxSetup are the solution
$.xhrPool = [];
$.xhrPool.abortAll = function() {
$(this).each(function(idx, jqXHR) {
jqXHR.abort();
});
$.xhrPool = [];
};
$.ajaxSetup({
beforeSend: function(jqXHR) {
$.xhrPool.push(jqXHR);
},
complete: function(jqXHR) {
var index = $.xhrPool.indexOf(jqXHR);
if (index > -1) {
$.xhrPool.splice(index, 1);
}
}
});
Check the result at http://jsfiddle.net/s4pbn/3/.
This answer to a related question is what worked for me:
https://stackoverflow.com/a/10701856/5114
Note the first line where the #grr says: "Using ajaxSetup is not correct"
You can adapt his answer to add your own function to window if you want to call it yourself rather than use window.onbeforeunload as they do.
// Most of this is copied from #grr verbatim:
(function($) {
var xhrPool = [];
$(document).ajaxSend(function(e, jqXHR, options){
xhrPool.push(jqXHR);
});
$(document).ajaxComplete(function(e, jqXHR, options) {
xhrPool = $.grep(xhrPool, function(x){return x!=jqXHR});
});
// I changed the name of the abort function here:
window.abortAllMyAjaxRequests = function() {
$.each(xhrPool, function(idx, jqXHR) {
jqXHR.abort();
});
};
})(jQuery);
Then you can call window.abortAllMyAjaxRequests(); to abort them all. Make sure you add a .fail(jqXHRFailCallback) to your ajax requests. The callback will get 'abort' as textStatus so you know what happened:
function jqXHRFailCallback(jqXHR, textStatus){
// textStatus === 'abort'
}

Categories

Resources