I have a simple form that shows/hides different field sets based on the selection of a select menu. This is using the scenario described in the Symfony docs here.
I am in the process of stripping jQuery from this site in favor of vanilla javascript, so I'm attempting to convert the AJAX script that sends the form data after the select changes to either XMLHttpRequest of Fetch API. However when doing so the Form's PreSubmit or PostSubmit events don't fire as they do when using the Ajax request.
At first I thought maybe the request headers were different and in some cases they were, so I made sure on the Fetch API version to exactly match mirror the Ajax request headers, and still the events do not fire. Only the PreSetData event fires.
This is the original AJAX
let $ptoType = $("#pto_type");
$ptoType.off('change').on('change', function () {
let $form = $(this).closest('form');
let data = {};
data[$ptoType.attr('name')] = $ptoType.val();
$.ajax({
url: $form.attr('action'),
type: $form.attr('method'),
data: data,
success: function (html) {
$('#formStep2').replaceWith(
$(html).find('#formStep2')
);
}
});
});
This is the attempt at the XMLHttpRequest
let ptoType = document.getElementById("pto_type");
ptoType.addEventListener('change', function () {
let xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState === XMLHttpRequest.DONE) {
if (xmlHttp.status === 200) {
document.getElementById("formStep2").innerHTML = xmlHttp.response.getElementById('formStep2').innerHTML;
} else if (xmlHttp.status === 400) {
alert('There was an error 400');
} else {
alert('something else other than 200 was returned');
}
}
};
xmlHttp.open(form.getAttribute('method'), form.getAttribute('action'), true);
xmlHttp.responseType = "document";
xmlHttp.setRequestHeader("X-Requested-With", "XMLHttpRequest")
xmlHttp.send(data);
});
And this is the attempt with the Fetch API
let ptoType = document.getElementById("pto_type");
ptoType.addEventListener('change', function () {
let form = document.getElementById('form_pto_entry');
const formData = new FormData();
formData.append('type', ptoType.options[ptoType.selectedIndex].text);
fetch(form.getAttribute('action'), {
method: form.getAttribute('method'),
headers: new Headers({'content-type': 'application/x-www-form-urlencoded; charset=UTF-8','x-requested-with': 'XMLHttpRequest'}),
body: formData,
})
.then(response => response.text())
.then((body) => {
let bodyHtml = ConvertStringToHTML(body);
document.getElementById("formStep2").innerHTML = bodyHtml.querySelector('#formStep2').innerHTML;
})
.catch((error) => {
console.error('Error:', error);
});
});
let ConvertStringToHTML = function (str) {
let parser = new DOMParser();
let doc = parser.parseFromString(str, 'text/html');
return doc.body;
};
So watching the Network tab in the dev tools and doing a little debugging, the headers sent in the Fetch API version match the headers sent in the Ajax version, however the pre submit data event just never fires.