Skip to content

Instantly share code, notes, and snippets.

@orlando
Last active July 25, 2016 04:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save orlando/bacff31757b80b86e062 to your computer and use it in GitHub Desktop.
Save orlando/bacff31757b80b86e062 to your computer and use it in GitHub Desktop.
Rails jquery-ujs Safari UI locking workaround
// Safari blocks the UI as soon as a form is submitted
// This behaviour prevents us from doing animations inside buttons
// This is a workaround to give the render engine some time before blocking
// This depends on jQuery browser to know if the current browser is Safari
// We happened to have that dependency when I implemeneted this workaround
$(function () {
if (!$.browser.safari) {
return;
}
var formHandler = function (e) {
var rails = $.rails;
var form = $(this),
remote = form.data('remote') !== undefined,
blankRequiredInputs,
nonBlankFileInputs;
if (!rails.allowAction(form)) return rails.stopEverything(e);
// skip other logic when required values are missing or file upload is present
if (form.attr('novalidate') == undefined) {
blankRequiredInputs = rails.blankInputs(form, rails.requiredInputSelector);
if (blankRequiredInputs && rails.fire(form, 'ajax:aborted:required', [blankRequiredInputs])) {
return rails.stopEverything(e);
}
}
if (remote) {
nonBlankFileInputs = rails.nonBlankInputs(form, rails.fileInputSelector);
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;
}
rails.handleRemote(form);
return false;
} else {
if (!e.isTrigger) {
e.preventDefault();
rails.disableFormElements(form);
setTimeout(function(){ form.trigger('submit'); }, 13);
}
}
};
$(document).undelegate('form', 'submit.rails');
$(document).delegate('form', 'submit.rails', formHandler);
});
@sebabouche
Copy link

As $.browser.safari is deprecated, can can change it for navigator.vendor.indexOf("Apple")==0 && /\sSafari\//.test(navigator.userAgent)

@orlando
Copy link
Author

orlando commented Jul 22, 2016

thanks for that input @sebabouche

@thanhtuong
Copy link

Hi @orlando. How about if the form is using Ajax to submit? It will trigger twice! Could you please have the solution for this case?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment