diff --git a/src/rails.js b/src/rails.js index 309d74d6..79ef1a94 100644 --- a/src/rails.js +++ b/src/rails.js @@ -129,7 +129,11 @@ if (settings.dataType === undefined) { xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script); } - return rails.fire(element, 'ajax:beforeSend', [xhr, settings]); + if (rails.fire(element, 'ajax:beforeSend', [xhr, settings])) { + element.trigger('ajax:send', xhr); + } else { + return false; + } }, success: function(data, status, xhr) { element.trigger('ajax:success', [data, status, xhr]); @@ -154,9 +158,7 @@ // Only pass url to `ajax` options if not blank if (url) { options.url = url; } - var jqxhr = rails.ajax(options); - element.trigger('ajax:send', jqxhr); - return jqxhr; + return rails.ajax(options); } else { return false; } @@ -382,7 +384,7 @@ button.closest('form').data('ujs:submit-button', data); }); - $document.delegate(rails.formSubmitSelector, 'ajax:beforeSend.rails', function(event) { + $document.delegate(rails.formSubmitSelector, 'ajax:send.rails', function(event) { if (this == event.target) rails.disableFormElements($(this)); }); diff --git a/test/public/test/call-remote-callbacks.js b/test/public/test/call-remote-callbacks.js index b4c4c7c7..fa785be9 100644 --- a/test/public/test/call-remote-callbacks.js +++ b/test/public/test/call-remote-callbacks.js @@ -9,6 +9,7 @@ module('call-remote-callbacks', { teardown: function() { $(document).undelegate('form[data-remote]', 'ajax:beforeSend'); $(document).undelegate('form[data-remote]', 'ajax:before'); + $(document).undelegate('form[data-remote]', 'ajax:send'); $(document).undelegate('form[data-remote]', 'ajax:complete'); $(document).undelegate('form[data-remote]', 'ajax:success'); $(document).unbind('ajaxStop'); @@ -97,6 +98,9 @@ asyncTest('stopping the "ajax:beforeSend" event aborts the request', 1, function ok(true, 'aborting request in ajax:beforeSend'); return false; }); + form.unbind('ajax:send').bind('ajax:send', function() { + ok(false, 'ajax:send should not run'); + }); form.unbind('ajax:complete').bind('ajax:complete', function() { ok(false, 'ajax:complete should not run'); }); @@ -315,6 +319,9 @@ asyncTest('"ajax:beforeSend" can be observed and stopped with event delegation', }); submit(function(form) { + form.unbind('ajax:send').bind('ajax:send', function() { + ok(false, 'ajax:send should not run'); + }); form.unbind('ajax:complete').bind('ajax:complete', function() { ok(false, 'ajax:complete should not run'); }); @@ -324,12 +331,15 @@ asyncTest('"ajax:beforeSend" can be observed and stopped with event delegation', }); }); -asyncTest('"ajax:beforeSend", "ajax:success" and "ajax:complete" are triggered', 8, function() { +asyncTest('"ajax:beforeSend", "ajax:send", "ajax:success" and "ajax:complete" are triggered', 9, function() { submit(function(form) { form.bind('ajax:beforeSend', function(e, xhr, settings) { ok(xhr.setRequestHeader, 'first argument to "ajax:beforeSend" should be an XHR object'); equal(settings.url, '/echo', 'second argument to "ajax:beforeSend" should be a settings object'); }); + form.bind('ajax:send', function(e, xhr) { + ok(xhr.abort, 'first argument to "ajax:send" should be an XHR object'); + }); form.bind('ajax:success', function(e, data, status, xhr) { ok(data.REQUEST_METHOD, 'first argument to ajax:success should be a data object'); equal(status, 'success', 'second argument to ajax:success should be a status string'); @@ -342,10 +352,11 @@ asyncTest('"ajax:beforeSend", "ajax:success" and "ajax:complete" are triggered', }); }); -asyncTest('"ajax:beforeSend", "ajax:error" and "ajax:complete" are triggered on error', 6, function() { +asyncTest('"ajax:beforeSend", "ajax:send", "ajax:error" and "ajax:complete" are triggered on error', 7, function() { submit(function(form) { form.attr('action', '/error'); form.bind('ajax:beforeSend', function(arg) { ok(true, 'ajax:beforeSend') }); + form.bind('ajax:send', function(arg) { ok(true, 'ajax:send') }); form.bind('ajax:error', function(e, xhr, status, error) { ok(xhr.getResponseHeader, 'first argument to "ajax:error" should be an XHR object'); equal(status, 'error', 'second argument to ajax:error should be a status string'); @@ -358,11 +369,14 @@ asyncTest('"ajax:beforeSend", "ajax:error" and "ajax:complete" are triggered on }); // IF THIS TEST IS FAILING, TRY INCREASING THE TIMEOUT AT THE BOTTOM TO > 100 -asyncTest('binding to ajax callbacks via .delegate() triggers handlers properly', 3, function() { +asyncTest('binding to ajax callbacks via .delegate() triggers handlers properly', 4, function() { $(document) .delegate('form[data-remote]', 'ajax:beforeSend', function() { ok(true, 'ajax:beforeSend handler is triggered'); }) + .delegate('form[data-remote]', 'ajax:send', function() { + ok(true, 'ajax:send handler is triggered'); + }) .delegate('form[data-remote]', 'ajax:complete', function() { ok(true, 'ajax:complete handler is triggered'); }) diff --git a/test/public/test/data-disable.js b/test/public/test/data-disable.js index ec858787..b73b3035 100644 --- a/test/public/test/data-disable.js +++ b/test/public/test/data-disable.js @@ -159,7 +159,7 @@ asyncTest('a[data-remote][data-disable-with] disables and re-enables', 6, functi checkEnabledState(link, 'Click me'); link - .bind('ajax:beforeSend', function() { + .bind('ajax:send', function() { checkDisabledState(link, 'clicking...'); }) .bind('ajax:complete', function() { @@ -213,7 +213,7 @@ asyncTest('a[data-remote][data-disable-with] re-enables when `ajax:error` event checkEnabledState(link, 'Click me'); link - .bind('ajax:beforeSend', function() { + .bind('ajax:send', function() { checkDisabledState(link, 'clicking...'); }) .trigger('click');