Files
pjax/lib/proto/attach-form.js

140 lines
3.5 KiB
JavaScript
Raw Permalink Normal View History

2019-03-03 01:37:45 -05:00
var on = require("../events/on");
var clone = require("../util/clone");
2019-03-03 01:37:45 -05:00
var attrState = "data-pjax-state";
2018-01-09 00:44:20 -05:00
var formAction = function(el, event) {
if (isDefaultPrevented(event)) {
2019-03-03 01:37:45 -05:00
return;
}
// Since loadUrl modifies options and we may add our own modifications below,
// clone it so the changes don't persist
2019-03-03 01:37:45 -05:00
var options = clone(this.options);
// Initialize requestOptions
options.requestOptions = {
2018-01-09 00:44:20 -05:00
requestUrl: el.getAttribute("action") || window.location.href,
requestMethod: el.getAttribute("method") || "GET"
2019-03-03 01:37:45 -05:00
};
2018-01-09 00:44:20 -05:00
// create a testable virtual link of the form action
2019-03-03 01:37:45 -05:00
var virtLinkElement = document.createElement("a");
virtLinkElement.setAttribute("href", options.requestOptions.requestUrl);
2019-03-03 01:37:45 -05:00
var attrValue = checkIfShouldAbort(virtLinkElement, options);
if (attrValue) {
2019-03-03 01:37:45 -05:00
el.setAttribute(attrState, attrValue);
return;
}
2019-03-03 01:37:45 -05:00
event.preventDefault();
if (el.enctype === "multipart/form-data") {
2019-03-03 01:37:45 -05:00
options.requestOptions.formData = new FormData(el);
} else {
options.requestOptions.requestParams = parseFormElements(el);
}
2019-03-03 01:37:45 -05:00
el.setAttribute(attrState, "submit");
2019-03-03 01:37:45 -05:00
options.triggerElement = el;
this.loadUrl(virtLinkElement.href, options);
};
function parseFormElements(el) {
2019-03-03 01:37:45 -05:00
var requestParams = [];
var formElements = el.elements;
for (var i = 0; i < formElements.length; i++) {
2019-03-03 01:37:45 -05:00
var element = formElements[i];
var tagName = element.tagName.toLowerCase();
2018-01-09 00:44:20 -05:00
// jscs:disable disallowImplicitTypeConversion
2019-03-03 01:37:45 -05:00
if (
!!element.name &&
element.attributes !== undefined &&
tagName !== "button"
) {
2018-01-09 00:44:20 -05:00
// jscs:enable disallowImplicitTypeConversion
2019-03-03 01:37:45 -05:00
var type = element.attributes.type;
2019-03-03 01:37:45 -05:00
if (
!type ||
(type.value !== "checkbox" && type.value !== "radio") ||
element.checked
) {
// Build array of values to submit
2019-03-03 01:37:45 -05:00
var values = [];
if (tagName === "select") {
2019-03-03 01:37:45 -05:00
var opt;
for (var j = 0; j < element.options.length; j++) {
2019-03-03 01:37:45 -05:00
opt = element.options[j];
if (opt.selected && !opt.disabled) {
2019-03-03 01:37:45 -05:00
values.push(opt.hasAttribute("value") ? opt.value : opt.text);
}
}
2019-03-03 01:37:45 -05:00
} else {
values.push(element.value);
}
for (var k = 0; k < values.length; k++) {
requestParams.push({
name: encodeURIComponent(element.name),
value: encodeURIComponent(values[k])
2019-03-03 01:37:45 -05:00
});
}
}
}
}
2019-03-03 01:37:45 -05:00
return requestParams;
}
function checkIfShouldAbort(virtLinkElement, options) {
// Ignore external links.
2019-03-03 01:37:45 -05:00
if (
virtLinkElement.protocol !== window.location.protocol ||
virtLinkElement.host !== window.location.host
) {
return "external";
}
// Ignore click if we are on an anchor on the same page
2019-03-03 01:37:45 -05:00
if (
virtLinkElement.hash &&
virtLinkElement.href.replace(virtLinkElement.hash, "") ===
window.location.href.replace(location.hash, "")
) {
return "anchor";
}
// Ignore empty anchor "foo.html#"
if (virtLinkElement.href === window.location.href.split("#")[0] + "#") {
2019-03-03 01:37:45 -05:00
return "anchor-empty";
}
// if declared as a full reload, just normally submit the form
2019-03-03 01:37:45 -05:00
if (
options.currentUrlFullReload &&
virtLinkElement.href === window.location.href.split("#")[0]
) {
return "reload";
}
}
var isDefaultPrevented = function(event) {
2019-03-03 01:37:45 -05:00
return event.defaultPrevented || event.returnValue === false;
};
module.exports = function(el) {
2019-03-03 01:37:45 -05:00
var that = this;
2019-03-03 01:37:45 -05:00
el.setAttribute(attrState, "");
on(el, "submit", function(event) {
2019-03-03 01:37:45 -05:00
formAction.call(that, el, event);
});
};