How do I capture response of form.submit
Asked Answered
S

20

172

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?

Scholiast answered 17/12, 2008 at 14:15 Comment(0)
B
133

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);
        }
    })
;
Boger answered 17/12, 2008 at 14:25 Comment(4)
+1 for jQuery Form plugin. It's awesome, but you've got the 'target' attribute wrong. It is not like the 'action' attribute of the form; i.e. it is not the submit destination. From the docs: target - Identifies the element(s) in the page to be updated with the server response.Mackmackay
to be fair, you don't NEED to use a library for AJAX. libraries are written using javascript, so therefore a non-library solution exists. that said, i am 100% in favor of using a library to abstract all the ridiculousness and complexity involved in making an AJAX call.Followup
I'm posting this comment more as an FYI that the above solution works, except when it comes to File Uploads via AJAX on IE 9 and below. I've had problems submitting files via ajax on non-HTML5 IE browsers (IE 9 and below) so I must use an iframe hack. But using the iframe hack requires the form.submit(), but you can't wait for a response to tell you if it succeeded or not. This has left me in a quandary.Pannier
Using a library really isn't worth it here. In pure JS the code isn't much more complicated: var xhr = new XMLHttpRequest() xhr.open("POST", "myscript.php"); xhr.onload=function(event){ alert("The server says: " + event.target.response); }; var formData = new FormData(document.getElementById("myForm")); xhr.send(formData);Riggins
G
77

The non-jQuery vanilla Javascript way, extracted from 12me21's comment:

var xhr = new XMLHttpRequest();
xhr.open("POST", "/your/url/name.php"); 
xhr.onload = function(event){ 
    alert("Success, server responded with: " + event.target.response); // raw response
}; 
// or onerror, onabort
var formData = new FormData(document.getElementById("myForm")); 
xhr.send(formData);

For POST's the default content type is "application/x-www-form-urlencoded" which matches what we're sending in the above snippet. If you want to send "other stuff" or tweak it somehow see here for some nitty gritty details.

Gertrudegertrudis answered 6/12, 2017 at 13:19 Comment(4)
Actually this is the correct answer! Because all other answers do exactly the same, but obfuscated by one more layer of libraries.Strage
This looks like exactly what I need, since I already have a PHP file that is handling many direct XMLHttpRequest()s on my page. But in the case of a simple form with a typical <form action = "/mysite/mycode.php"> and <submit> tags, I'm not sure how to modify.. Would I substitute my javascript httprequest calls( with a callback,) as in: <form action="myhttpreq("url, etc...)? or maybe <form action="#" onsubmit="return myhttpfunction() ? Something like that? If its that easy, this should definitely be THE answer. But I'm a little confused how to set it up.Gehman
@Gehman In my case I had a button within the form like this <input type='button' onclick="submitForm(); return false;"> or you could add an event listener for 'submit' event like Marcus' answer: https://mcmap.net/q/142815/-how-do-i-capture-response-of-form-submitGertrudegertrudis
This was perfect for me. I am writing a chrome addon and am trying to avoid any libraries instead handling more complex operations on the server. This was perfect for my needs Thanks!Cressida
F
68

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.

