Symfony form events not firing when AJAX request converted to vanilla Javascript

Viewed 39

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.

1 Answers

Based on the doc link you posted, I assumed that you are in symfony 6.1.

You can check the symfony UX component dedicated to this this may fix your problem in no time without any JS configuration. = Symfony UX Dependent form fields doc

Related