XMLHttpRequest to Post HTML Form

85,754

Solution 1

The POST string format is the following:

name=value&name2=value2&name3=value3


So you have to grab all names, their values and put them into that format. You can either iterate all input elements or get specific ones by calling document.getElementById().

Warning: You have to use encodeURIComponent() for all names and especially for the values so that possible & contained in the strings do not break the format.

Example:

var input = document.getElementById("my-input-id");
var inputData = encodeURIComponent(input.value);

request.send("action=dosomething&" + input.name + "=" + inputData);

Another far simpler option would be to use FormData objects. Such an object can hold name and value pairs.

Luckily, we can construct a FormData object from an existing form and we can send it it directly to XMLHttpRequest's method send():

var formData = new FormData( document.getElementById("my-form-id") );
xhr.send(formData);

Solution 2

The ComFreek's answer is correct but a complete example is missing.

Therefore I have wrote an extremely simplified working snippet:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge, chrome=1"/>

<script>
"use strict";
function submitForm(oFormElement)
{
  var xhr = new XMLHttpRequest();
  xhr.onload = function(){ alert(xhr.responseText); }
  xhr.open(oFormElement.method, oFormElement.getAttribute("action"));
  xhr.send(new FormData(oFormElement));
  return false;
}
</script>
</head>

<body>
<form method="POST"
      action="post-handler.php"
      onsubmit="return submitForm(this);" >
   <input type="text"   value="previousValue" name="name"/>
   <input type="submit" value="Update"/>
</form>
</body>
</html>

This snippet is basic and cannot use GET. I have been inspired from the excellent Mozilla Documentation. Have a deeper read of this MDN documentation to do more. See also this answer using formAction.

Solution 3

By the way I have used the following code to submit form in ajax request.

 $('form[id=demo-form]').submit(function (event) {

    if (request) {
        request.abort();
    }
    // setup some local variables
    var $form = $(this);

    // let's select and cache all the fields
    var $inputs = $form.find("input, select, button, textarea");


    // serialize the data in the form
    var serializedData = $form.serialize();


    // fire off the request to specific url

    var request = $.ajax({
        url : "URL TO POST FORM",
        type: "post",
        data: serializedData
    });
    // callback handler that will be called on success
    request.done(function (response, textStatus, jqXHR){


    });

    // callback handler that will be called on failure
    request.fail(function (jqXHR, textStatus, errorThrown){

    });

    // callback handler that will be called regardless
    // if the request failed or succeeded
    request.always(function () {
        // reenable the inputs

    });

    // prevent default posting of form
    event.preventDefault();
});
Share:
85,754
StuStirling
Author by

StuStirling

Updated on July 22, 2022

