Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Supporting button[data-remote] as replacement of button_to helper #308

Merged
merged 1 commit into from

3 participants

@ingeniarius

In some cases we want to send data via AJAX with appropriate HTTP method (POST/PUT/DELETE).

We have two possibilities to reach this:
1. use "a" tag (link_to helper) with data-remote and data-method
2. use "button_to" helper.

In the first case the trouble is that user can do middle-click, then will be opened new tab in browser with correct url, but with wrong HTTP method (GET instead POST/PUT/DELETE).

In the second case the trouble is that additional markup will be generated (form, div, input...).

So this pull request will add support "button" tag with "data-remote" attribute, which solve issues with "link" and "button_to" approaches.
Also "button" tag have great ability to customization, because it can have inline html markup as opposed to "input" tag.

@JangoSteve
Collaborator

This looks good to me. Thanks for the test.

The only comment I have is that the default method should be GET instead of POST. But I'll change this after I pull it in.

@JangoSteve JangoSteve merged commit c304620 into rails:master
@morganchristiansson

tyop

boud instead of bound

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Feb 20, 2013
This page is out of date. Refresh to see the latest.
Showing with 41 additions and 6 deletions.
  1. +16 −0 src/rails.js
  2. +25 −6 test/public/test/data-remote.js
View
16 src/rails.js
@@ -23,6 +23,9 @@
// Link elements bound by jquery-ujs
linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote], a[data-disable-with]',
+ // Button elements boud jquery-ujs
+ buttonClickSelector: 'button[data-remote]',
+
// Select elements bound by jquery-ujs
inputChangeSelector: 'select[data-remote], input[data-remote], textarea[data-remote]',
@@ -100,6 +103,11 @@
url = element.data('url');
data = element.serialize();
if (element.data('params')) data = data + "&" + element.data('params');
+ } else if (element.is(rails.buttonClickSelector)) {
+ method = element.data('method') || 'post';
+ url = element.data('url');
+ data = element.serialize();
+ if (element.data('params')) data = data + "&" + element.data('params');
} else {
method = element.data('method');
url = rails.href(element);
@@ -315,6 +323,14 @@
}
});
+ $(document).delegate(rails.buttonClickSelector, 'click.rails', function(e) {
+ var button = $(this);
+ if (!rails.allowAction(button)) return rails.stopEverything(e);
+
+ rails.handleRemote(button);
+ return false;
+ });
+
$(document).delegate(rails.inputChangeSelector, 'change.rails', function(e) {
var link = $(this);
if (!rails.allowAction(link)) return rails.stopEverything(e);
View
31 test/public/test/data-remote.js
@@ -7,6 +7,12 @@ module('data-remote', {
'data-params': 'data1=value1&data2=value2',
text: 'my address'
}))
+ .append($('<button />', {
+ 'data-url': '/echo',
+ 'data-remote': 'true',
+ 'data-params': 'data1=value1&data2=value2',
+ text: 'my button'
+ }))
.append($('<form />', {
action: '/echo',
'data-remote': 'true',
@@ -67,12 +73,25 @@ asyncTest('ctrl-clicking on a link still fires ajax for non-GET links and for li
asyncTest('clicking on a link with data-remote attribute', 5, function() {
$('a[data-remote]')
- .bind('ajax:success', function(e, data, status, xhr) {
+ .bind('ajax:success', function(e, data, status, xhr) {
+ App.assert_callback_invoked('ajax:success');
+ App.assert_request_path(data, '/echo');
+ equal(data.params.data1, 'value1', 'ajax arguments should have key data1 with right value');
+ equal(data.params.data2, 'value2', 'ajax arguments should have key data2 with right value');
+ App.assert_get_request(data);
+ })
+ .bind('ajax:complete', function() { start() })
+ .trigger('click');
+});
+
+asyncTest('clicking on a button with data-remote attribute', 5, function() {
+ $('button[data-remote]')
+ .bind('ajax:success', function(e, data, status, xhr) {
App.assert_callback_invoked('ajax:success');
App.assert_request_path(data, '/echo');
equal(data.params.data1, 'value1', 'ajax arguments should have key data1 with right value');
equal(data.params.data2, 'value2', 'ajax arguments should have key data2 with right value');
- App.assert_get_request(data);
+ App.assert_post_request(data);
})
.bind('ajax:complete', function() { start() })
.trigger('click');
@@ -92,12 +111,12 @@ asyncTest('changing a select option with data-remote attribute', 5, function() {
);
$('select[data-remote]')
- .bind('ajax:success', function(e, data, status, xhr) {
+ .bind('ajax:success', function(e, data, status, xhr) {
App.assert_callback_invoked('ajax:success');
App.assert_request_path(data, '/echo');
equal(data.params.user_data, 'optionValue2', 'ajax arguments should have key term with right value');
equal(data.params.data1, 'value1', 'ajax arguments should have key data1 with right value');
- App.assert_get_request(data);
+ App.assert_get_request(data);
})
.bind('ajax:complete', function() { start() })
.val('optionValue2')
@@ -106,11 +125,11 @@ asyncTest('changing a select option with data-remote attribute', 5, function() {
asyncTest('submitting form with data-remote attribute', 4, function() {
$('form[data-remote]')
- .bind('ajax:success', function(e, data, status, xhr) {
+ .bind('ajax:success', function(e, data, status, xhr) {
App.assert_callback_invoked('ajax:success');
App.assert_request_path(data, '/echo');
equal(data.params.user_name, 'john', 'ajax arguments should have key user_name with right value');
- App.assert_post_request(data);
+ App.assert_post_request(data);
})
.bind('ajax:complete', function() { start() })
.trigger('submit');
Something went wrong with that request. Please try again.