Add the option to use FormData to encode the form elements (#153)

* Add the option to use FormData to encode the form elements

If the form's enctype attribute is set to "multipart/form-data",
use FormData to encode the form's elements.
This commit was merged in pull request #153.
This commit is contained in:
BehindTheMath
2018-04-29 15:05:22 -04:00
committed by GitHub
parent 7d26a75fdf
commit e49d8947f7
4 changed files with 54 additions and 7 deletions

1
index.d.ts vendored
View File

@@ -177,6 +177,7 @@ declare namespace Pjax {
requestUrl?: string; requestUrl?: string;
requestMethod?: string; requestMethod?: string;
requestParams?: IRequestParams[]; requestParams?: IRequestParams[];
formData?: FormData;
} }
} }

View File

@@ -15,8 +15,7 @@ var formAction = function(el, event) {
// Initialize requestOptions // Initialize requestOptions
options.requestOptions = { options.requestOptions = {
requestUrl: el.getAttribute("action") || window.location.href, requestUrl: el.getAttribute("action") || window.location.href,
requestMethod: el.getAttribute("method") || "GET", requestMethod: el.getAttribute("method") || "GET"
requestParams: []
} }
// create a testable virtual link of the form action // create a testable virtual link of the form action
@@ -31,6 +30,22 @@ var formAction = function(el, event) {
event.preventDefault() 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) { for (var elementKey in el.elements) {
if (Number.isNaN(Number(elementKey))) { if (Number.isNaN(Number(elementKey))) {
continue; continue;
@@ -62,7 +77,7 @@ var formAction = function(el, event) {
} }
for (var j = 0; j < values.length; j++) { for (var j = 0; j < values.length; j++) {
options.requestOptions.requestParams.push({ requestParams.push({
name: encodeURIComponent(element.name), name: encodeURIComponent(element.name),
value: encodeURIComponent(values[j]) value: encodeURIComponent(values[j])
}) })
@@ -71,10 +86,7 @@ var formAction = function(el, event) {
} }
} }
el.setAttribute(attrState, "submit") return requestParams
options.triggerElement = el
this.loadUrl(virtLinkElement.href, options)
} }
function checkIfShouldAbort(virtLinkElement, options) { function checkIfShouldAbort(virtLinkElement, options) {

View File

@@ -6,6 +6,7 @@ module.exports = function(location, options, callback) {
var requestOptions = options.requestOptions || {} var requestOptions = options.requestOptions || {}
var requestMethod = (requestOptions.requestMethod || "GET").toUpperCase() var requestMethod = (requestOptions.requestMethod || "GET").toUpperCase()
var requestParams = requestOptions.requestParams || null var requestParams = requestOptions.requestParams || null
var formData = requestOptions.formData || null;
var requestPayload = null var requestPayload = null
var request = new XMLHttpRequest() var request = new XMLHttpRequest()
var timeout = options.timeout || 0 var timeout = options.timeout || 0
@@ -51,6 +52,9 @@ module.exports = function(location, options, callback) {
break break
} }
} }
else if (formData) {
requestPayload = formData
}
// Add a timestamp as part of the query string if cache busting is enabled // Add a timestamp as part of the query string if cache busting is enabled
if (options.cacheBust) { if (options.cacheBust) {

View File

@@ -152,3 +152,33 @@ tape("test form elements parsed correctly", function(t) {
t.end() 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, undefined, "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()
})