Friar answered 17/12, 2008 at 14:27 Comment(7)
Say if you wanted to post to a URL for a download through a button click? Now you can't use Ajax for your request. Want to then clean up or update the interface when the download is complete? Now is a time to want a callback from a POST that isn't Ajax. (Necropost, I know.)President
@Dropped.on.Caprica Yup, that's still a legitimate use case for <iframe> POSTs (with callback to parent). For downloads and uploads alike...Friar
Also as far as I know for anyone that needs compatibility with older versions of IE (7+), I'm pretty sure the iframe method is the only way to go. Please correct me if I'm wrong because I'm currently having this issue right now.Schnorkle
For detecting the success of a download, a neat trick I learned recently is to set a cookie in the download response and poll for the existence of that cookie in the browser.Friar
three words: asynchronous file uploadsUnusual
Note that this will only work if the form submission action is on the same site as the iframe. Otherwise Same-Origin policy will block it.Guildhall
Wow, THAT was a great hack! Solved for me. Thanks! :)Blend
A
63

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((response) => {
        if (!response.ok) {
          throw new Error(`HTTP error! Status: ${response.status}`);
        }
        return response.json(); // or response.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.

Aigrette answered 7/8, 2018 at 15:8 Comment(2)
Important note from MDN : "The Promise returned from fetch() won’t reject on HTTP error status even if the response is an HTTP 404 or 500. Instead, it will resolve normally (with ok status set to false), and it will only reject on network failure or if anything prevented the request from completing." That means then then callbacks must check HTTP status.Nastassia
Thanks @FrançoisF, I edited my answer to include a check for http status based on developer.mozilla.org/en-US/docs/Web/API/fetchAigrette
W
37

I am doing it this way and its working.

$('#form').submit(function(){
    $.ajax({
      url: $('#form').attr('action'),
      type: 'POST',
      data : $('#form').serialize(),
      success: function(){
        console.log('form submitted.');
      }
    });
    return false;
});
Wimble answered 21/3, 2014 at 19:24 Comment(5)
You may want to event.preventDefault(); (event = first argument of submit function) instead of return false. Returning false will not simply stop the browser from submitting the form but also stop other side-effects from happening that could be important. There are lots of questions related to this.Aerate
well, yes, return false or preventDefault or stopPropogation based on the needs.Wimble
You may need to use FormData($("myform")[0]) if you are attempting an input type=file upload.Senility
To be a bit more generic, you can use event.target.action and $(event.target).serialize() instead of $('#form').attr('action') and $('#form').serialize().Geryon
Cleanest solution by far.Argile
C
13

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.

Cobbie answered 17/12, 2008 at 14:20 Comment(2)
I created another html page and returned this as response.Digiacomo
how you did this approach @DigiacomoGinder
B
6

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.

Bourke answered 17/12, 2008 at 14:20 Comment(0)
M
2

You can event.preventDefault() in the click handler for your submit button to ensure that the HTML form default submit event doesn't fire (which is what leads to the page refreshing).

Another alternative would be to use hackier form markup: It's the use of <form> and type="submit" that is getting in the way of the desired behavior here; as these ultimately lead to click events refreshing the page.

If you want to still use <form>, and you don't want to write custom click handlers, you can use jQuery's ajax method, which abstracts the entire problem away for you by exposing promise methods for success, error, etc.


To recap, you can solve your problem by either:

• preventing default behavior in the handling function by using event.preventDefault()

• using elements that don't have default behavior (e.g. <form>)

• using jQuery ajax


(i just noticed this question is from 2008, not sure why it showed up in my feed; at any rate, hopefully this is a clear answer)

Maxillary answered 11/5, 2015 at 20:42 Comment(0)
S
2
    $.ajax({
        url: "/users/login/",    //give your url here
        type: 'POST',
        dataType: "json",
        data: logindata,
        success: function ( data ){
        //  alert(data);    do your stuff
        },
        error: function ( data ){
        //  alert(data);    do your stuff
        }
    });
Seif answered 29/4, 2016 at 7:43 Comment(0)
E
2

This is my code for this problem:

<form id="formoid" action="./demoText.php" title="" method="post">
    <div>
        <label class="title">First Name</label>
        <input type="text" id="name" name="name" >
    </div>
    <div>
        <input type="submit" id="submitButton"  name="submitButton" value="Submit">
    </div>
</form>

<script type='text/javascript'>
    /* attach a submit handler to the form */
    $("#formoid").submit(function(event) {
        /* stop form from submitting normally */
        event.preventDefault();

        /* get the action attribute from the <form action=""> element */
        var $form = $(this), url = $form.attr('action');

        /* Send the data using post with element id name and name2*/
        var posting = $.post(url, {
            name: $('#name').val()
        });

        /* Alerts the results */
        posting.done(function(data) {
            alert('success');
        });
    });
</script>
Encumbrance answered 20/7, 2016 at 7:4 Comment(0)
A
1

In case you want to capture the output of an AJAX request using Chrome you can follow these simple steps:

  1. Open up the Programmers toolbox
  2. Go to the console and right anywhere inside it
  3. In the menu that appears, click "Enable XMXHTTPRequest Logging"
  4. After doing that everytime you make an AJAX request a message starting with "XHR finished loading:http://......" will appear in your console.
  5. Clicking on the link that appears, will bring the "Resources tab" where your can see the headers and the content of the response!
Apply answered 7/10, 2010 at 15:29 Comment(0)
A
1

Building on the answer by @rajesh_kw (https://mcmap.net/q/142815/-how-do-i-capture-response-of-form-submit), I handle form post errors and success:

    $('#formName').on('submit', function(event) {
        event.preventDefault(); // or return false, your choice
        $.ajax({
            url: $(this).attr('action'),
            type: 'post',
            data: $(this).serialize(),
            success: function(data, textStatus, jqXHR) {
                // if success, HTML response is expected, so replace current
                if(textStatus === 'success') {
                    // https://mcmap.net/q/144832/-how-do-i-replace-the-entire-html-node-using-jquery
                    var newDoc = document.open('text/html', 'replace');
                    newDoc.write(data);
                    newDoc.close();
                }
            }
        }).fail(function(jqXHR, textStatus, errorThrown) {
            if(jqXHR.status == 0 || jqXHR == 302) {
                alert('Your session has ended due to inactivity after 10 minutes.\nPlease refresh this page, or close this window and log back in to system.');
            } else {
                alert('Unknown error returned while saving' + (typeof errorThrown == 'string' && errorThrown.trim().length > 0 ? ':\n' + errorThrown : ''));
            }
        });
    });

I make use of this so that my logic is reusable, I expect HTML to be returned on a success so I render it and replace the current page, and in my case I expect a redirect to the login page if the session is timed out, so I intercept that redirect in order to preserve the state of the page.

Now users can log in via another tab and try their submit again.

Aerate answered 8/9, 2016 at 21:58 Comment(0)
R
1

I have Following code perfactly run using ajax with multi-part form data

function getUserDetail()
{
    var firstName = document.getElementById("firstName").value;
    var lastName = document.getElementById("lastName").value;
    var username = document.getElementById("username").value;
    var email = document.getElementById("email").value;
    var phoneNumber = document.getElementById("phoneNumber").value;
    var gender =$("#userForm input[type='radio']:checked").val();
    //var gender2 = document.getElementById("gender2").value;
    //alert("fn"+firstName+lastName+username+email);
    var roleIndex = document.getElementById("role");
    var role = roleIndex.options[roleIndex.selectedIndex].value;
    var jobTitleIndex = document.getElementById("jobTitle");
    var jobTitle = jobTitleIndex.options[jobTitleIndex.selectedIndex].value;
    var shiftIdIndex = document.getElementById("shiftId");
    var shiftId = shiftIdIndex.options[shiftIdIndex.selectedIndex].value;


    var addressLine1 = document.getElementById("addressLine1").value;
    var addressLine2 = document.getElementById("addressLine2").value;
    var streetRoad = document.getElementById("streetRoad").value;

    var countryIndex = document.getElementById("country");
    var country = countryIndex.options[countryIndex.selectedIndex].value;

    var stateIndex = document.getElementById("state");
    var state = stateIndex.options[stateIndex.selectedIndex].value;

    var cityIndex = document.getElementById("city");
    var city = cityIndex.options[cityIndex.selectedIndex].value;



    var pincode = document.getElementById("pincode").value;

    var branchIndex = document.getElementById("branch");
    var branch = branchIndex.options[branchIndex.selectedIndex].value;

    var language = document.getElementById("language").value;
    var profilePicture = document.getElementById("profilePicture").value;
    //alert(profilePicture);
    var addDocument = document.getElementById("addDocument").value;


    var shiftIdIndex = document.getElementById("shiftId");
    var shiftId = shiftIdIndex.options[shiftIdIndex.selectedIndex].value;


    var data = new FormData();
    data.append('firstName', firstName);
    data.append('lastName', lastName);
    data.append('username', username);
    data.append('email', email);
    data.append('phoneNumber', phoneNumber);
    data.append('role', role);
    data.append('jobTitle', jobTitle);
    data.append('gender', gender);
    data.append('shiftId', shiftId);
    data.append('lastName', lastName);
    data.append('addressLine1', addressLine1);
    data.append('addressLine2', addressLine2);
    data.append('streetRoad', streetRoad);
    data.append('country', country);
    data.append('state', state);
    data.append('city', city);
    data.append('pincode', pincode);
    data.append('branch', branch);
    data.append('language', language);
    data.append('profilePicture', $('#profilePicture')[0].files[0]);
     for (var i = 0; i < $('#document')[0].files.length; i++) {
            data.append('document[]', $('#document')[0].files[i]);
        }



    $.ajax({
        //url : '${pageContext.request.contextPath}/user/save-user',
        type: "POST",
        Accept: "application/json",
        async: true,
        contentType:false,
        processData: false,
        data: data,
        cache: false,

        success : function(data) {      
            reset();
            $(".alert alert-success alert-div").text("New User Created Successfully!");
         },
       error :function(data, textStatus, xhr){
           $(".alert alert-danger alert-div").text("new User Not Create!");
        }


    });


//

}
Rog answered 26/7, 2017 at 4:7 Comment(0)
O
0

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

Odum answered 17/12, 2008 at 14:19 Comment(0)
I
0

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.

Indrawn answered 17/12, 2008 at 14:24 Comment(0)
E
0

You can accomplish this using jQuery and the ajax() method:

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script language="javascript" type="text/javascript">
function submitform() {
      $.ajax({
        headers: { 
          'Accept': 'application/json',
          'Content-Type': 'application/json' 
        },
        type: "POST",
        url : "/hello.hello",
        dataType : "json",
        data : JSON.stringify({"hello_name": "hello"}),
        error: function () {
          alert('loading Ajax failure');
        },
    	onFailure: function () {
          alert('Ajax Failure');
    	},
    	statusCode: {
          404: function() {
          alert("missing info");
          }   
    	},
        success : function (response) {
          alert("The server says: " + JSON.stringify(response));
        }
      })
      .done(function( data ) {
        $("#result").text(data['hello']);
      });
};</script>
Entity answered 12/10, 2015 at 5:52 Comment(0)
E
0
 $(document).ready(function() {
    $('form').submit(function(event) {
        event.preventDefault();
        $.ajax({
            url : "<wiki:action path='/your struts action'/>",//path of url where u want to submit form
            type : "POST",
            data : $(this).serialize(),
            success : function(data) {
                var treeMenuFrame = parent.frames['wikiMenu'];
                if (treeMenuFrame) {
                    treeMenuFrame.location.href = treeMenuFrame.location.href;
                }
                var contentFrame = parent.frames['wikiContent'];
                contentFrame.document.open();
                contentFrame.document.write(data);
                contentFrame.document.close();
            }
        });
    });
});

First of all use $(document).ready(function()) inside this use ('formid').submit(function(event)) and then prevent default action after that call ajax form submission $.ajax({, , , , });

It will take parameter u can choose according your requirement then call a function

success:function(data) {
    // do whatever you want my example to put response html on div 
}
Electrostatic answered 7/12, 2016 at 12:30 Comment(0)
H
0

First of all we will need serializeObject();

$.fn.serializeObject = function () {
    var o = {};
    var a = this.serializeArray();
    $.each(a, function () {
        if (o[this.name]) {
            if (!o[this.name].push) {
                o[this.name] = [o[this.name]];
            }
            o[this.name].push(this.value || '');
        } else {
            o[this.name] = this.value || '';
        }
    });
    return o;
};

then you make a basic post and get response

$.post("/Education/StudentSave", $("#frmNewStudent").serializeObject(), function (data) {
if(data){
//do true 
}
else
{
//do false
}

});
Hindemith answered 14/6, 2017 at 15:33 Comment(0)
A
0

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;
    }
}
Asa answered 1/11, 2017 at 16:2 Comment(0)
J
-7

you can do that without ajax.

write your like below.

.. .. ..

and then in "action.php"

then after frmLogin.submit();

read variable $submit_return..

$submit_return contains return value.

good luck.

Jocosity answered 11/7, 2015 at 17:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.