Как узнать, какой <input> отправлен, когда несколько из них определены в <form>?

Я хочу реализовать следующую простую функцию JavaScript submitForm() на основе XMLHttpRequest и FormData. Эти функции хорошо работают на первом <form>, но не работают на втором: функция должна использовать input.formaction вместо form.action.

Как обнаружить нажатый <input> и получить соответствующий formaction?

(Большинство ответов SO советуют использовать фреймворк (как jquery) для такой обработки. Но я думаю, что изучение исключительно чистого JavaScript проще, чем изучение также JS-фреймворков. Если вы уверены, что этот фрагмент можно написать проще с использованием структуры, пожалуйста, предложите свою версию. Пожалуйста, объясните также, почему ваша рекомендуемая структура подходит/актуальна/подходит в этом случае. Я могу решить изучить вашу любимую структуру JS... РЕДАКТИРОВАТЬ: Я нашел этот похожий вопрос: JQuery получить форму и форму формы)

<!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>

(Я выполнил этот фрагмент после прочтения XMLHttpRequest для отправки HTML-формы, Отправка данных POST с помощью XMLHttpRequest и отличную документацию MDN.)

Ответ 1

Я бы предложил установить прослушиватель событий в JavaScript, чтобы вы могли получить доступ к объекту Event.

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;
}

Ответ 2

11684 answer является хорошей отправной точкой, но не работает для меня...

Я, наконец, исправил его (успешно протестирован на Firefox 25, не работает на IE9)

Поэтому я предоставляю свою версию, если это может помочь кому-то еще:

<!DOCTYPE html><html>
<head>
<script>
function submitForm(e)
{
  var form   = e.target;
  var input  = e.explicitOriginalTarget;
  var action = input.formAction || form.action;
  var xhr    = new XMLHttpRequest();
  xhr.onload = function() { alert (xhr.responseText); }
  xhr.open ("post", action, true);
  xhr.send (new FormData (form));
  return false; //avoid following the link
}
</script>
</head>
<body onload="var forms = document.querySelectorAll('form');
              for (var i = 0; i < forms.length; ++i) 
                 forms.item(i).onsubmit = submitForm;">

<form id="first" action="first.php">
   <fieldset>
      <legend>First</legend>
      <input type="text" name="data" />
      <input type="submit"  />
   </fieldset>
</form>

<form id="second" >
   <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>