Search code examples
javascriptajaxxmlhttprequestformshttp-post

XMLHttpRequest to Post HTML Form


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

Solution

  • 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);