How do I capture response of form.submit

Viewed 424425

I have the following code:

<script type="text/javascript">
        function SubmitForm()
        {

            form1.submit();
        }

        function ShowResponse()
        {

        }
</script>
.
.
.
<div>
    <a href="#" onclick="SubmitForm();">Click</a>
</div>

I want to capture the html response of form1.submit? How do I do this? Can I register any callback function to form1.submit method?

20 Answers

You won't be able to do this easily with plain javascript. When you post a form, the form inputs are sent to the server and your page is refreshed - the data is handled on the server side. That is, the submit() function doesn't actually return anything, it just sends the form data to the server.

If you really wanted to get the response in Javascript (without the page refreshing), then you'll need to use AJAX, and when you start talking about using AJAX, you'll need to use a library. jQuery is by far the most popular, and my personal favourite. There's a great plugin for jQuery called Form which will do exactly what it sounds like you want.

Here's how you'd use jQuery and that plugin:

$('#myForm')
    .ajaxForm({
        url : 'myscript.php', // or whatever
        dataType : 'json',
        success : function (response) {
            alert("The server says: " + response);
        }
    })
;

An Ajax alternative is to set an invisible <iframe> as your form's target and read the contents of that <iframe> in its onload handler. But why bother when there's Ajax?

Note: I just wanted to mention this alternative since some of the answers claim that it's impossible to achieve this without Ajax.

Future internet searchers:

For new browsers (as of 2018: Chrome, Firefox, Safari, Opera, Edge, and most mobile browsers, but not IE), fetch is a standard API that simplifies asynchronous network calls (for which we used to need XMLHttpRequest or jQuery's $.ajax).

Here is a traditional form:

<form id="myFormId" action="/api/process/form" method="post">
    <!-- form fields here -->
    <button type="submit">SubmitAction</button>
</form>

If a form like the above is handed to you (or you created it because it is semantic html), then you can wrap the fetch code in an event listener as below:

document.forms['myFormId'].addEventListener('submit', (event) => {
    event.preventDefault();
    // TODO do something here to show user that form is being submitted
    fetch(event.target.action, {
        method: 'POST',
        body: new URLSearchParams(new FormData(event.target)) // event.target is the form
    }).then((resp) => {
        return resp.json(); // or resp.text() or whatever the server sends
    }).then((body) => {
        // TODO handle body
    }).catch((error) => {
        // TODO handle error
    });
});

(Or, if like the original poster you want to call it manually without a submit event, just put the fetch code there and pass a reference to the form element instead of using event.target.)

Docs:

Fetch: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API

Other: https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript That page in 2018 does not mention fetch (yet). But it mentions that the target="myIFrame" trick is deprecated. And it also has an example of form.addEventListener for the 'submit' event.

I am not sure that you understand what submit() does...

When you do form1.submit(); the form information is sent to the webserver.

The WebServer will do whatever its supposed to do and return a brand new webpage to the client(usually the same page with something changed).

So, there is no way you can "catch" the return of a form.submit() action.

There is no callback. It's like following a link.

If you want to capture the server response, use AJAX or post it to an Iframe and grab what appears there after the iframe's onload() event.

You need to be using AJAX. Submitting the form usually results in the browser loading a new page.

You can do that using javascript and AJAX technology. Have a look at jquery and at this form plug in. You only need to include two js files to register a callback for the form.submit.

You can use jQuery.post() and return nicely structured JSON answers from server. It also allows you to validate/sanitize your data directly on server, which is a good practice because it's more secure (and even easier) than doing this on client.

For example if you need to post html form to server (to saveprofilechanges.php) with user data for simple registration:

I. Client parts:

I.a. HTML part:

<form id="user_profile_form">
  <label for="first_name"><input type="text" name="first_name" id="first_name" required />First name</label>
  <label for="family_name"><input type="text" name="family_name" id="family_name" required />Family name</label>
  <label for="email"><input type="email" name="email" id="email" required />Email</label> 
  <input type="submit" value="Save changes" id="submit" />
</form>

I.b. Script part:

$(function () {
    $("#user_profile_form").submit(function(event) {
      event.preventDefault();
      var postData = {
        first_name: $('#first_name').val(),
        family_name: $('#family_name').val(),
        email: $('#email').val()
      };
      $.post("/saveprofilechanges.php", postData,
        function(data) {
          var json = jQuery.parseJSON(data);
          if (json.ExceptionMessage != undefined) {
            alert(json.ExceptionMessage); // the exception from the server
            $('#' + json.Field).focus(); // focus the specific field to fill in
          }
          if (json.SuccessMessage != undefined) {
            alert(json.SuccessMessage); // the success message from server
          }
       });
    });
});

II. Server part (saveprofilechanges.php):

$data = $_POST;
if (!empty($data) && is_array($data)) {
    // Some data validation:
    if (empty($data['first_name']) || !preg_match("/^[a-zA-Z]*$/", $data['first_name'])) {
       echo json_encode(array(
         'ExceptionMessage' => "First name missing or incorrect (only letters and spaces allowed).",
         'Field' => 'first_name' // Form field to focus in client form
       ));
       return FALSE;
    }
    if (empty($data['family_name']) || !preg_match("/^[a-zA-Z ]*$/", $data['family_name'])) {
       echo json_encode(array(
         'ExceptionMessage' => "Family name missing or incorrect (only letters and spaces allowed).",
         'Field' => 'family_name' // Form field to focus in client form
       ));
       return FALSE;
    }
    if (empty($data['email']) || !filter_var($data['email'], FILTER_VALIDATE_EMAIL)) {
       echo json_encode(array(
         'ExceptionMessage' => "Email missing or incorrectly formatted. Please enter it again.",
         'Field' => 'email' // Form field to focus in client form
       ));
       return FALSE;
    }
    // more actions..
    // more actions..
    try {
       // Some save to database or other action..:
       $this->User->update($data, array('username=?' => $username));
       echo json_encode(array(
         'SuccessMessage' => "Data saved!"
       ));
       return TRUE;
    } catch (Exception $e) {
       echo json_encode(array(
         'ExceptionMessage' => $e->getMessage()
       ));
       return FALSE;
    }
}
Related