From 1c84b339d3da8157c4ba43def0923cefa592e341 Mon Sep 17 00:00:00 2001 From: Lucas Mazza Date: Fri, 1 Nov 2013 18:35:15 -0200 Subject: [PATCH 1/4] Add support for the `data-disable` attribute. This gives the same behavior as the `data-disable-with` attribute, but instead of using a replacement String from the `data-disable-with` attribute the disabled state will use the origin text/value of the element. --- src/rails.js | 23 ++- test/public/test/data-disable-with.js | 248 ++++++++++++++++++++++++++ test/public/test/data-disable.js | 136 ++++++-------- test/public/test/settings.js | 18 ++ test/views/index.erb | 2 +- 5 files changed, 340 insertions(+), 87 deletions(-) create mode 100644 test/public/test/data-disable-with.js diff --git a/src/rails.js b/src/rails.js index 309d74d6..0c4fa64e 100644 --- a/src/rails.js +++ b/src/rails.js @@ -22,7 +22,7 @@ $.rails = rails = { // Link elements bound by jquery-ujs - linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote], a[data-disable-with]', + linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote], a[data-disable-with], a[data-disable]', // Button elements bound by jquery-ujs buttonClickSelector: 'button[data-remote]', @@ -37,10 +37,10 @@ formInputClickSelector: 'form input[type=submit], form input[type=image], form button[type=submit], form button:not([type])', // Form input elements disabled during form submission - disableSelector: 'input[data-disable-with], button[data-disable-with], textarea[data-disable-with]', + disableSelector: 'input[data-disable-with], button[data-disable-with], textarea[data-disable-with], input[data-disable], button[data-disable], textarea[data-disable]', // Form input elements re-enabled after form submission - enableSelector: 'input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled', + enableSelector: 'input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled, input[data-disable]:disabled, button[data-disable]:disabled, textarea[data-disable]:disabled', // Form required input elements requiredInputSelector: 'input[name][required]:not([disabled]),textarea[name][required]:not([disabled])', @@ -49,7 +49,7 @@ fileInputSelector: 'input[type=file]', // Link onClick disable selector with possible reenable after remote submission - linkDisableSelector: 'a[data-disable-with]', + linkDisableSelector: 'a[data-disable-with], a[data-disable]', // Make sure that every Ajax request sends the CSRF token CSRFProtection: function(xhr) { @@ -190,9 +190,13 @@ */ disableFormElements: function(form) { form.find(rails.disableSelector).each(function() { - var element = $(this), method = element.is('button') ? 'html' : 'val'; - element.data('ujs:enable-with', element[method]()); - element[method](element.data('disable-with')); + var element, method, enabledState; + element = $(this); + method = element.is('button') ? 'html' : 'val'; + enabledState = element[method](); + + element.data('ujs:enable-with', enabledState); + element[method](element.data('disable-with') || enabledState); element.prop('disabled', true); }); }, @@ -269,8 +273,9 @@ // replace element's html with the 'data-disable-with' after storing original html // and prevent clicking on it disableElement: function(element) { - element.data('ujs:enable-with', element.html()); // store enabled state - element.html(element.data('disable-with')); // set to disabled state + var enabledState = element.html(); + element.data('ujs:enable-with', enabledState); // store enabled state + element.html(element.data('disable-with') || enabledState); // set to disabled state element.bind('click.railsDisable', function(e) { // prevent further clicking return rails.stopEverything(e); }); diff --git a/test/public/test/data-disable-with.js b/test/public/test/data-disable-with.js new file mode 100644 index 00000000..80a183af --- /dev/null +++ b/test/public/test/data-disable-with.js @@ -0,0 +1,248 @@ +module('data-disable-with', { + setup: function() { + $('#qunit-fixture').append($('
', { + action: '/echo', + 'data-remote': 'true', + method: 'post' + })) + .find('form') + .append($('')); + + $('#qunit-fixture').append($('', { + action: '/echo', + method: 'post' + })) + .find('form:last') + // WEEIRDD: the form won't submit to an iframe if the button is name="submit" (??!) + .append($('')); + + $('#qunit-fixture').append($('', { + text: 'Click me', + href: '/echo', + 'data-disable-with': 'clicking...' + })); + }, + teardown: function() { + $(document).unbind('iframe:loaded'); + } +}); + + +asyncTest('form input field with "data-disable-with" attribute', 7, function() { + var form = $('form[data-remote]'), input = form.find('input[type=text]'); + + App.checkEnabledState(input, 'john'); + + form.bind('ajax:success', function(e, data) { + setTimeout(function() { + App.checkEnabledState(input, 'john'); + equal(data.params.user_name, 'john'); + start(); + }, 13) + }) + form.trigger('submit'); + + App.checkDisabledState(input, 'processing ...'); +}); + +asyncTest('form button with "data-disable-with" attribute', 6, function() { + var form = $('form[data-remote]'), button = $(''); + form.append(button); + + App.checkEnabledState(button, 'Submit'); + + form.bind('ajax:success', function(e, data) { + setTimeout(function() { + App.checkEnabledState(button, 'Submit'); + start(); + }, 13) + }) + form.trigger('submit'); + + App.checkDisabledState(button, 'submitting ...'); +}); + +asyncTest('form input[type=submit][data-disable-with] disables', 6, function(){ + var form = $('form:not([data-remote])'), input = form.find('input[type=submit]'); + + App.checkEnabledState(input, 'Submit'); + + // WEEIRDD: attaching this handler makes the test work in IE7 + $(document).bind('iframe:loading', function(e, form) {}); + + $(document).bind('iframe:loaded', function(e, data) { + setTimeout(function() { + App.checkDisabledState(input, 'submitting ...'); + start(); + }, 30); + }); + form.trigger('submit'); + + setTimeout(function() { + App.checkDisabledState(input, 'submitting ...'); + }, 30); +}); + +asyncTest('form[data-remote] input[type=submit][data-disable-with] is replaced in ajax callback', 2, function(){ + var form = $('form:not([data-remote])').attr('data-remote', 'true'), origFormContents = form.html(); + + form.bind('ajax:success', function(){ + form.html(origFormContents); + + setTimeout(function(){ + var input = form.find('input[type=submit]'); + App.checkEnabledState(input, 'Submit'); + start(); + }, 30); + }).trigger('submit'); +}); + +asyncTest('form[data-remote] input[data-disable-with] is replaced with disabled field in ajax callback', 2, function(){ + var form = $('form:not([data-remote])').attr('data-remote', 'true'), input = form.find('input[type=submit]'), + newDisabledInput = input.clone().attr('disabled', 'disabled'); + + form.bind('ajax:success', function(){ + input.replaceWith(newDisabledInput); + + setTimeout(function(){ + App.checkEnabledState(newDisabledInput, 'Submit'); + start(); + }, 30); + }).trigger('submit'); +}); + +asyncTest('form[data-remote] textarea[data-disable-with] attribute', 3, function() { + var form = $('form[data-remote]'), + textarea = $('').appendTo(form); + + form.bind('ajax:success', function(e, data) { + setTimeout(function() { + equal(data.params.user_bio, 'born, lived, died.'); + start(); + }, 13) + }) + form.trigger('submit'); + + App.checkDisabledState(textarea, 'processing ...'); +}); + +asyncTest('a[data-disable-with] disables', 4, function() { + var link = $('a[data-disable-with]'); + + App.checkEnabledState(link, 'Click me'); + + link.trigger('click'); + App.checkDisabledState(link, 'clicking...'); + start(); +}); + +asyncTest('a[data-remote][data-disable-with] disables and re-enables', 6, function() { + var link = $('a[data-disable-with]').attr('data-remote', true); + + App.checkEnabledState(link, 'Click me'); + + link + .bind('ajax:beforeSend', function() { + App.checkDisabledState(link, 'clicking...'); + }) + .bind('ajax:complete', function() { + setTimeout( function() { + App.checkEnabledState(link, 'Click me'); + start(); + }, 15); + }) + .trigger('click'); +}); + +asyncTest('a[data-remote][data-disable-with] re-enables when `ajax:before` event is cancelled', 6, function() { + var link = $('a[data-disable-with]').attr('data-remote', true); + + App.checkEnabledState(link, 'Click me'); + + link + .bind('ajax:before', function() { + App.checkDisabledState(link, 'clicking...'); + return false; + }) + .trigger('click'); + + setTimeout(function() { + App.checkEnabledState(link, 'Click me'); + start(); + }, 30); +}); + +asyncTest('a[data-remote][data-disable-with] re-enables when `ajax:beforeSend` event is cancelled', 6, function() { + var link = $('a[data-disable-with]').attr('data-remote', true); + + App.checkEnabledState(link, 'Click me'); + + link + .bind('ajax:beforeSend', function() { + App.checkDisabledState(link, 'clicking...'); + return false; + }) + .trigger('click'); + + setTimeout(function() { + App.checkEnabledState(link, 'Click me'); + start(); + }, 30); +}); + +asyncTest('a[data-remote][data-disable-with] re-enables when `ajax:error` event is triggered', 6, function() { + var link = $('a[data-disable-with]').attr('data-remote', true).attr('href', '/error'); + + App.checkEnabledState(link, 'Click me'); + + link + .bind('ajax:beforeSend', function() { + App.checkDisabledState(link, 'clicking...'); + }) + .trigger('click'); + + setTimeout(function() { + App.checkEnabledState(link, 'Click me'); + start(); + }, 30); +}); + +asyncTest('form[data-remote] input|button|textarea[data-disable-with] does not disable when `ajax:beforeSend` event is cancelled', 8, function() { + var form = $('form[data-remote]'), + input = form.find('input:text'), + button = $('').appendTo(form), + textarea = $('').appendTo(form), + submit = $('').appendTo(form); + + form + .bind('ajax:beforeSend', function() { + return false; + }) + .trigger('submit'); + + App.checkEnabledState(input, 'john'); + App.checkEnabledState(button, 'Submit'); + App.checkEnabledState(textarea, 'born, lived, died.'); + App.checkEnabledState(submit, 'Submit'); + + start(); + +}); + +asyncTest('ctrl-clicking on a link does not disables the link', 6, function() { + var link = $('a[data-disable-with]'), e; + e = $.Event('click'); + e.metaKey = true; + + App.checkEnabledState(link, 'Click me'); + + link.trigger(e); + App.checkEnabledState(link, 'Click me'); + + e = $.Event('click'); + e.ctrlKey = true; + + link.trigger(e); + App.checkEnabledState(link, 'Click me'); + start(); +}); diff --git a/test/public/test/data-disable.js b/test/public/test/data-disable.js index ec858787..181e42a1 100644 --- a/test/public/test/data-disable.js +++ b/test/public/test/data-disable.js @@ -6,7 +6,7 @@ module('data-disable', { method: 'post' })) .find('form') - .append($('')); + .append($('')); $('#qunit-fixture').append($('', { action: '/echo', @@ -14,12 +14,12 @@ module('data-disable', { })) .find('form:last') // WEEIRDD: the form won't submit to an iframe if the button is name="submit" (??!) - .append($('')); + .append($('')); $('#qunit-fixture').append($('', { text: 'Click me', href: '/echo', - 'data-disable-with': 'clicking...' + 'data-disable': 'true' })); }, teardown: function() { @@ -27,80 +27,62 @@ module('data-disable', { } }); -function getVal(el) { - return el.is('input,textarea,select') ? el.val() : el.text(); -} - -function disabled(el) { - return el.is('input,textarea,select,button') ? el.is(':disabled') : el.data('ujs:enable-with'); -} - -function checkEnabledState(el, text) { - ok(!disabled(el), el.get(0).tagName + ' should not be disabled'); - equal(getVal(el), text, el.get(0).tagName + ' text should be original value'); -} - -function checkDisabledState(el, text) { - ok(disabled(el), el.get(0).tagName + ' should be disabled'); - equal(getVal(el), text, el.get(0).tagName + ' text should be disabled value'); -} - -asyncTest('form input field with "data-disable-with" attribute', 7, function() { +asyncTest('form input field with "data-disable" attribute', 7, function() { var form = $('form[data-remote]'), input = form.find('input[type=text]'); - checkEnabledState(input, 'john'); + App.checkEnabledState(input, 'john'); form.bind('ajax:success', function(e, data) { setTimeout(function() { - checkEnabledState(input, 'john'); + App.checkEnabledState(input, 'john'); equal(data.params.user_name, 'john'); start(); }, 13) }) form.trigger('submit'); - checkDisabledState(input, 'processing ...'); + App.checkDisabledState(input, 'john'); }); -asyncTest('form button with "data-disable-with" attribute', 6, function() { - var form = $('form[data-remote]'), button = $(''); +asyncTest('form button with "data-disable" attribute', 6, function() { + var form = $('form[data-remote]'), button = $(''); form.append(button); - checkEnabledState(button, 'Submit'); + App.checkEnabledState(button, 'Submit'); form.bind('ajax:success', function(e, data) { setTimeout(function() { - checkEnabledState(button, 'Submit'); + App.checkEnabledState(button, 'Submit'); start(); }, 13) }) form.trigger('submit'); - checkDisabledState(button, 'submitting ...'); + App.checkDisabledState(button, 'Submit'); }); -asyncTest('form input[type=submit][data-disable-with] disables', 6, function(){ +asyncTest('form input[type=submit][data-disable] disables', 6, function(){ var form = $('form:not([data-remote])'), input = form.find('input[type=submit]'); - checkEnabledState(input, 'Submit'); + App.checkEnabledState(input, 'Submit'); // WEEIRDD: attaching this handler makes the test work in IE7 $(document).bind('iframe:loading', function(e, form) {}); $(document).bind('iframe:loaded', function(e, data) { setTimeout(function() { - checkDisabledState(input, 'submitting ...'); + App.checkDisabledState(input, 'Submit'); start(); }, 30); }); form.trigger('submit'); setTimeout(function() { - checkDisabledState(input, 'submitting ...'); + App.checkDisabledState(input, 'Submit'); }, 30); }); -asyncTest('form[data-remote] input[type=submit][data-disable-with] is replaced in ajax callback', 2, function(){ +asyncTest('form[data-remote] input[type=submit][data-disable] is replaced in ajax callback', 2, function(){ var form = $('form:not([data-remote])').attr('data-remote', 'true'), origFormContents = form.html(); form.bind('ajax:success', function(){ @@ -108,13 +90,13 @@ asyncTest('form[data-remote] input[type=submit][data-disable-with] is replaced i setTimeout(function(){ var input = form.find('input[type=submit]'); - checkEnabledState(input, 'Submit'); + App.checkEnabledState(input, 'Submit'); start(); }, 30); }).trigger('submit'); }); -asyncTest('form[data-remote] input[data-disable-with] is replaced with disabled field in ajax callback', 2, function(){ +asyncTest('form[data-remote] input[data-disable] is replaced with disabled field in ajax callback', 2, function(){ var form = $('form:not([data-remote])').attr('data-remote', 'true'), input = form.find('input[type=submit]'), newDisabledInput = input.clone().attr('disabled', 'disabled'); @@ -122,15 +104,15 @@ asyncTest('form[data-remote] input[data-disable-with] is replaced with disabled input.replaceWith(newDisabledInput); setTimeout(function(){ - checkEnabledState(newDisabledInput, 'Submit'); + App.checkEnabledState(newDisabledInput, 'Submit'); start(); }, 30); }).trigger('submit'); }); -asyncTest('form[data-remote] textarea[data-disable-with] attribute', 3, function() { +asyncTest('form[data-remote] textarea[data-disable] attribute', 3, function() { var form = $('form[data-remote]'), - textarea = $('').appendTo(form); + textarea = $('').appendTo(form); form.bind('ajax:success', function(e, data) { setTimeout(function() { @@ -140,96 +122,96 @@ asyncTest('form[data-remote] textarea[data-disable-with] attribute', 3, function }) form.trigger('submit'); - checkDisabledState(textarea, 'processing ...'); + App.checkDisabledState(textarea, 'born, lived, died.'); }); -asyncTest('a[data-disable-with] disables', 4, function() { - var link = $('a[data-disable-with]'); +asyncTest('a[data-disable] disables', 4, function() { + var link = $('a[data-disable]'); - checkEnabledState(link, 'Click me'); + App.checkEnabledState(link, 'Click me'); link.trigger('click'); - checkDisabledState(link, 'clicking...'); + App.checkDisabledState(link, 'Click me'); start(); }); -asyncTest('a[data-remote][data-disable-with] disables and re-enables', 6, function() { - var link = $('a[data-disable-with]').attr('data-remote', true); +asyncTest('a[data-remote][data-disable] disables and re-enables', 6, function() { + var link = $('a[data-disable]').attr('data-remote', true); - checkEnabledState(link, 'Click me'); + App.checkEnabledState(link, 'Click me'); link .bind('ajax:beforeSend', function() { - checkDisabledState(link, 'clicking...'); + App.checkDisabledState(link, 'Click me'); }) .bind('ajax:complete', function() { setTimeout( function() { - checkEnabledState(link, 'Click me'); + App.checkEnabledState(link, 'Click me'); start(); }, 15); }) .trigger('click'); }); -asyncTest('a[data-remote][data-disable-with] re-enables when `ajax:before` event is cancelled', 6, function() { - var link = $('a[data-disable-with]').attr('data-remote', true); +asyncTest('a[data-remote][data-disable] re-enables when `ajax:before` event is cancelled', 6, function() { + var link = $('a[data-disable]').attr('data-remote', true); - checkEnabledState(link, 'Click me'); + App.checkEnabledState(link, 'Click me'); link .bind('ajax:before', function() { - checkDisabledState(link, 'clicking...'); + App.checkDisabledState(link, 'Click me'); return false; }) .trigger('click'); setTimeout(function() { - checkEnabledState(link, 'Click me'); + App.checkEnabledState(link, 'Click me'); start(); }, 30); }); -asyncTest('a[data-remote][data-disable-with] re-enables when `ajax:beforeSend` event is cancelled', 6, function() { - var link = $('a[data-disable-with]').attr('data-remote', true); +asyncTest('a[data-remote][data-disable] re-enables when `ajax:beforeSend` event is cancelled', 6, function() { + var link = $('a[data-disable]').attr('data-remote', true); - checkEnabledState(link, 'Click me'); + App.checkEnabledState(link, 'Click me'); link .bind('ajax:beforeSend', function() { - checkDisabledState(link, 'clicking...'); + App.checkDisabledState(link, 'Click me'); return false; }) .trigger('click'); setTimeout(function() { - checkEnabledState(link, 'Click me'); + App.checkEnabledState(link, 'Click me'); start(); }, 30); }); -asyncTest('a[data-remote][data-disable-with] re-enables when `ajax:error` event is triggered', 6, function() { - var link = $('a[data-disable-with]').attr('data-remote', true).attr('href', '/error'); +asyncTest('a[data-remote][data-disable] re-enables when `ajax:error` event is triggered', 6, function() { + var link = $('a[data-disable]').attr('data-remote', true).attr('href', '/error'); - checkEnabledState(link, 'Click me'); + App.checkEnabledState(link, 'Click me'); link .bind('ajax:beforeSend', function() { - checkDisabledState(link, 'clicking...'); + App.checkDisabledState(link, 'Click me'); }) .trigger('click'); setTimeout(function() { - checkEnabledState(link, 'Click me'); + App.checkEnabledState(link, 'Click me'); start(); }, 30); }); -asyncTest('form[data-remote] input|button|textarea[data-disable-with] does not disable when `ajax:beforeSend` event is cancelled', 8, function() { +asyncTest('form[data-remote] input|button|textarea[data-disable] does not disable when `ajax:beforeSend` event is cancelled', 8, function() { var form = $('form[data-remote]'), input = form.find('input:text'), - button = $('').appendTo(form), - textarea = $('').appendTo(form), - submit = $('').appendTo(form); + button = $('').appendTo(form), + textarea = $('').appendTo(form), + submit = $('').appendTo(form); form .bind('ajax:beforeSend', function() { @@ -237,29 +219,29 @@ asyncTest('form[data-remote] input|button|textarea[data-disable-with] does not d }) .trigger('submit'); - checkEnabledState(input, 'john'); - checkEnabledState(button, 'Submit'); - checkEnabledState(textarea, 'born, lived, died.'); - checkEnabledState(submit, 'Submit'); + App.checkEnabledState(input, 'john'); + App.checkEnabledState(button, 'Submit'); + App.checkEnabledState(textarea, 'born, lived, died.'); + App.checkEnabledState(submit, 'Submit'); start(); }); asyncTest('ctrl-clicking on a link does not disables the link', 6, function() { - var link = $('a[data-disable-with]'), e; + var link = $('a[data-disable]'), e; e = $.Event('click'); e.metaKey = true; - checkEnabledState(link, 'Click me'); + App.checkEnabledState(link, 'Click me'); link.trigger(e); - checkEnabledState(link, 'Click me'); + App.checkEnabledState(link, 'Click me'); e = $.Event('click'); e.ctrlKey = true; link.trigger(e); - checkEnabledState(link, 'Click me'); + App.checkEnabledState(link, 'Click me'); start(); }); diff --git a/test/public/test/settings.js b/test/public/test/settings.js index 1eddc251..606f2900 100644 --- a/test/public/test/settings.js +++ b/test/public/test/settings.js @@ -20,6 +20,24 @@ App.assertRequestPath = function(requestEnv, path) { equal(requestEnv['PATH_INFO'], path, 'request should be sent to right url'); }; +App.getVal = function(el) { + return el.is('input,textarea,select') ? el.val() : el.text(); +}; + +App.disabled = function(el) { + return el.is('input,textarea,select,button') ? el.is(':disabled') : el.data('ujs:enable-with'); +}; + +App.checkEnabledState = function(el, text) { + ok(!App.disabled(el), el.get(0).tagName + ' should not be disabled'); + equal(App.getVal(el), text, el.get(0).tagName + ' text should be original value'); +}; + +App.checkDisabledState = function(el, text) { + ok(App.disabled(el), el.get(0).tagName + ' should be disabled'); + equal(App.getVal(el), text, el.get(0).tagName + ' text should be disabled value'); +}; + // hijacks normal form submit; lets it submit to an iframe to prevent // navigating away from the test suite $(document).bind('submit', function(e) { diff --git a/test/views/index.erb b/test/views/index.erb index 6caf6f03..f153cd12 100644 --- a/test/views/index.erb +++ b/test/views/index.erb @@ -1,6 +1,6 @@ <% @title = "jquery-ujs test" %> -<%= test 'data-confirm', 'data-remote', 'data-disable', 'call-remote', 'call-remote-callbacks', 'data-method', 'override', 'csrf-refresh' %> +<%= test 'data-confirm', 'data-remote', 'data-disable', 'data-disable-with', 'call-remote', 'call-remote-callbacks', 'data-method', 'override', 'csrf-refresh' %>

<%= @title %>

From d61894b7b17f89440b08cb0b742a2a589533124f Mon Sep 17 00:00:00 2001 From: Lucas Mazza Date: Mon, 27 Jan 2014 16:53:02 -0200 Subject: [PATCH 2/4] Tidy up `data-disable-with` test source a bit. --- test/public/test/data-disable-with.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/test/public/test/data-disable-with.js b/test/public/test/data-disable-with.js index 80a183af..116f398b 100644 --- a/test/public/test/data-disable-with.js +++ b/test/public/test/data-disable-with.js @@ -27,7 +27,6 @@ module('data-disable-with', { } }); - asyncTest('form input field with "data-disable-with" attribute', 7, function() { var form = $('form[data-remote]'), input = form.find('input[type=text]'); @@ -38,8 +37,8 @@ asyncTest('form input field with "data-disable-with" attribute', 7, function() { App.checkEnabledState(input, 'john'); equal(data.params.user_name, 'john'); start(); - }, 13) - }) + }, 13); + }); form.trigger('submit'); App.checkDisabledState(input, 'processing ...'); @@ -55,8 +54,8 @@ asyncTest('form button with "data-disable-with" attribute', 6, function() { setTimeout(function() { App.checkEnabledState(button, 'Submit'); start(); - }, 13) - }) + }, 13); + }); form.trigger('submit'); App.checkDisabledState(button, 'submitting ...'); @@ -119,8 +118,8 @@ asyncTest('form[data-remote] textarea[data-disable-with] attribute', 3, function setTimeout(function() { equal(data.params.user_bio, 'born, lived, died.'); start(); - }, 13) - }) + }, 13); + }); form.trigger('submit'); App.checkDisabledState(textarea, 'processing ...'); From ed1fb395e98055e948071b18c360a0843c7d1b06 Mon Sep 17 00:00:00 2001 From: Lucas Mazza Date: Tue, 11 Mar 2014 22:52:43 -0300 Subject: [PATCH 3/4] Trim empty newlines --- test/public/test/data-disable-with.js | 1 - test/public/test/data-disable.js | 1 - 2 files changed, 2 deletions(-) diff --git a/test/public/test/data-disable-with.js b/test/public/test/data-disable-with.js index 116f398b..39a30172 100644 --- a/test/public/test/data-disable-with.js +++ b/test/public/test/data-disable-with.js @@ -225,7 +225,6 @@ asyncTest('form[data-remote] input|button|textarea[data-disable-with] does not d App.checkEnabledState(submit, 'Submit'); start(); - }); asyncTest('ctrl-clicking on a link does not disables the link', 6, function() { diff --git a/test/public/test/data-disable.js b/test/public/test/data-disable.js index 8d070352..60b8fd42 100644 --- a/test/public/test/data-disable.js +++ b/test/public/test/data-disable.js @@ -225,7 +225,6 @@ asyncTest('form[data-remote] input|button|textarea[data-disable] does not disabl App.checkEnabledState(submit, 'Submit'); start(); - }); asyncTest('ctrl-clicking on a link does not disables the link', 6, function() { From 693ccdf750fa715dbdc252f0d7215d5fdd490cce Mon Sep 17 00:00:00 2001 From: Lucas Mazza Date: Fri, 4 Apr 2014 19:03:15 -0300 Subject: [PATCH 4/4] Update replacement logic to avoid DOM operations when we won't change the HTML after all. --- src/rails.js | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/rails.js b/src/rails.js index 70454201..953d9d30 100644 --- a/src/rails.js +++ b/src/rails.js @@ -192,13 +192,17 @@ */ disableFormElements: function(form) { form.find(rails.disableSelector).each(function() { - var element, method, enabledState; + var element, method, replacement; + element = $(this); method = element.is('button') ? 'html' : 'val'; - enabledState = element[method](); + replacement = element.data('disable-with'); + + element.data('ujs:enable-with', element[method]()); + if (replacement !== undefined) { + element[method](replacement); + } - element.data('ujs:enable-with', enabledState); - element[method](element.data('disable-with') || enabledState); element.prop('disabled', true); }); }, @@ -275,9 +279,13 @@ // replace element's html with the 'data-disable-with' after storing original html // and prevent clicking on it disableElement: function(element) { - var enabledState = element.html(); - element.data('ujs:enable-with', enabledState); // store enabled state - element.html(element.data('disable-with') || enabledState); // set to disabled state + var replacement = element.data('disable-with'); + + element.data('ujs:enable-with', element.html()); // store enabled state + if (replacement !== undefined) { + element.html(replacement); + } + element.bind('click.railsDisable', function(e) { // prevent further clicking return rails.stopEverything(e); });