Skip to content

Commit

Permalink
Add the option to use FormData to encode the form elements (#153)
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
BehindTheMath committed Apr 29, 2018
1 parent 7d26a75 commit e49d894
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 7 deletions.
1 change: 1 addition & 0 deletions index.d.ts
Expand Up @@ -177,6 +177,7 @@ declare namespace Pjax {
requestUrl?: string;
requestMethod?: string;
requestParams?: IRequestParams[];
formData?: FormData;
}
}

Expand Down
26 changes: 19 additions & 7 deletions lib/proto/attach-form.js
Expand Up @@ -15,8 +15,7 @@ var formAction = function(el, event) {
// Initialize requestOptions
options.requestOptions = {
requestUrl: el.getAttribute("action") || window.location.href,
requestMethod: el.getAttribute("method") || "GET",
requestParams: []
requestMethod: el.getAttribute("method") || "GET"
}

// create a testable virtual link of the form action
Expand All @@ -31,6 +30,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;
Expand Down Expand Up @@ -62,7 +77,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])
})
Expand All @@ -71,10 +86,7 @@ var formAction = function(el, event) {
}
}

el.setAttribute(attrState, "submit")

options.triggerElement = el
this.loadUrl(virtLinkElement.href, options)
return requestParams
}

function checkIfShouldAbort(virtLinkElement, options) {
Expand Down
4 changes: 4 additions & 0 deletions lib/send-request.js
Expand Up @@ -6,6 +6,7 @@ module.exports = function(location, options, callback) {
var requestOptions = options.requestOptions || {}
var requestMethod = (requestOptions.requestMethod || "GET").toUpperCase()
var requestParams = requestOptions.requestParams || null
var formData = requestOptions.formData || null;
var requestPayload = null
var request = new XMLHttpRequest()
var timeout = options.timeout || 0
Expand Down Expand Up @@ -51,6 +52,9 @@ module.exports = function(location, options, callback) {
break
}
}
else if (formData) {
requestPayload = formData
}

// Add a timestamp as part of the query string if cache busting is enabled
if (options.cacheBust) {
Expand Down
30 changes: 30 additions & 0 deletions tests/lib/proto/attach-form.js
Expand Up @@ -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, 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()
})

0 comments on commit e49d894

Please sign in to comment.