From aafbf25d88d2c526e9296e10990687c805f4d776 Mon Sep 17 00:00:00 2001 From: Tortue Torche Date: Wed, 23 Aug 2017 10:54:30 +0200 Subject: [PATCH 1/2] File upload support with FormData object Borrowed from: https://gist.github.com/zakcrawford/b05b1399208fcb257ff9 See: https://github.com/rails/jquery-ujs/issues/374 --- src/rails.js | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/rails.js b/src/rails.js index 7eee3906..1b10e36e 100644 --- a/src/rails.js +++ b/src/rails.js @@ -115,7 +115,13 @@ if (element.is('form')) { method = element.data('ujs:submit-button-formmethod') || element.attr('method'); url = element.data('ujs:submit-button-formaction') || element.attr('action'); - data = $(element[0]).serializeArray(); + if (typeof window.FormData !== 'undefined' && element.find(rails.fileInputSelector).length) { + data = new FormData(element[0]); + var contentType = false; + var processData = false; + } else { + data = $(element[0]).serializeArray(); + } // memoized value from clicked submit button var button = element.data('ujs:submit-button'); if (button) { @@ -124,6 +130,15 @@ } element.data('ujs:submit-button-formmethod', null); element.data('ujs:submit-button-formaction', null); + } else if (typeof window.FormData !== 'undefined' && element.is(rails.fileInputSelector)) { + method = element.data('method') || 'get'; + url = element.data('url'); + var formData = new FormData(); + formData.append(element.attr('name'), element[0].files[0]); + formData.append(rails.csrfParam(), $('input[name="' + rails.csrfParam() + '"]').val()); + data = formData; + var contentType = false; + var processData = false; } else if (element.is(rails.inputChangeSelector)) { method = element.data('method'); url = element.data('url'); @@ -165,6 +180,13 @@ crossDomain: rails.isCrossDomain(url) }; + if (typeof contentType !== "undefined" && contentType !== null) { + options.contentType = contentType; + } + if (typeof processData !== "undefined" && processData !== null) { + options.processData = processData; + } + // There is no withCredentials for IE6-8 when // "Enable native XMLHTTP support" is disabled if (withCredentials) { @@ -496,8 +518,9 @@ } if (remote) { + // Disable this feature for modern web browsers nonBlankFileInputs = rails.nonBlankInputs(form, rails.fileInputSelector); - if (nonBlankFileInputs) { + if (typeof window.FormData === 'undefined' && 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); From 32361f14b60e4fbe04945c8dd1633835f1e2670c Mon Sep 17 00:00:00 2001 From: Tortue Torche Date: Wed, 23 Aug 2017 11:16:37 +0200 Subject: [PATCH 2/2] Fix JS coding style --- src/rails.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/rails.js b/src/rails.js index 1b10e36e..50f8a405 100644 --- a/src/rails.js +++ b/src/rails.js @@ -106,7 +106,7 @@ // Submits "remote" forms and links with ajax handleRemote: function(element) { - var method, url, data, withCredentials, dataType, options; + var method, url, data, withCredentials, dataType, options, contentType, processData; if (rails.fire(element, 'ajax:before')) { withCredentials = element.data('with-credentials') || null; @@ -117,8 +117,8 @@ url = element.data('ujs:submit-button-formaction') || element.attr('action'); if (typeof window.FormData !== 'undefined' && element.find(rails.fileInputSelector).length) { data = new FormData(element[0]); - var contentType = false; - var processData = false; + contentType = false; + processData = false; } else { data = $(element[0]).serializeArray(); } @@ -137,8 +137,8 @@ formData.append(element.attr('name'), element[0].files[0]); formData.append(rails.csrfParam(), $('input[name="' + rails.csrfParam() + '"]').val()); data = formData; - var contentType = false; - var processData = false; + contentType = false; + processData = false; } else if (element.is(rails.inputChangeSelector)) { method = element.data('method'); url = element.data('url'); @@ -180,10 +180,10 @@ crossDomain: rails.isCrossDomain(url) }; - if (typeof contentType !== "undefined" && contentType !== null) { + if (contentType !== null) { options.contentType = contentType; } - if (typeof processData !== "undefined" && processData !== null) { + if (processData !== null) { options.processData = processData; }