From 7073f0227433e16ff69cf9e646efb5c3eb98df1b Mon Sep 17 00:00:00 2001 From: Steve Schwartz Date: Fri, 15 Apr 2011 14:51:49 -0400 Subject: [PATCH] Created test cases and solutions for correcting submit handler call order for browsers that don't support event bubbling. --- src/rails.js | 14 +++++++++ test/public/test/data-remote.js | 51 +++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/src/rails.js b/src/rails.js index 3b745f49..98b1e507 100644 --- a/src/rails.js +++ b/src/rails.js @@ -160,6 +160,16 @@ return false; } + function callFormSubmitBindings(form) { + var events = form.data('events'), continuePropagation = true; + if (events != undefined && events['submit'] != undefined) { + $.each(events['submit'], function(i, obj){ + if (typeof obj.handler === 'function') return continuePropagation = obj.handler(obj.data); + }) + } + return continuePropagation; + } + $('a[data-confirm], a[data-method], a[data-remote]').live('click.rails', function(e) { var link = $(this); if (!allowAction(link)) return stopEverything(e); @@ -185,6 +195,10 @@ return fire(form, 'ajax:aborted:file'); } + // If browser does not support submit bubbling, then this live-binding will be called before direct + // bindings. Therefore, we should directly call any direct bindings before remotely submitting form. + if (!$.support.submitBubbles && callFormSubmitBindings(form) == false) return stopEverything(e) + if (remote) { handleRemote(form); return false; diff --git a/test/public/test/data-remote.js b/test/public/test/data-remote.js index ac78e0ef..694143b9 100644 --- a/test/public/test/data-remote.js +++ b/test/public/test/data-remote.js @@ -37,3 +37,54 @@ asyncTest('submitting form with data-remote attribute', 4, function() { .bind('ajax:complete', function() { start() }) .trigger('submit'); }); + +asyncTest('form\'s submit bindings in browsers that don\'t support submit bubbling', 4, function() { + var form = $('form[data-remote]'), directBindingCalled = false; + + ok(!directBindingCalled, 'nothing is called'); + + form + .append($('')) + .bind('submit', function(){ + ok(true, 'binding handler is called'); + directBindingCalled = true; + }) + .bind('ajax:beforeSend', function(){ + ok(true, 'form being submitted via ajax'); + ok(directBindingCalled, 'binding handler already called'); + }) + .bind('ajax:complete', function(){ + start(); + }); + + if(!$.support.submitBubbles) { + // Must indrectly submit form via click to trigger jQuery's manual submit bubbling in IE + form.find('input[type=submit]') + .trigger('click'); + } else { + form.trigger('submit'); + } +}); + +asyncTest('returning false in form\'s submit bindings in non-submit-bubbling browsers', 1, function(){ + var form = $('form[data-remote]'); + + form + .append($('')) + .bind('submit', function(){ + ok(true, 'binding handler is called'); + return false; + }) + .bind('ajax:beforeSend', function(){ + ok(false, 'form should not be submitted'); + }); + + if (!$.support.submitBubbles) { + // Must indrectly submit form via click to trigger jQuery's manual submit bubbling in IE + form.find('input[type=submit]').trigger('click'); + } else { + form.trigger('submit'); + } + + setTimeout(function(){ start(); }, 13); +});