jquery-ujs
Advanced tools
Comparing version 1.1.0-1 to 1.2.0
{ | ||
"name": "jquery-ujs", | ||
"version": "1.1.0-1", | ||
"version": "1.2.0", | ||
"description": "Ruby on Rails unobtrusive scripting adapter for jQuery, for npm", | ||
@@ -5,0 +5,0 @@ "main": "src/rails.js", |
@@ -84,5 +84,14 @@ Notes on the npm supporting fork | ||
Follow [this wiki](https://github.com/rails/jquery-ujs/wiki/Running-Tests-and-Contributing) to run tests . | ||
Follow [this wiki](https://github.com/rails/jquery-ujs/wiki/Running-Tests-and-Contributing) to run tests. | ||
## Contributing to jquery-ujs | ||
jquery-ujs is work of many contributors. You're encouraged to submit pull requests, propose | ||
features and discuss issues. | ||
See [CONTRIBUTING](CONTRIBUTING.md). | ||
## License | ||
jquery-ujs is released under the [MIT License](MIT-LICENSE). | ||
[data]: http://www.w3.org/TR/html5/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes "Embedding custom non-visible data with the data-* attributes" | ||
@@ -89,0 +98,0 @@ [wiki]: https://github.com/rails/jquery-ujs/wiki |
@@ -27,6 +27,6 @@ (function($, undefined) { | ||
// Link elements bound by jquery-ujs | ||
linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote], a[data-disable-with], a[data-disable]', | ||
linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote]:not([disabled]), a[data-disable-with], a[data-disable]', | ||
// Button elements bound by jquery-ujs | ||
buttonClickSelector: 'button[data-remote]:not(form button), button[data-confirm]:not(form button)', | ||
buttonClickSelector: 'button[data-remote]:not([form]):not(form button), button[data-confirm]:not([form]):not(form button)', | ||
@@ -49,3 +49,3 @@ // Select elements bound by jquery-ujs | ||
// Form required input elements | ||
requiredInputSelector: 'input[name][required]:not([disabled]),textarea[name][required]:not([disabled])', | ||
requiredInputSelector: 'input[name][required]:not([disabled]), textarea[name][required]:not([disabled])', | ||
@@ -77,3 +77,3 @@ // Form file input elements | ||
// making sure that all forms have actual up-to-date token(cached forms contain old one) | ||
// Make sure that all forms have actual up-to-date tokens (cached forms contain old ones) | ||
refreshCSRFTokens: function(){ | ||
@@ -119,5 +119,5 @@ $('form input[name="' + rails.csrfParam() + '"]').val(rails.csrfToken()); | ||
if (element.is('form')) { | ||
method = element.attr('method'); | ||
url = element.attr('action'); | ||
data = element.serializeArray(); | ||
method = element.data('ujs:submit-button-formmethod') || element.attr('method'); | ||
url = element.data('ujs:submit-button-formaction') || element.attr('action'); | ||
data = $(element[0].elements).serializeArray(); | ||
// memoized value from clicked submit button | ||
@@ -129,2 +129,4 @@ var button = element.data('ujs:submit-button'); | ||
} | ||
element.data('ujs:submit-button-formmethod', null); | ||
element.data('ujs:submit-button-formaction', null); | ||
} else if (element.is(rails.inputChangeSelector)) { | ||
@@ -258,4 +260,4 @@ method = element.data('method'); | ||
element.data('ujs:enable-with', element[method]()); | ||
if (replacement !== undefined) { | ||
element.data('ujs:enable-with', element[method]()); | ||
element[method](replacement); | ||
@@ -265,2 +267,3 @@ } | ||
element.prop('disabled', true); | ||
element.data('ujs:disabled', true); | ||
}, | ||
@@ -280,4 +283,8 @@ | ||
var method = element.is('button') ? 'html' : 'val'; | ||
if (typeof element.data('ujs:enable-with') !== 'undefined') element[method](element.data('ujs:enable-with')); | ||
if (element.data('ujs:enable-with') !== undefined) { | ||
element[method](element.data('ujs:enable-with')); | ||
element.removeData('ujs:enable-with'); // clean up cache | ||
} | ||
element.prop('disabled', false); | ||
element.removeData('ujs:disabled'); | ||
}, | ||
@@ -345,3 +352,3 @@ | ||
// replace element's html with the 'data-disable-with' after storing original html | ||
// Replace element's html with the 'data-disable-with' after storing original html | ||
// and prevent clicking on it | ||
@@ -351,4 +358,4 @@ disableElement: function(element) { | ||
element.data('ujs:enable-with', element.html()); // store enabled state | ||
if (replacement !== undefined) { | ||
element.data('ujs:enable-with', element.html()); // store enabled state | ||
element.html(replacement); | ||
@@ -360,5 +367,6 @@ } | ||
}); | ||
element.data('ujs:disabled', true); | ||
}, | ||
// restore element to its original state which was disabled by 'disableElement' above | ||
// Restore element to its original state which was disabled by 'disableElement' above | ||
enableElement: function(element) { | ||
@@ -370,2 +378,3 @@ if (element.data('ujs:enable-with') !== undefined) { | ||
element.unbind('click.railsDisable'); // enable element | ||
element.removeData('ujs:disabled'); | ||
} | ||
@@ -387,3 +396,3 @@ }; | ||
if (element.data('ujs:enable-with')) { | ||
if (element.data('ujs:disabled')) { | ||
$.rails.enableFormElement(element); | ||
@@ -396,3 +405,3 @@ } | ||
if (element.data('ujs:enable-with')) { | ||
if (element.data('ujs:disabled')) { | ||
$.rails.enableElement(element); | ||
@@ -421,3 +430,3 @@ } | ||
var handleRemote = rails.handleRemote(link); | ||
// response from rails.handleRemote() will either be false or a deferred object promise. | ||
// Response from rails.handleRemote() will either be false or a deferred object promise. | ||
if (handleRemote === false) { | ||
@@ -444,3 +453,3 @@ rails.enableElement(link); | ||
var handleRemote = rails.handleRemote(button); | ||
// response from rails.handleRemote() will either be false or a deferred object promise. | ||
// Response from rails.handleRemote() will either be false or a deferred object promise. | ||
if (handleRemote === false) { | ||
@@ -470,7 +479,13 @@ rails.enableFormElement(button); | ||
// skip other logic when required values are missing or file upload is present | ||
// Skip other logic when required values are missing or file upload is present | ||
if (form.attr('novalidate') === undefined) { | ||
blankRequiredInputs = rails.blankInputs(form, rails.requiredInputSelector, false); | ||
if (blankRequiredInputs && rails.fire(form, 'ajax:aborted:required', [blankRequiredInputs])) { | ||
return rails.stopEverything(e); | ||
if (form.data('ujs:formnovalidate-button') === undefined) { | ||
blankRequiredInputs = rails.blankInputs(form, rails.requiredInputSelector, false); | ||
if (blankRequiredInputs && rails.fire(form, 'ajax:aborted:required', [blankRequiredInputs])) { | ||
return rails.stopEverything(e); | ||
} | ||
} else { | ||
// Clear the formnovalidate in case the next button click is not on a formnovalidate button | ||
// Not strictly necessary to do here, since it is also reset on each button click, but just to be certain | ||
form.data('ujs:formnovalidate-button', undefined); | ||
} | ||
@@ -482,3 +497,3 @@ } | ||
if (nonBlankFileInputs) { | ||
// slight timeout so that the submit button gets properly serialized | ||
// Slight timeout so that the submit button gets properly serialized | ||
// (make it easy for event handler to serialize form without disabled values) | ||
@@ -488,3 +503,3 @@ setTimeout(function(){ rails.disableFormElements(form); }, 13); | ||
// re-enable form elements if event bindings return false (canceling normal form submission) | ||
// Re-enable form elements if event bindings return false (canceling normal form submission) | ||
if (!aborted) { setTimeout(function(){ rails.enableFormElements(form); }, 13); } | ||
@@ -499,3 +514,3 @@ | ||
} else { | ||
// slight timeout so that the submit button gets properly serialized | ||
// Slight timeout so that the submit button gets properly serialized | ||
setTimeout(function(){ rails.disableFormElements(form); }, 13); | ||
@@ -510,7 +525,16 @@ } | ||
// register the pressed submit button | ||
// Register the pressed submit button | ||
var name = button.attr('name'), | ||
data = name ? {name:name, value:button.val()} : null; | ||
button.closest('form').data('ujs:submit-button', data); | ||
var form = button.closest('form'); | ||
if (form.length === 0) { | ||
form = $('#' + button.attr('form')); | ||
} | ||
form.data('ujs:submit-button', data); | ||
// Save attributes from button | ||
form.data('ujs:formnovalidate-button', button.attr('formnovalidate')); | ||
form.data('ujs:submit-button-formaction', button.attr('formaction')); | ||
form.data('ujs:submit-button-formmethod', button.attr('formmethod')); | ||
}); | ||
@@ -517,0 +541,0 @@ |
@@ -20,8 +20,12 @@ (function(){ | ||
function start_after_submit(form) { | ||
form.bind('ajax:complete', function() { | ||
ok(true, 'ajax:complete'); | ||
start(); | ||
}); | ||
} | ||
function submit(fn) { | ||
var form = $('form') | ||
.bind('ajax:complete', function(){ | ||
ok(true, 'ajax:complete'); | ||
start(); | ||
}); | ||
var form = $('form'); | ||
start_after_submit(form); | ||
@@ -32,2 +36,9 @@ if (fn) fn(form); | ||
function submit_with_button(submit_button) { | ||
var form = $('form'); | ||
start_after_submit(form); | ||
submit_button.trigger('click'); | ||
} | ||
asyncTest('modifying form fields with "ajax:before" sends modified data in request', 4, function(){ | ||
@@ -188,2 +199,17 @@ $('form[data-remote]') | ||
asyncTest('form should be submitted with blank required fields if the button has the "formnovalidate" attribute', 2, function(){ | ||
var submit_button = $('<input type="submit" formnovalidate>'); | ||
var form = $('form[data-remote]') | ||
.append($('<input type="text" name="user_name" required="required">')) | ||
.append(submit_button) | ||
.bind('ajax:beforeSend', function() { | ||
ok(true, 'ajax:beforeSend should run'); | ||
}) | ||
.bind('ajax:aborted:required', function() { | ||
ok(false, 'ajax:aborted:required should not run'); | ||
}); | ||
submit_with_button(submit_button); | ||
}); | ||
asyncTest('blank required form input for non-remote form with "novalidate" attribute should not abort normal submission', 1, function() { | ||
@@ -190,0 +216,0 @@ $(document).bind('iframe:loading', function() { |
@@ -35,2 +35,15 @@ (function(){ | ||
asyncTest('form method is read from submit button "formmethod" if submit is triggered by that button', 1, function() { | ||
var submitButton = $('<input type="submit" formmethod="get">') | ||
buildForm({ method: 'post' }); | ||
$('#qunit-fixture').find('form').append(submitButton) | ||
.bind('ajax:success', function(e, data, status, xhr) { | ||
App.assertGetRequest(data); | ||
}) | ||
.bind('ajax:complete', function() { start() }); | ||
submitButton.trigger('click'); | ||
}); | ||
asyncTest('form default method is GET', 1, function() { | ||
@@ -60,2 +73,15 @@ buildForm(); | ||
asyncTest('form url is read from submit button "formaction" if submit is triggered by that button', 1, function() { | ||
var submitButton = $('<input type="submit" formaction="/echo">') | ||
buildForm({ method: 'post', href: '/echo2' }); | ||
$('#qunit-fixture').find('form').append(submitButton) | ||
.bind('ajax:success', function(e, data, status, xhr) { | ||
App.assertRequestPath(data, '/echo'); | ||
}) | ||
.bind('ajax:complete', function() { start() }); | ||
submitButton.trigger('click'); | ||
}); | ||
asyncTest('prefer JS, but accept any format', 1, function() { | ||
@@ -62,0 +88,0 @@ buildForm({ method: 'post' }); |
@@ -54,3 +54,3 @@ module('data-disable', { | ||
asyncTest('form button with "data-disable" attribute', 6, function() { | ||
asyncTest('form button with "data-disable" attribute', 7, function() { | ||
var form = $('form[data-remote]'), button = $('<button data-disable name="submit2">Submit</button>'); | ||
@@ -70,2 +70,3 @@ form.append(button); | ||
App.checkDisabledState(button, 'Submit'); | ||
equal(button.data('ujs:enable-with'), undefined); | ||
}); | ||
@@ -137,3 +138,3 @@ | ||
asyncTest('a[data-disable] disables', 4, function() { | ||
asyncTest('a[data-disable] disables', 5, function() { | ||
var link = $('a[data-disable]'); | ||
@@ -145,2 +146,3 @@ | ||
App.checkDisabledState(link, 'Click me'); | ||
equal(link.data('ujs:enable-with'), undefined); | ||
start(); | ||
@@ -147,0 +149,0 @@ }); |
@@ -19,4 +19,11 @@ module('data-remote', { | ||
'data-remote': 'true', | ||
method: 'post' | ||
method: 'post', | ||
id: 'my-remote-form' | ||
})) | ||
.append($('<a />', { | ||
href: '/echo', | ||
'data-remote': 'true', | ||
disabled: 'disabled', | ||
text: 'Disabed link' | ||
})) | ||
.find('form').append($('<input type="text" name="user_name" value="john">')); | ||
@@ -88,2 +95,15 @@ | ||
asyncTest('clicking on a link with disabled attribute', 0, function() { | ||
$('a[disabled]') | ||
.bind("ajax:before", function(e, data, status, xhr) { | ||
App.assertCallbackNotInvoked('ajax:success') | ||
}) | ||
.bind('ajax:complete', function() { start() }) | ||
.trigger('click') | ||
setTimeout(function() { | ||
start(); | ||
}, 13); | ||
}); | ||
asyncTest('clicking on a button with data-remote attribute', 5, function() { | ||
@@ -140,2 +160,47 @@ $('button[data-remote]') | ||
asyncTest('submitting form with data-remote attribute submits input with matching [form] attribute', 5, function() { | ||
$('#qunit-fixture') | ||
.append($('<input type="text" name="user_data" value="value1" form="my-remote-form">')); | ||
$('form[data-remote]') | ||
.bind('ajax:success', function(e, data, status, xhr) { | ||
App.assertCallbackInvoked('ajax:success'); | ||
App.assertRequestPath(data, '/echo'); | ||
equal(data.params.user_name, 'john', 'ajax arguments should have key user_name with right value'); | ||
equal(data.params.user_data, 'value1', 'ajax arguments should have key user_data with right value'); | ||
App.assertPostRequest(data); | ||
}) | ||
.bind('ajax:complete', function() { start() }) | ||
.trigger('submit'); | ||
}); | ||
asyncTest('submitting form with data-remote attribute by clicking button with matching [form] attribute', 5, function() { | ||
$('form[data-remote]') | ||
.bind('ajax:success', function(e, data, status, xhr) { | ||
App.assertCallbackInvoked('ajax:success'); | ||
App.assertRequestPath(data, '/echo'); | ||
equal(data.params.user_name, 'john', 'ajax arguments should have key user_name with right value'); | ||
equal(data.params.user_data, 'value2', 'ajax arguments should have key user_data with right value'); | ||
App.assertPostRequest(data); | ||
}) | ||
.bind('ajax:complete', function() { start() }); | ||
$('<button />', { | ||
type: "submit", | ||
name: "user_data", | ||
value: "value1", | ||
form: "my-remote-form" | ||
}) | ||
.appendTo($('#qunit-fixture')); | ||
$('<button />', { | ||
type: "submit", | ||
name: "user_data", | ||
value: "value2", | ||
form: "my-remote-form" | ||
}) | ||
.appendTo($('#qunit-fixture')) | ||
.trigger('click'); | ||
}); | ||
asyncTest('form\'s submit bindings in browsers that don\'t support submit bubbling', 5, function() { | ||
@@ -142,0 +207,0 @@ var form = $('form[data-remote]'), directBindingCalled = false; |
@@ -28,3 +28,3 @@ var App = App || {}; | ||
App.disabled = function(el) { | ||
return el.is('input,textarea,select,button') ? el.is(':disabled') : el.data('ujs:enable-with'); | ||
return el.is('input,textarea,select,button') ? (el.is(':disabled') && el.data('ujs:disabled')) : el.data('ujs:disabled'); | ||
}; | ||
@@ -31,0 +31,0 @@ |
Sorry, the diff of this file is not supported yet
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
4674
0
103
0
183968
32