javascriptajaxformsform-dataxmlhttprequest-level2

How to know which <input> is submited when several ones are defined within a <form>?


I want to implement the below simple JavaScript function submitForm() based on XMLHttpRequest and FormData. This functions works well on the first <form> but fails on the second one: the function should use input.formaction instead of form.action.

How to detect the pressed <input> and retrieve the corresponding formaction?

( Most of SO answers advise to use a framework (as jquery) for such processing. But I think learning solely pure JavaScript is easier than learning also JS frameworks. If you are convinced that this snippet can be written simpler using a framework, please propose your version. Please explain also why your advised framework is pertinent/relevant/suitable in this case. I may decide to learn your favorite JS framework... EDIT: I have found this similar question: JQuery get formaction and formmethod )

<!DOCTYPE html>
<html>

<head>
<script>
function submitForm(form)
{
  var xhr = new XMLHttpRequest();
  xhr.onload = function() { alert (xhr.responseText); }
  xhr.open ("post", form.action, true);
  xhr.send (new FormData (form));
  return false;
}
</script>
</head>

<body>
<form action="first.php" onsubmit="submitForm(this);">
   <fieldset>
      <legend>First</legend>
      <input type="text" name="data" />
      <input type="submit"  />
   </fieldset>
</form>

<form onsubmit="submitForm(this);">
   <fieldset>
      <legend>Second</legend>
      <input type="text" name="data" />
      <input type="submit" value="A" formaction="second-A.php" />
      <input type="submit" value="B" formaction="second-B.php" />
   </fieldset>
</form>
</body>
</html>

( I have implemented this snippet after reading XMLHttpRequest to Post HTML Form, Sending POST data with a XMLHttpRequest and the excellent MDN documentation. )


Solution

  • I'd propose to set the event listener in JavaScript, so you can access the Event object.

    function submitForm(e) {
      // Get the DOM element that submitted the form
      var caller = e.target || e.srcElement;
      // Set the action to 'formaction' attribute of the caller if it exists, otherwise use the action of the form the caller is in
      var action = caller.getAttribute("formaction") || caller.form.action;
    
      // This is your code, I just changed the variable name for the action to 'action'.
      var xhr = new XMLHttpRequest();
      xhr.onload = function() { alert (xhr.responseText); }
      xhr.open ("post", action, true);
      xhr.send (new FormData (form));
    }
    
    // Get all forms
    var forms = document.querySelectorAll("form");
    
    // Iterate over the forms
    for (var i = 0; i < forms.length; ++i) {
      // Set the event listener
      forms.item(i).onsubmit = submitForm;
    }