diff --git a/lib/proto/attach-form.js b/lib/proto/attach-form.js index 0dbab38..d194d81 100644 --- a/lib/proto/attach-form.js +++ b/lib/proto/attach-form.js @@ -31,6 +31,22 @@ var formAction = function(el, event) { event.preventDefault() + if (el.enctype === "multipart/form-data") { + options.requestOptions.formData = new FormData(el) + } + else { + options.requestOptions.requestParams = parseFormElements(el) + } + + el.setAttribute(attrState, "submit") + + options.triggerElement = el + this.loadUrl(virtLinkElement.href, options) +} + +function parseFormElements(el) { + var requestParams = [] + for (var elementKey in el.elements) { if (Number.isNaN(Number(elementKey))) { continue; @@ -62,7 +78,7 @@ var formAction = function(el, event) { } for (var j = 0; j < values.length; j++) { - options.requestOptions.requestParams.push({ + requestParams.push({ name: encodeURIComponent(element.name), value: encodeURIComponent(values[j]) }) @@ -71,10 +87,7 @@ var formAction = function(el, event) { } } - el.setAttribute(attrState, "submit") - - options.triggerElement = el - this.loadUrl(virtLinkElement.href, options) + return requestParams } function checkIfShouldAbort(virtLinkElement, options) { diff --git a/lib/send-request.js b/lib/send-request.js index 5f74d5f..c7e5a6a 100644 --- a/lib/send-request.js +++ b/lib/send-request.js @@ -51,6 +51,9 @@ module.exports = function(location, options, callback) { break } } + else if (requestOptions.formData) { + requestPayload = requestOptions.formData + } // Add a timestamp as part of the query string if cache busting is enabled if (options.cacheBust) { diff --git a/tests/lib/proto/attach-form.js b/tests/lib/proto/attach-form.js index 865e993..73de36e 100644 --- a/tests/lib/proto/attach-form.js +++ b/tests/lib/proto/attach-form.js @@ -152,3 +152,33 @@ tape("test form elements parsed correctly", function(t) { t.end() }) + +tape("test form.enctype=\"multipart/form-data\"", function(t) { + t.plan(4) + + var form = document.createElement("form") + form.enctype = "multipart/form-data" + var input = document.createElement("input") + input.name = "input" + input.value = "value" + form.appendChild(input) + + var pjax = { + options: {}, + loadUrl: function(href, options) { + t.equals(options.requestOptions.requestParams.length, 0, "form elements not parsed manually") + t.true(options.requestOptions.formData instanceof FormData, "requestOptions.formData is a FormData") + t.equals(Array.from(options.requestOptions.formData.entries()).length, 1, "correct number of FormData elements") + t.equals(options.requestOptions.formData.get("input"), "value", "FormData element value set correctly") + } + } + + attachForm.call(pjax, form) + + form.action = window.location.protocol + "//" + window.location.host + "/internal" + + trigger(form, "submit") + // see loadUrl defined above + + t.end() +})