Diff
checker
Text
Text
Images
Documents
Excel
Folders
Legal
Enterprise
Desktop
Pricing
Sign in
Download Diffchecker Desktop
Compare text
Find the difference between two text files
Tools
History
Real-time editor
Hide whitespace changes
Hide unchanged lines
Disable line wrap
Layout
Split
Unified
Diff precision
Smart
Word
Char
Text styles
Change appearance
Syntax highlighting
Choose syntax
Ignore
Transform text
Go to first change
Edit input
Diffchecker Desktop
The most secure way to run Diffchecker. Get the Diffchecker Desktop app: your diffs never leave your computer!
Get Desktop
Untitled diff
Created
11 years ago
Diff never expires
Clear
Export
Share
Explain
112 removals
Lines
Total
Removed
Characters
Total
Removed
To continue using this feature, upgrade to
Diff
checker
Pro
View Pricing
374 lines
Copy
172 additions
Lines
Total
Added
Characters
Total
Added
To continue using this feature, upgrade to
Diff
checker
Pro
View Pricing
430 lines
Copy
(function($, undefined) {
(function($, undefined) {
/**
/**
* Unobtrusive scripting adapter for jQuery
* Unobtrusive scripting adapter for jQuery
*
*
* Requires jQuery 1.6.0 or later.
* Requires jQuery 1.6.0 or later.
* https://github.com/rails/jquery-ujs
* https://github.com/rails/jquery-ujs
* Uploading file using rails.js
* Uploading file using rails.js
* =============================
* =============================
*
*
* By default, browsers do not allow files to be uploaded via AJAX. As a result, if there are any non-blank file fields
* By default, browsers do not allow files to be uploaded via AJAX. As a result, if there are any non-blank file fields
* in the remote form, this adapter aborts the AJAX submission and allows the form to submit through standard means.
* in the remote form, this adapter aborts the AJAX submission and allows the form to submit through standard means.
*
*
* The `ajax:aborted:file` event allows you to bind your own handler to process the form submission however you wish.
* The `ajax:aborted:file` event allows you to bind your own handler to process the form submission however you wish.
*
*
* Ex:
* Ex:
* $('form').live('ajax:aborted:file', function(event, elements){
* $('form').live('ajax:aborted:file', function(event, elements){
* // Implement own remote file-transfer handler here for non-blank file inputs passed in `elements`.
* // Implement own remote file-transfer handler here for non-blank file inputs passed in `elements`.
* // Returning false in this handler tells rails.js to disallow standard form submission
* // Returning false in this handler tells rails.js to disallow standard form submission
* return false;
* return false;
* });
* });
*
*
* The `ajax:aborted:file` event is fired when a file-type input is detected with a non-blank value.
* The `ajax:aborted:file` event is fired when a file-type input is detected with a non-blank value.
*
*
* Third-party tools can use this hook to detect when an AJAX file upload is attempted, and then use
* Third-party tools can use this hook to detect when an AJAX file upload is attempted, and then use
* techniques like the iframe method to upload the file instead.
* techniques like the iframe method to upload the file instead.
*
*
* Required fields in rails.js
* Required fields in rails.js
* ===========================
* ===========================
*
*
* If any blank required inputs (required="required") are detected in the remote form, the whole form submission
* If any blank required inputs (required="required") are detected in the remote form, the whole form submission
* is canceled. Note that this is unlike file inputs, which still allow standard (non-AJAX) form submission.
* is canceled. Note that this is unlike file inputs, which still allow standard (non-AJAX) form submission.
*
*
* The `ajax:aborted:required` event allows you to bind your own handler to inform the user of blank required inputs.
* The `ajax:aborted:required` event allows you to bind your own handler to inform the user of blank required inputs.
*
*
* !! Note that Opera does not fire the form's submit event if there are blank required inputs, so this event may never
* !! Note that Opera does not fire the form's submit event if there are blank required inputs, so this event may never
* get fired in Opera. This event is what causes other browsers to exhibit the same submit-aborting behavior.
* get fired in Opera. This event is what causes other browsers to exhibit the same submit-aborting behavior.
*
*
* Ex:
* Ex:
* $('form').live('ajax:aborted:required', function(event, elements){
* $('form').live('ajax:aborted:required', function(event, elements){
* // Returning false in this handler tells rails.js to submit the form anyway.
* // Returning false in this handler tells rails.js to submit the form anyway.
* // The blank required inputs are passed to this function in `elements`.
* // The blank required inputs are passed to this function in `elements`.
* return ! confirm("Would you like to submit the form with missing info?");
* return ! confirm("Would you like to submit the form with missing info?");
* });
* });
*/
*/
Copy
Copied
Copy
Copied
// Cut down on the number if issues from people inadvertently including jquery_ujs twice
// by detecting and raising an error when it happens.
var alreadyInitialized = function() {
var events = $._data(document, 'events');
return events && events.click && $.grep(events.click, function(e) { return e.namespace === 'rails'; }).length;
}
if ( alreadyInitialized() ) {
$.error('jquery-ujs has already been loaded!');
}
// Shorthand to make it a little easier to call public rails functions from within rails.js
// Shorthand to make it a little easier to call public rails functions from within rails.js
var rails;
var rails;
$.rails = rails = {
$.rails = rails = {
// Link elements bound by jquery-ujs
// 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]',
// Select elements bound by jquery-ujs
// Select elements bound by jquery-ujs
inputChangeSelector: 'select[data-remote], input[data-remote], textarea[data-remote]',
inputChangeSelector: 'select[data-remote], input[data-remote], textarea[data-remote]',
// Form elements bound by jquery-ujs
// Form elements bound by jquery-ujs
formSubmitSelector: 'form',
formSubmitSelector: 'form',
// Form input elements bound by jquery-ujs
// Form input elements bound by jquery-ujs
Copy
Copied
Copy
Copied
formInputClickSelector: 'form input[type=submit], form input[type=image], form button[type=submit], form button:not(
button
[type])',
formInputClickSelector: 'form input[type=submit], form input[type=image], form button[type=submit], form button:not(
[type])',
// Form input elements disabled during form submission
// 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]',
// Form input elements re-enabled after form submission
// 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',
// Form required input elements
// 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])',
// Form file input elements
// Form file input elements
fileInputSelector: 'input:file',
fileInputSelector: 'input:file',
// Link onClick disable selector with possible reenable after remote submission
// Link onClick disable selector with possible reenable after remote submission
linkDisableSelector: 'a[data-disable-with]',
linkDisableSelector: 'a[data-disable-with]',
// Make sure that every Ajax request sends the CSRF token
// Make sure that every Ajax request sends the CSRF token
CSRFProtection: function(xhr) {
CSRFProtection: function(xhr) {
var token = $('meta[name="csrf-token"]').attr('content');
var token = $('meta[name="csrf-token"]').attr('content');
if (token) xhr.setRequestHeader('X-CSRF-Token', token);
if (token) xhr.setRequestHeader('X-CSRF-Token', token);
},
},
// Triggers an event on an element and returns false if the event result is false
// Triggers an event on an element and returns false if the event result is false
fire: function(obj, name, data) {
fire: function(obj, name, data) {
var event = $.Event(name);
var event = $.Event(name);
obj.trigger(event, data);
obj.trigger(event, data);
return event.result !== false;
return event.result !== false;
},
},
// Default confirm dialog, may be overridden with custom confirm dialog in $.rails.confirm
// Default confirm dialog, may be overridden with custom confirm dialog in $.rails.confirm
confirm: function(message) {
confirm: function(message) {
return confirm(message);
return confirm(message);
},
},
// Default ajax function, may be overridden with custom function in $.rails.ajax
// Default ajax function, may be overridden with custom function in $.rails.ajax
ajax: function(options) {
ajax: function(options) {
return $.ajax(options);
return $.ajax(options);
},
},
Copy
Copied
Copy
Copied
// Default way to get an element's href. May be overridden at $.rails.href.
href: function(element) {
return element.attr('href');
},
// Submits "remote" forms and links with ajax
// Submits "remote" forms and links with ajax
handleRemote: function(element) {
handleRemote: function(element) {
Copy
Copied
Copy
Copied
var method, url, data,
var method, url, data,
elC
rossDomain
,
cross
D
omain
, withCredentials,
dataType
,
options;
c
rossDomain
= element.data('
cross
-d
omain
') || null,
dataType = element.data('type') || ($.ajaxSettings && $.ajaxSettings.
dataType
),
options;
if (rails.fire(element, 'ajax:before')) {
if (rails.fire(element, 'ajax:before')) {
Copy
Copied
Copy
Copied
elCrossDomain = element.data('cross-domain');
crossDomain = elCrossDomain === undefined ? null : elCrossDomain;
withCredentials = element.data('with-credentials') || null;
dataType = element.data('type') || ($.ajaxSettings && $.ajaxSettings.dataType);
if (element.is('form')) {
if (element.is('form')) {
method = element.attr('method');
method = element.attr('method');
url = element.attr('action');
url = element.attr('action');
data = element.serializeArray();
data = element.serializeArray();
// memoized value from clicked submit button
// memoized value from clicked submit button
var button = element.data('ujs:submit-button');
var button = element.data('ujs:submit-button');
if (button) {
if (button) {
data.push(button);
data.push(button);
element.data('ujs:submit-button', null);
element.data('ujs:submit-button', null);
}
}
} else if (element.is(rails.inputChangeSelector)) {
} else if (element.is(rails.inputChangeSelector)) {
method = element.data('method');
method = element.data('method');
url = element.data('url');
url = element.data('url');
data = element.serialize();
data = element.serialize();
if (element.data('params')) data = data + "&" + element.data('params');
if (element.data('params')) data = data + "&" + element.data('params');
} else {
} else {
method = element.data('method');
method = element.data('method');
Copy
Copied
Copy
Copied
url =
element
.attr('href'
);
url =
rails.href(
element
);
data = element.data('params') || null;
data = element.data('params') || null;
}
}
options = {
options = {
Copy
Copied
Copy
Copied
type: method || 'GET', data: data, dataType: dataType,
crossDomain: crossDomain,
type: method || 'GET', data: data, dataType: dataType,
// stopping the "ajax:beforeSend" event will cancel the ajax request
// stopping the "ajax:beforeSend" event will cancel the ajax request
beforeSend: function(xhr, settings) {
beforeSend: function(xhr, settings) {
if (settings.dataType === undefined) {
if (settings.dataType === undefined) {
xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script);
xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script);
}
}
return rails.fire(element, 'ajax:beforeSend', [xhr, settings]);
return rails.fire(element, 'ajax:beforeSend', [xhr, settings]);
},
},
success: function(data, status, xhr) {
success: function(data, status, xhr) {
element.trigger('ajax:success', [data, status, xhr]);
element.trigger('ajax:success', [data, status, xhr]);
},
},
complete: function(xhr, status) {
complete: function(xhr, status) {
element.trigger('ajax:complete', [xhr, status]);
element.trigger('ajax:complete', [xhr, status]);
},
},
error: function(xhr, status, error) {
error: function(xhr, status, error) {
element.trigger('ajax:error', [xhr, status, error]);
element.trigger('ajax:error', [xhr, status, error]);
Copy
Copied
Copy
Copied
}
},
xhrFields: {
withCredentials: withCredentials
},
crossDomain: crossDomain
};
};
// Only pass url to `ajax` options if not blank
// Only pass url to `ajax` options if not blank
if (url) { options.url = url; }
if (url) { options.url = url; }
Copy
Copied
Copy
Copied
return
rails.ajax(options);
var jqxhr =
rails.ajax(options);
element.trigger('ajax:send', jqxhr);
return jqxhr;
} else {
} else {
return false;
return false;
}
}
},
},
// Handles "data-method" on links such as:
// Handles "data-method" on links such as:
// <a href="/users/5" data-method="delete" rel="nofollow" data-confirm="Are you sure?">Delete</a>
// <a href="/users/5" data-method="delete" rel="nofollow" data-confirm="Are you sure?">Delete</a>
handleMethod: function(link) {
handleMethod: function(link) {
Copy
Copied
Copy
Copied
var href =
link.attr('
href
'
),
var href =
rails.
href
(link
),
method = link.data('method'),
method = link.data('method'),
target = link.attr('target'),
target = link.attr('target'),
csrf_token = $('meta[name=csrf-token]').attr('content'),
csrf_token = $('meta[name=csrf-token]').attr('content'),
csrf_param = $('meta[name=csrf-param]').attr('content'),
csrf_param = $('meta[name=csrf-param]').attr('content'),
form = $('<form method="post" action="' + href + '"></form>'),
form = $('<form method="post" action="' + href + '"></form>'),
metadata_input = '<input name="_method" value="' + method + '" type="hidden" />';
metadata_input = '<input name="_method" value="' + method + '" type="hidden" />';
if (csrf_param !== undefined && csrf_token !== undefined) {
if (csrf_param !== undefined && csrf_token !== undefined) {
metadata_input += '<input name="' + csrf_param + '" value="' + csrf_token + '" type="hidden" />';
metadata_input += '<input name="' + csrf_param + '" value="' + csrf_token + '" type="hidden" />';
}
}
if (target) { form.attr('target', target); }
if (target) { form.attr('target', target); }
form.hide().append(metadata_input).appendTo('body');
form.hide().append(metadata_input).appendTo('body');
form.submit();
form.submit();
},
},
/* Disables form elements:
/* Disables form elements:
- Caches element value in 'ujs:enable-with' data store
- Caches element value in 'ujs:enable-with' data store
- Replaces element text with value of 'data-disable-with' attribute
- Replaces element text with value of 'data-disable-with' attribute
- Sets disabled property to true
- Sets disabled property to true
*/
*/
disableFormElements: function(form) {
disableFormElements: function(form) {
form.find(rails.disableSelector).each(function() {
form.find(rails.disableSelector).each(function() {
var element = $(this), method = element.is('button') ? 'html' : 'val';
var element = $(this), method = element.is('button') ? 'html' : 'val';
element.data('ujs:enable-with', element[method]());
element.data('ujs:enable-with', element[method]());
element[method](element.data('disable-with'));
element[method](element.data('disable-with'));
element.prop('disabled', true);
element.prop('disabled', true);
});
});
},
},
/* Re-enables disabled form elements:
/* Re-enables disabled form elements:
- Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`)
- Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`)
- Sets disabled property to false
- Sets disabled property to false
*/
*/
enableFormElements: function(form) {
enableFormElements: function(form) {
form.find(rails.enableSelector).each(function() {
form.find(rails.enableSelector).each(function() {
var element = $(this), method = element.is('button') ? 'html' : 'val';
var element = $(this), method = element.is('button') ? 'html' : 'val';
if (element.data('ujs:enable-with')) element[method](element.data('ujs:enable-with'));
if (element.data('ujs:enable-with')) element[method](element.data('ujs:enable-with'));
element.prop('disabled', false);
element.prop('disabled', false);
});
});
},
},
/* For 'data-confirm' attribute:
/* For 'data-confirm' attribute:
- Fires `confirm` event
- Fires `confirm` event
- Shows the confirmation dialog
- Shows the confirmation dialog
- Fires the `confirm:complete` event
- Fires the `confirm:complete` event
Returns `true` if no function stops the chain and user chose yes; `false` otherwise.
Returns `true` if no function stops the chain and user chose yes; `false` otherwise.
Attaching a handler to the element's `confirm` event that returns a `falsy` value cancels the confirmation dialog.
Attaching a handler to the element's `confirm` event that returns a `falsy` value cancels the confirmation dialog.
Attaching a handler to the element's `confirm:complete` event that returns a `falsy` value makes this function
Attaching a handler to the element's `confirm:complete` event that returns a `falsy` value makes this function
return false. The `confirm:complete` event is fired whether or not the user answered true or false to the dialog.
return false. The `confirm:complete` event is fired whether or not the user answered true or false to the dialog.
*/
*/
allowAction: function(element) {
allowAction: function(element) {
var message = element.data('confirm'),
var message = element.data('confirm'),
answer = false, callback;
answer = false, callback;
if (!message) { return true; }
if (!message) { return true; }
if (rails.fire(element, 'confirm')) {
if (rails.fire(element, 'confirm')) {
answer = rails.confirm(message);
answer = rails.confirm(message);
callback = rails.fire(element, 'confirm:complete', [answer]);
callback = rails.fire(element, 'confirm:complete', [answer]);
}
}
return answer && callback;
return answer && callback;
},
},
// Helper function which checks for blank inputs in a form that match the specified CSS selector
// Helper function which checks for blank inputs in a form that match the specified CSS selector
blankInputs: function(form, specifiedSelector, nonBlank) {
blankInputs: function(form, specifiedSelector, nonBlank) {
Copy
Copied
Copy
Copied
var inputs = $(), input,
var inputs = $(), input,
valueToCheck,
selector = specifiedSelector || 'input,textarea'
;
selector = specifiedSelector || 'input,textarea'
,
form.find(selector)
.each(function() {
allInputs =
form.find(selector)
;
allInputs
.each(function() {
input = $(this);
input = $(this);
Copy
Copied
Copy
Copied
// Collect non-blank
input
s if
nonBlank
option is true, otherwise, collect blank inputs
valueToCheck = input.is(':checkbox,:radio') ?
input
.is(':checked') : input.val();
if (
nonBlank
?
input.
val() : !
input.
val()
) {
// If
nonBlank
and valueToCheck are both truthy, or nonBlank and valueToCheck are both falsey
if (
!valueToCheck === !
nonBlank
) {
// Don't count unchecked required radio if other radio with same name is checked
if (
input.
is(':radio') && allInputs.filter('input:radio:checked[name="' +
input.
attr('name') + '"]').length
) {
return true; // Skip to next input
}
inputs = inputs.add(input);
inputs = inputs.add(input);
}
}
});
});
return inputs.length ? inputs : false;
return inputs.length ? inputs : false;
},
},
// Helper function which checks for non-blank inputs in a form that match the specified CSS selector
// Helper function which checks for non-blank inputs in a form that match the specified CSS selector
nonBlankInputs: function(form, specifiedSelector) {
nonBlankInputs: function(form, specifiedSelector) {
return rails.blankInputs(form, specifiedSelector, true); // true specifies nonBlank
return rails.blankInputs(form, specifiedSelector, true); // true specifies nonBlank
},
},
// Helper function, needed to provide consistent behavior in IE
// Helper function, needed to provide consistent behavior in IE
stopEverything: function(e) {
stopEverything: function(e) {
$(e.target).trigger('ujs:everythingStopped');
$(e.target).trigger('ujs:everythingStopped');
e.stopImmediatePropagation();
e.stopImmediatePropagation();
return false;
return false;
},
},
// find all the submit events directly bound to the form and
// find all the submit events directly bound to the form and
// manually invoke them. If anyone returns false then stop the loop
// manually invoke them. If anyone returns false then stop the loop
callFormSubmitBindings: function(form, event) {
callFormSubmitBindings: function(form, event) {
var events = form.data('events'), continuePropagation = true;
var events = form.data('events'), continuePropagation = true;
if (events !== undefined && events['submit'] !== undefined) {
if (events !== undefined && events['submit'] !== undefined) {
$.each(events['submit'], function(i, obj){
$.each(events['submit'], function(i, obj){
if (typeof obj.handler === 'function') return continuePropagation = obj.handler(event);
if (typeof obj.handler === 'function') return continuePropagation = obj.handler(event);
});
});
}
}
return continuePropagation;
return continuePropagation;
},
},
// 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
// and prevent clicking on it
disableElement: function(element) {
disableElement: function(element) {
element.data('ujs:enable-with', element.html()); // store enabled state
element.data('ujs:enable-with', element.html()); // store enabled state
element.html(element.data('disable-with')); // set to disabled state
element.html(element.data('disable-with')); // set to disabled state
element.bind('click.railsDisable', function(e) { // prevent further clicking
element.bind('click.railsDisable', function(e) { // prevent further clicking
Copy
Copied
Copy
Copied
return rails.stopEverything(e)
return rails.stopEverything(e)
;
});
});
},
},
// 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) {
enableElement: function(element) {
if (element.data('ujs:enable-with') !== undefined) {
if (element.data('ujs:enable-with') !== undefined) {
element.html(element.data('ujs:enable-with')); // set to old enabled state
element.html(element.data('ujs:enable-with')); // set to old enabled state
// this should be element.removeData('ujs:enable-with')
// this should be element.removeData('ujs:enable-with')
// but, there is currently a bug in jquery which makes hyphenated data attributes not get removed
// but, there is currently a bug in jquery which makes hyphenated data attributes not get removed
element.data('ujs:enable-with', false); // clean up cache
element.data('ujs:enable-with', false); // clean up cache
}
}
element.unbind('click.railsDisable'); // enable element
element.unbind('click.railsDisable'); // enable element
}
}
};
};
Copy
Copied
Copy
Copied
$.ajaxPrefilter(function(options, originalOptions, xhr){
if (
!options.crossDomain ) {
rails
.CSRFProtection(xhr); }});
if (
rails.fire($(document), '
rails
:attachBindings')) {
Copy
Copied
Copy
Copied
$
(document).delegate(rails.linkDisableSelector, 'ajax:complete',
function(
) {
$
.ajaxPrefilter(
function(
options, originalOptions, xhr){ if ( !options.crossDomain ) {
rails.
CSRFProtection(xhr); }}
);
rails.
enableElement($(this));
}
);
Copy
Copied
Copy
Copied
$(document).delegate(rails.link
Click
Selector, '
click.rails
', function(
e
) {
$(document).delegate(rails.link
Disable
Selector, '
ajax:complete
', function(
) {
var link =
$(this)
, method = link.data('method'), data = link.data('params'
);
rails.enableElement(
$(this)
);
if (!rails.allowAction(link)) return rails.stopEverything(e
);
}
);
Copy
Copied
Copy
Copied
if (link.is
(rails.link
Disable
Selector
))
rails.
disableElement
(link)
;
$(document).delegate
(rails.link
Click
Selector
, 'click.rails', function(e) {
var link = $(this), method = link.data('method'), data = link.data('params');
if (!
rails.
allowAction
(link)
) return rails.stopEverything(e)
;
Copy
Copied
Copy
Copied
if (link.data('remote') !== undefined) {
if (link.is(rails.linkDisableSelector)) rails.disableElement(link);
if ( (e.metaKey || e.ctrlKey) && (!method || method === 'GET') && !data ) { return true; }
Copy
Copied
Copy
Copied
if (
rails.handleRemote(link) =
==
false
) {
rails.enableElement(link); }
if (
link.data('remote') !
==
undefined
) {
return
false;
if ( (e.metaKey || e.ctrlKey) && (!method || method === 'GET') && !data ) {
return
true; }
Copy
Copied
Copy
Copied
} else if
(link
.data('method')) {
var handleRemote = rails.handleRemote
(link
);
rails.
handleMethod
(link);
// response from
rails.
handleRemote() will either be false or a deferred object promise.
return false;
if (handleRemote === false) {
}
rails.enableElement
(link);
});
} else {
handleRemote.error( function() { rails.enableElement(link); } );
}
return false;
Copy
Copied
Copy
Copied
$(document).delegate(rails.inputChangeSelector, 'change.rails', function(e) {
} else if (link.data('method')) {
var link = $(this);
rails.
handleMethod
(link)
;
if (!
rails.
allowAction
(link)
)
return
rails.stopEverything(e
);
return
false;
}
}
);
Copy
Copied
Copy
Copied
rails.
handleRemote(
link
);
$(document).delegate(
rails.
inputChangeSelector, 'change.rails', function(e) {
return
false;
var
link
= $(this
);
}
);
if (!rails.allowAction(link))
return
rails.stopEverything(e
);
Copy
Copied
Copy
Copied
$(document).delegate(rails.formSubmitSelector, 'submit.rails', function(e) {
rails.handleRemote(link);
var form = $(this),
return false;
remote = form.data('remote') !== undefined,
});
blankRequiredInputs = rails.blankInputs(form, rails.requiredInputSelector),
nonBlankFileInputs = rails.nonBlankInputs(form, rails.fileInputSelector);
Copy
Copied
Copy
Copied
if (!rails.allowAction(form)) return rails.stopEverything(e);
$(document).delegate(rails.formSubmitSelector, 'submit.rails', function(e) {
var form = $(this),
remote = form.data('remote') !== undefined,
blankRequiredInputs = rails.blankInputs(form, rails.requiredInputSelector),
nonBlankFileInputs = rails.nonBlankInputs(form, rails.fileInputSelector);
Copy
Copied
Copy
Copied
// skip other logic when required values are missing or file upload is present
if (
!
rails.
allowAction
(form
))
return rails.stopEverything(e);
if (
blankRequiredInputs && form.attr("novalidate") == undefined &&
rails.
fire
(form
, 'ajax:aborted:required', [blankRequiredInputs])) {
return rails.stopEverything(e);
}
Copy
Copied
Copy
Copied
if (remote) {
// skip other logic when required values are missing or file upload is present
if (
nonBlankFileInputs) {
if (
blankRequiredInputs && form.attr("novalidate") == undefined &&
rails.fire(form, 'ajax:aborted:
required
', [
blankRequiredInputs])) {
return
rails.fire(form, 'ajax:aborted:
file
', [
nonBlankFileInputs])
;
return rails.stopEverything(e)
;
}
}
Copy
Copied
Copy
Copied
// If browser does not support submit bubbling, then this live-binding will be called before direct
if (remote) {
// bindings. Therefore, we should directly call any direct bindings before remotely submitting form.
if (nonBlankFileInputs) {
if (!$.support.submitBubbles && $().jquery < '1.7' && rails.callFormSubmitBindings(form, e) === false) return rails.stopEverything(e);
// slight timeout so that the submit button gets properly serialized
// (make it easy for event handler to serialize form without disabled values)
setTimeout(function(){ rails.disableFormElements(form); }, 13);
var aborted = rails.fire(form, 'ajax:aborted:file', [nonBlankFileInputs]);
Copy
Copied
Copy
Copied
rails.handleRemote(
form
);
// re-enable
form
elements if event bindings
return false
(canceling normal form submission)
return false
;
if (!aborted) { setTimeout(function(){ rails.enableFormElements(form); }, 13); }
Copy
Copied
Copy
Copied
} else {
return aborted;
// slight timeout so that the submit button gets properly serialized
}
setTimeout(function(){ rails.disableFormElements(form); }, 13);
}
}
);
Copy
Copied
Copy
Copied
$(document).delegate(rails.formInputClickSelector, 'click.rails', function(event) {
// If browser does not support submit bubbling, then this live-binding will be called before direct
var button = $(this);
// bindings. Therefore, we should directly call any direct bindings before remotely submitting form.
if (!$.support.submitBubbles && $().jquery < '1.7' && rails.callFormSubmitBindings(form, e) === false) return rails.stopEverything(e);
Copy
Copied
Copy
Copied
if (!
rails.
allowAction(button))
return
rails.stopEverything(event)
;
rails.
handleRemote(form);
return
false
;
Copy
Copied
Copy
Copied
//
register
the
pressed
submit button
} else {
var name = button.attr('name'),
//
slight timeout so that
the
submit button
gets properly serialized
data = name ? {name:name, value:button.val()} : null
;
setTimeout(function(){ rails.disableFormElements(form); }, 13);
}
})
;
Copy
Copied
Copy
Copied
button.closest('form').data('ujs:submit-button', data);
$(document).delegate(rails.formInputClickSelector, 'click.rails', function(event) {
});
var button = $(this);
Copy
Copied
Copy
Copied
$(document).delegate(rails.formSubmitSelector, 'ajax:beforeSend.rails', function(event) {
if (!rails.allowAction(button)) return rails.stopEverything(event);
if (this == event.target) rails.disableFormElements($(this));
});
Copy
Copied
Copy
Copied
$(document).delegate(rails.formSubmitSelector, 'ajax:complete.rails', function(event) {
// register the pressed submit button
if (this == event.target) rails.enableFormElements($(this));
var name = button.attr('name'),
});
data = name ? {name:name, value:button.val()} : null;
button.closest('form').data('ujs:submit-button', data);
});
$(document).delegate(rails.formSubmitSelector, 'ajax:beforeSend.rails', function(event) {
if (this == event.target) rails.disableFormElements($(this));
});
$(document).delegate(rails.formSubmitSelector, 'ajax:complete.rails', function(event) {
if (this == event.target) rails.enableFormElements($(this));
});
$(function(){
// making sure that all forms have actual up-to-date token(cached forms contain old one)
csrf_token = $('meta[name=csrf-token]').attr('content');
csrf_param = $('meta[name=csrf-param]').attr('content');
$('form input[name="' + csrf_param + '"]').val(csrf_token);
});
}
})( jQuery );
})( jQuery );
Saved diffs
Original text
Open file
(function($, undefined) { /** * Unobtrusive scripting adapter for jQuery * * Requires jQuery 1.6.0 or later. * https://github.com/rails/jquery-ujs * Uploading file using rails.js * ============================= * * By default, browsers do not allow files to be uploaded via AJAX. As a result, if there are any non-blank file fields * in the remote form, this adapter aborts the AJAX submission and allows the form to submit through standard means. * * The `ajax:aborted:file` event allows you to bind your own handler to process the form submission however you wish. * * Ex: * $('form').live('ajax:aborted:file', function(event, elements){ * // Implement own remote file-transfer handler here for non-blank file inputs passed in `elements`. * // Returning false in this handler tells rails.js to disallow standard form submission * return false; * }); * * The `ajax:aborted:file` event is fired when a file-type input is detected with a non-blank value. * * Third-party tools can use this hook to detect when an AJAX file upload is attempted, and then use * techniques like the iframe method to upload the file instead. * * Required fields in rails.js * =========================== * * If any blank required inputs (required="required") are detected in the remote form, the whole form submission * is canceled. Note that this is unlike file inputs, which still allow standard (non-AJAX) form submission. * * The `ajax:aborted:required` event allows you to bind your own handler to inform the user of blank required inputs. * * !! Note that Opera does not fire the form's submit event if there are blank required inputs, so this event may never * get fired in Opera. This event is what causes other browsers to exhibit the same submit-aborting behavior. * * Ex: * $('form').live('ajax:aborted:required', function(event, elements){ * // Returning false in this handler tells rails.js to submit the form anyway. * // The blank required inputs are passed to this function in `elements`. * return ! confirm("Would you like to submit the form with missing info?"); * }); */ // Shorthand to make it a little easier to call public rails functions from within rails.js var rails; $.rails = rails = { // Link elements bound by jquery-ujs linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote], a[data-disable-with]', // Select elements bound by jquery-ujs inputChangeSelector: 'select[data-remote], input[data-remote], textarea[data-remote]', // Form elements bound by jquery-ujs formSubmitSelector: 'form', // Form input elements bound by jquery-ujs formInputClickSelector: 'form input[type=submit], form input[type=image], form button[type=submit], form button:not(button[type])', // Form input elements disabled during form submission disableSelector: 'input[data-disable-with], button[data-disable-with], textarea[data-disable-with]', // Form input elements re-enabled after form submission enableSelector: 'input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled', // Form required input elements requiredInputSelector: 'input[name][required]:not([disabled]),textarea[name][required]:not([disabled])', // Form file input elements fileInputSelector: 'input:file', // Link onClick disable selector with possible reenable after remote submission linkDisableSelector: 'a[data-disable-with]', // Make sure that every Ajax request sends the CSRF token CSRFProtection: function(xhr) { var token = $('meta[name="csrf-token"]').attr('content'); if (token) xhr.setRequestHeader('X-CSRF-Token', token); }, // Triggers an event on an element and returns false if the event result is false fire: function(obj, name, data) { var event = $.Event(name); obj.trigger(event, data); return event.result !== false; }, // Default confirm dialog, may be overridden with custom confirm dialog in $.rails.confirm confirm: function(message) { return confirm(message); }, // Default ajax function, may be overridden with custom function in $.rails.ajax ajax: function(options) { return $.ajax(options); }, // Submits "remote" forms and links with ajax handleRemote: function(element) { var method, url, data, crossDomain = element.data('cross-domain') || null, dataType = element.data('type') || ($.ajaxSettings && $.ajaxSettings.dataType), options; if (rails.fire(element, 'ajax:before')) { if (element.is('form')) { method = element.attr('method'); url = element.attr('action'); data = element.serializeArray(); // memoized value from clicked submit button var button = element.data('ujs:submit-button'); if (button) { data.push(button); element.data('ujs:submit-button', null); } } else if (element.is(rails.inputChangeSelector)) { method = element.data('method'); url = element.data('url'); data = element.serialize(); if (element.data('params')) data = data + "&" + element.data('params'); } else { method = element.data('method'); url = element.attr('href'); data = element.data('params') || null; } options = { type: method || 'GET', data: data, dataType: dataType, crossDomain: crossDomain, // stopping the "ajax:beforeSend" event will cancel the ajax request beforeSend: function(xhr, settings) { if (settings.dataType === undefined) { xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script); } return rails.fire(element, 'ajax:beforeSend', [xhr, settings]); }, success: function(data, status, xhr) { element.trigger('ajax:success', [data, status, xhr]); }, complete: function(xhr, status) { element.trigger('ajax:complete', [xhr, status]); }, error: function(xhr, status, error) { element.trigger('ajax:error', [xhr, status, error]); } }; // Only pass url to `ajax` options if not blank if (url) { options.url = url; } return rails.ajax(options); } else { return false; } }, // Handles "data-method" on links such as: // <a href="/users/5" data-method="delete" rel="nofollow" data-confirm="Are you sure?">Delete</a> handleMethod: function(link) { var href = link.attr('href'), method = link.data('method'), target = link.attr('target'), csrf_token = $('meta[name=csrf-token]').attr('content'), csrf_param = $('meta[name=csrf-param]').attr('content'), form = $('<form method="post" action="' + href + '"></form>'), metadata_input = '<input name="_method" value="' + method + '" type="hidden" />'; if (csrf_param !== undefined && csrf_token !== undefined) { metadata_input += '<input name="' + csrf_param + '" value="' + csrf_token + '" type="hidden" />'; } if (target) { form.attr('target', target); } form.hide().append(metadata_input).appendTo('body'); form.submit(); }, /* Disables form elements: - Caches element value in 'ujs:enable-with' data store - Replaces element text with value of 'data-disable-with' attribute - Sets disabled property to true */ 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')); element.prop('disabled', true); }); }, /* Re-enables disabled form elements: - Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`) - Sets disabled property to false */ enableFormElements: function(form) { form.find(rails.enableSelector).each(function() { var element = $(this), method = element.is('button') ? 'html' : 'val'; if (element.data('ujs:enable-with')) element[method](element.data('ujs:enable-with')); element.prop('disabled', false); }); }, /* For 'data-confirm' attribute: - Fires `confirm` event - Shows the confirmation dialog - Fires the `confirm:complete` event Returns `true` if no function stops the chain and user chose yes; `false` otherwise. Attaching a handler to the element's `confirm` event that returns a `falsy` value cancels the confirmation dialog. Attaching a handler to the element's `confirm:complete` event that returns a `falsy` value makes this function return false. The `confirm:complete` event is fired whether or not the user answered true or false to the dialog. */ allowAction: function(element) { var message = element.data('confirm'), answer = false, callback; if (!message) { return true; } if (rails.fire(element, 'confirm')) { answer = rails.confirm(message); callback = rails.fire(element, 'confirm:complete', [answer]); } return answer && callback; }, // Helper function which checks for blank inputs in a form that match the specified CSS selector blankInputs: function(form, specifiedSelector, nonBlank) { var inputs = $(), input, selector = specifiedSelector || 'input,textarea'; form.find(selector).each(function() { input = $(this); // Collect non-blank inputs if nonBlank option is true, otherwise, collect blank inputs if (nonBlank ? input.val() : !input.val()) { inputs = inputs.add(input); } }); return inputs.length ? inputs : false; }, // Helper function which checks for non-blank inputs in a form that match the specified CSS selector nonBlankInputs: function(form, specifiedSelector) { return rails.blankInputs(form, specifiedSelector, true); // true specifies nonBlank }, // Helper function, needed to provide consistent behavior in IE stopEverything: function(e) { $(e.target).trigger('ujs:everythingStopped'); e.stopImmediatePropagation(); return false; }, // find all the submit events directly bound to the form and // manually invoke them. If anyone returns false then stop the loop callFormSubmitBindings: function(form, event) { 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(event); }); } return continuePropagation; }, // 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 element.bind('click.railsDisable', function(e) { // prevent further clicking return rails.stopEverything(e) }); }, // restore element to its original state which was disabled by 'disableElement' above enableElement: function(element) { if (element.data('ujs:enable-with') !== undefined) { element.html(element.data('ujs:enable-with')); // set to old enabled state // this should be element.removeData('ujs:enable-with') // but, there is currently a bug in jquery which makes hyphenated data attributes not get removed element.data('ujs:enable-with', false); // clean up cache } element.unbind('click.railsDisable'); // enable element } }; $.ajaxPrefilter(function(options, originalOptions, xhr){ if ( !options.crossDomain ) { rails.CSRFProtection(xhr); }}); $(document).delegate(rails.linkDisableSelector, 'ajax:complete', function() { rails.enableElement($(this)); }); $(document).delegate(rails.linkClickSelector, 'click.rails', function(e) { var link = $(this), method = link.data('method'), data = link.data('params'); if (!rails.allowAction(link)) return rails.stopEverything(e); if (link.is(rails.linkDisableSelector)) rails.disableElement(link); if (link.data('remote') !== undefined) { if ( (e.metaKey || e.ctrlKey) && (!method || method === 'GET') && !data ) { return true; } if (rails.handleRemote(link) === false) { rails.enableElement(link); } return false; } else if (link.data('method')) { rails.handleMethod(link); return false; } }); $(document).delegate(rails.inputChangeSelector, 'change.rails', function(e) { var link = $(this); if (!rails.allowAction(link)) return rails.stopEverything(e); rails.handleRemote(link); return false; }); $(document).delegate(rails.formSubmitSelector, 'submit.rails', function(e) { var form = $(this), remote = form.data('remote') !== undefined, blankRequiredInputs = rails.blankInputs(form, rails.requiredInputSelector), nonBlankFileInputs = rails.nonBlankInputs(form, rails.fileInputSelector); if (!rails.allowAction(form)) return rails.stopEverything(e); // skip other logic when required values are missing or file upload is present if (blankRequiredInputs && form.attr("novalidate") == undefined && rails.fire(form, 'ajax:aborted:required', [blankRequiredInputs])) { return rails.stopEverything(e); } if (remote) { if (nonBlankFileInputs) { return rails.fire(form, 'ajax:aborted:file', [nonBlankFileInputs]); } // 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 && $().jquery < '1.7' && rails.callFormSubmitBindings(form, e) === false) return rails.stopEverything(e); rails.handleRemote(form); return false; } else { // slight timeout so that the submit button gets properly serialized setTimeout(function(){ rails.disableFormElements(form); }, 13); } }); $(document).delegate(rails.formInputClickSelector, 'click.rails', function(event) { var button = $(this); if (!rails.allowAction(button)) return rails.stopEverything(event); // 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); }); $(document).delegate(rails.formSubmitSelector, 'ajax:beforeSend.rails', function(event) { if (this == event.target) rails.disableFormElements($(this)); }); $(document).delegate(rails.formSubmitSelector, 'ajax:complete.rails', function(event) { if (this == event.target) rails.enableFormElements($(this)); }); })( jQuery );
Changed text
Open file
(function($, undefined) { /** * Unobtrusive scripting adapter for jQuery * * Requires jQuery 1.6.0 or later. * https://github.com/rails/jquery-ujs * Uploading file using rails.js * ============================= * * By default, browsers do not allow files to be uploaded via AJAX. As a result, if there are any non-blank file fields * in the remote form, this adapter aborts the AJAX submission and allows the form to submit through standard means. * * The `ajax:aborted:file` event allows you to bind your own handler to process the form submission however you wish. * * Ex: * $('form').live('ajax:aborted:file', function(event, elements){ * // Implement own remote file-transfer handler here for non-blank file inputs passed in `elements`. * // Returning false in this handler tells rails.js to disallow standard form submission * return false; * }); * * The `ajax:aborted:file` event is fired when a file-type input is detected with a non-blank value. * * Third-party tools can use this hook to detect when an AJAX file upload is attempted, and then use * techniques like the iframe method to upload the file instead. * * Required fields in rails.js * =========================== * * If any blank required inputs (required="required") are detected in the remote form, the whole form submission * is canceled. Note that this is unlike file inputs, which still allow standard (non-AJAX) form submission. * * The `ajax:aborted:required` event allows you to bind your own handler to inform the user of blank required inputs. * * !! Note that Opera does not fire the form's submit event if there are blank required inputs, so this event may never * get fired in Opera. This event is what causes other browsers to exhibit the same submit-aborting behavior. * * Ex: * $('form').live('ajax:aborted:required', function(event, elements){ * // Returning false in this handler tells rails.js to submit the form anyway. * // The blank required inputs are passed to this function in `elements`. * return ! confirm("Would you like to submit the form with missing info?"); * }); */ // Cut down on the number if issues from people inadvertently including jquery_ujs twice // by detecting and raising an error when it happens. var alreadyInitialized = function() { var events = $._data(document, 'events'); return events && events.click && $.grep(events.click, function(e) { return e.namespace === 'rails'; }).length; } if ( alreadyInitialized() ) { $.error('jquery-ujs has already been loaded!'); } // Shorthand to make it a little easier to call public rails functions from within rails.js var rails; $.rails = rails = { // Link elements bound by jquery-ujs linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote], a[data-disable-with]', // Select elements bound by jquery-ujs inputChangeSelector: 'select[data-remote], input[data-remote], textarea[data-remote]', // Form elements bound by jquery-ujs formSubmitSelector: 'form', // Form input elements bound by jquery-ujs 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]', // Form input elements re-enabled after form submission enableSelector: 'input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled', // Form required input elements requiredInputSelector: 'input[name][required]:not([disabled]),textarea[name][required]:not([disabled])', // Form file input elements fileInputSelector: 'input:file', // Link onClick disable selector with possible reenable after remote submission linkDisableSelector: 'a[data-disable-with]', // Make sure that every Ajax request sends the CSRF token CSRFProtection: function(xhr) { var token = $('meta[name="csrf-token"]').attr('content'); if (token) xhr.setRequestHeader('X-CSRF-Token', token); }, // Triggers an event on an element and returns false if the event result is false fire: function(obj, name, data) { var event = $.Event(name); obj.trigger(event, data); return event.result !== false; }, // Default confirm dialog, may be overridden with custom confirm dialog in $.rails.confirm confirm: function(message) { return confirm(message); }, // Default ajax function, may be overridden with custom function in $.rails.ajax ajax: function(options) { return $.ajax(options); }, // Default way to get an element's href. May be overridden at $.rails.href. href: function(element) { return element.attr('href'); }, // Submits "remote" forms and links with ajax handleRemote: function(element) { var method, url, data, elCrossDomain, crossDomain, withCredentials, dataType, options; if (rails.fire(element, 'ajax:before')) { elCrossDomain = element.data('cross-domain'); crossDomain = elCrossDomain === undefined ? null : elCrossDomain; withCredentials = element.data('with-credentials') || null; dataType = element.data('type') || ($.ajaxSettings && $.ajaxSettings.dataType); if (element.is('form')) { method = element.attr('method'); url = element.attr('action'); data = element.serializeArray(); // memoized value from clicked submit button var button = element.data('ujs:submit-button'); if (button) { data.push(button); element.data('ujs:submit-button', null); } } else if (element.is(rails.inputChangeSelector)) { method = element.data('method'); 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); data = element.data('params') || null; } options = { type: method || 'GET', data: data, dataType: dataType, // stopping the "ajax:beforeSend" event will cancel the ajax request beforeSend: function(xhr, settings) { if (settings.dataType === undefined) { xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script); } return rails.fire(element, 'ajax:beforeSend', [xhr, settings]); }, success: function(data, status, xhr) { element.trigger('ajax:success', [data, status, xhr]); }, complete: function(xhr, status) { element.trigger('ajax:complete', [xhr, status]); }, error: function(xhr, status, error) { element.trigger('ajax:error', [xhr, status, error]); }, xhrFields: { withCredentials: withCredentials }, crossDomain: crossDomain }; // 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; } else { return false; } }, // Handles "data-method" on links such as: // <a href="/users/5" data-method="delete" rel="nofollow" data-confirm="Are you sure?">Delete</a> handleMethod: function(link) { var href = rails.href(link), method = link.data('method'), target = link.attr('target'), csrf_token = $('meta[name=csrf-token]').attr('content'), csrf_param = $('meta[name=csrf-param]').attr('content'), form = $('<form method="post" action="' + href + '"></form>'), metadata_input = '<input name="_method" value="' + method + '" type="hidden" />'; if (csrf_param !== undefined && csrf_token !== undefined) { metadata_input += '<input name="' + csrf_param + '" value="' + csrf_token + '" type="hidden" />'; } if (target) { form.attr('target', target); } form.hide().append(metadata_input).appendTo('body'); form.submit(); }, /* Disables form elements: - Caches element value in 'ujs:enable-with' data store - Replaces element text with value of 'data-disable-with' attribute - Sets disabled property to true */ 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')); element.prop('disabled', true); }); }, /* Re-enables disabled form elements: - Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`) - Sets disabled property to false */ enableFormElements: function(form) { form.find(rails.enableSelector).each(function() { var element = $(this), method = element.is('button') ? 'html' : 'val'; if (element.data('ujs:enable-with')) element[method](element.data('ujs:enable-with')); element.prop('disabled', false); }); }, /* For 'data-confirm' attribute: - Fires `confirm` event - Shows the confirmation dialog - Fires the `confirm:complete` event Returns `true` if no function stops the chain and user chose yes; `false` otherwise. Attaching a handler to the element's `confirm` event that returns a `falsy` value cancels the confirmation dialog. Attaching a handler to the element's `confirm:complete` event that returns a `falsy` value makes this function return false. The `confirm:complete` event is fired whether or not the user answered true or false to the dialog. */ allowAction: function(element) { var message = element.data('confirm'), answer = false, callback; if (!message) { return true; } if (rails.fire(element, 'confirm')) { answer = rails.confirm(message); callback = rails.fire(element, 'confirm:complete', [answer]); } return answer && callback; }, // Helper function which checks for blank inputs in a form that match the specified CSS selector blankInputs: function(form, specifiedSelector, nonBlank) { var inputs = $(), input, valueToCheck, selector = specifiedSelector || 'input,textarea', allInputs = form.find(selector); allInputs.each(function() { input = $(this); valueToCheck = input.is(':checkbox,:radio') ? input.is(':checked') : input.val(); // If nonBlank and valueToCheck are both truthy, or nonBlank and valueToCheck are both falsey if (!valueToCheck === !nonBlank) { // Don't count unchecked required radio if other radio with same name is checked if (input.is(':radio') && allInputs.filter('input:radio:checked[name="' + input.attr('name') + '"]').length) { return true; // Skip to next input } inputs = inputs.add(input); } }); return inputs.length ? inputs : false; }, // Helper function which checks for non-blank inputs in a form that match the specified CSS selector nonBlankInputs: function(form, specifiedSelector) { return rails.blankInputs(form, specifiedSelector, true); // true specifies nonBlank }, // Helper function, needed to provide consistent behavior in IE stopEverything: function(e) { $(e.target).trigger('ujs:everythingStopped'); e.stopImmediatePropagation(); return false; }, // find all the submit events directly bound to the form and // manually invoke them. If anyone returns false then stop the loop callFormSubmitBindings: function(form, event) { 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(event); }); } return continuePropagation; }, // 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 element.bind('click.railsDisable', function(e) { // prevent further clicking return rails.stopEverything(e); }); }, // restore element to its original state which was disabled by 'disableElement' above enableElement: function(element) { if (element.data('ujs:enable-with') !== undefined) { element.html(element.data('ujs:enable-with')); // set to old enabled state // this should be element.removeData('ujs:enable-with') // but, there is currently a bug in jquery which makes hyphenated data attributes not get removed element.data('ujs:enable-with', false); // clean up cache } element.unbind('click.railsDisable'); // enable element } }; if (rails.fire($(document), 'rails:attachBindings')) { $.ajaxPrefilter(function(options, originalOptions, xhr){ if ( !options.crossDomain ) { rails.CSRFProtection(xhr); }}); $(document).delegate(rails.linkDisableSelector, 'ajax:complete', function() { rails.enableElement($(this)); }); $(document).delegate(rails.linkClickSelector, 'click.rails', function(e) { var link = $(this), method = link.data('method'), data = link.data('params'); if (!rails.allowAction(link)) return rails.stopEverything(e); if (link.is(rails.linkDisableSelector)) rails.disableElement(link); if (link.data('remote') !== undefined) { if ( (e.metaKey || e.ctrlKey) && (!method || method === 'GET') && !data ) { return true; } var handleRemote = rails.handleRemote(link); // response from rails.handleRemote() will either be false or a deferred object promise. if (handleRemote === false) { rails.enableElement(link); } else { handleRemote.error( function() { rails.enableElement(link); } ); } return false; } else if (link.data('method')) { rails.handleMethod(link); return false; } }); $(document).delegate(rails.inputChangeSelector, 'change.rails', function(e) { var link = $(this); if (!rails.allowAction(link)) return rails.stopEverything(e); rails.handleRemote(link); return false; }); $(document).delegate(rails.formSubmitSelector, 'submit.rails', function(e) { var form = $(this), remote = form.data('remote') !== undefined, blankRequiredInputs = rails.blankInputs(form, rails.requiredInputSelector), nonBlankFileInputs = rails.nonBlankInputs(form, rails.fileInputSelector); if (!rails.allowAction(form)) return rails.stopEverything(e); // skip other logic when required values are missing or file upload is present if (blankRequiredInputs && form.attr("novalidate") == undefined && rails.fire(form, 'ajax:aborted:required', [blankRequiredInputs])) { return rails.stopEverything(e); } if (remote) { if (nonBlankFileInputs) { // slight timeout so that the submit button gets properly serialized // (make it easy for event handler to serialize form without disabled values) setTimeout(function(){ rails.disableFormElements(form); }, 13); var aborted = rails.fire(form, 'ajax:aborted:file', [nonBlankFileInputs]); // re-enable form elements if event bindings return false (canceling normal form submission) if (!aborted) { setTimeout(function(){ rails.enableFormElements(form); }, 13); } return aborted; } // 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 && $().jquery < '1.7' && rails.callFormSubmitBindings(form, e) === false) return rails.stopEverything(e); rails.handleRemote(form); return false; } else { // slight timeout so that the submit button gets properly serialized setTimeout(function(){ rails.disableFormElements(form); }, 13); } }); $(document).delegate(rails.formInputClickSelector, 'click.rails', function(event) { var button = $(this); if (!rails.allowAction(button)) return rails.stopEverything(event); // 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); }); $(document).delegate(rails.formSubmitSelector, 'ajax:beforeSend.rails', function(event) { if (this == event.target) rails.disableFormElements($(this)); }); $(document).delegate(rails.formSubmitSelector, 'ajax:complete.rails', function(event) { if (this == event.target) rails.enableFormElements($(this)); }); $(function(){ // making sure that all forms have actual up-to-date token(cached forms contain old one) csrf_token = $('meta[name=csrf-token]').attr('content'); csrf_param = $('meta[name=csrf-param]').attr('content'); $('form input[name="' + csrf_param + '"]').val(csrf_token); }); } })( jQuery );
Find difference