Comments

  • StuStirling
    StuStirling almost 2 years

    Current Setup

    I have an HTML form like so.

    <form id="demo-form" action="post-handler.php" method="POST">
       <input type="text" name="name" value="previousValue"/>
       <button type="submit" name="action" value="dosomething">Update</button>
    </form>
    

    I may have many of these forms on a page.

    My Question

    How do I submit this form asynchronously and not get redirected or refresh the page? I know how to use XMLHttpRequest. The issue I have is retrieving the data from the HTML in javascript to then put into a post request string. Here is the method I'm currently using for my zXMLHttpRequest`'s.

    function getHttpRequest() {
        var xmlhttp;
        if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
            xmlhttp=new XMLHttpRequest();
        } else {// code for IE6, IE5
            xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
        }
        
        return xmlhttp;
    }
    
    function demoRequest() {
           var request = getHttpRequest();
           request.onreadystatechange=function() {
                 if (request.readyState == 4 && request.status == 200) {
                       console.log("Response Received");
                 }
           }
           request.open("POST","post-handler.php",true);
           request.setRequestHeader("Content-type","application/x-www-form-urlencoded");
           request.send("action=dosomething");
    }
    

    So for example, say the javascript method demoRequest() was called when the form's submit button was clicked, how do I access the form's values from this method to then add it to the XMLHttpRequest?

    EDIT

    Trying to implement a solution from an answer below I have modified my form like so.

    <form id="demo-form">
           <input type="text" name="name" value="previousValue"/>
           <button type="submit" name="action" value="dosomething" onClick="demoRequest()">Update</button>
    </form>
    

    However, on clicking the button, it's still trying to redirect me (to where I'm unsure) and my method isn't called?

    Button Event Listener

    document.getElementById('updateBtn').addEventListener('click', function (evt) {
                                    evt.preventDefault();
                                    
                                    // Do something
                                    updateProperties();
                                    
                                    return false;
                                });
    
    • Brewal
      Brewal over 10 years
      You tagged jQuery but there is no jQuery code... Do you want to use jQuery or pure javascript ?
    • StuStirling
      StuStirling over 10 years
      Sorry misclick. Just javascript
    • Roy M J
      Roy M J over 10 years
      I posted an answer that you can use via jquery though
    • oHo
      oHo over 10 years
    • Mashmagar
      Mashmagar about 4 years
      To prevent the default form action, set an event listener on the form's submit event, instead of the button's click event. (And still call evt.preventDefault();)
    • Tanque
      Tanque almost 4 years
      In your edit captioned "Button Event Listener", where exactly would you put that code? into the functions demoRequest() body? why the return false statement?
  • ComFreek
    ComFreek over 10 years
    The OP does not want to use jQuery.
  • Awais Qarni
    Awais Qarni over 10 years
    @ComFreek He didn't mention in question. Now he mentioned in comment. I posted answer before this comment.
  • StuStirling
    StuStirling over 10 years
    Do I override the button's onClick function and point it to my XMLHttpRequest method?
  • ComFreek
    ComFreek over 10 years
    @DiscoS2 Yes. Do you have any other event handlers registered for the click event?
  • StuStirling
    StuStirling over 10 years
    Not for this form no.
  • StuStirling
    StuStirling over 10 years
    Thank you for expanding on your answer more. I am having issues submitting the form. I have remove the action and method from the <form> tag as it was still posting via HTML. How do I call my javascript method?
  • ComFreek
    ComFreek over 10 years
    @DiscoS2 How did you assign the event listener? Can you show us the code (in your answer - not in a comment, please)?
  • StuStirling
    StuStirling over 10 years
    Added the code in my original question. However, its not a listener... unsure of how to do this?
  • ComFreek
    ComFreek over 10 years
    @DiscoS2 Try this code: jsfiddle.net/ZsHgu (add an ID to your button and register an event listener as provided in the fiddle).
  • StuStirling
    StuStirling over 10 years
  • svenyonson
    svenyonson over 7 years
    Thanks for posting Awais, I found this thread and I DO want to use jQuery
  • Mayur Patel
    Mayur Patel over 6 years
    When I use this method my form is submitting multiple(2) times. Any suggestion?
  • Mayur Patel
    Mayur Patel over 6 years
    Today I just found a small fix for this. I have changed onsubmit="submitForm(this);" to onsubmit="return submitForm(this);". Rest of your code remains same. This solved my problem. Thanks.
  • oHo
    oHo over 6 years
    Thank you @MayurPatel very much for your feedback. I have just edited the snippet to reflect your contribution. Have fun ;-)
  • Sayok88
    Sayok88 about 6 years
    If we wanted ajax we would have used jq so no thanks
  • Black
    Black about 6 years
    Your code does not work with file uploads... I used var formData = new FormData( document.getElementById("my-form-id") ); and formData is empty.
  • ComFreek
    ComFreek about 6 years
    @Black According to MDN on FormData objects, it should work. Did you use a POST or GET request?
  • Black
    Black about 6 years
    @ComFreek, It works now. It was not working because of a wrong header (stackoverflow.com/questions/50020648/…)
  • john ktejik
    john ktejik almost 6 years
    This doesn't work in an addon. how to do this without overriding the onsubmit()? addons/extensions do not allow overriding onsubmit due to security reasons.
  • h3n
    h3n almost 5 years
    You should use oFormElement.getAttribute("action") in case you ever add an input field named "action", which will override your oFormElement.action. Same goes for method ofc
  • oHo
    oHo over 4 years
    Thank you @h3n for your advice 👍 I have just applied your trick. Should I do the same for oFormElement.getAttribute("method")? I am a bit afraid my original tiny snippet is becoming more complex... What do you think? Have fun 😊
  • Admin
    Admin over 4 years
    @olibre Async is by default true, so you don't need it - developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/…
  • the_new_mr
    the_new_mr about 3 years
    If you have a separate question, you should create one rather than posting an answer on an already existing question. Thank you.