Simple ajax form using javascript no jQuery
The following is a far more elegant solution of the other answer, more fit for modern browsers.
My reasoning is that if you need support for older browser you already most likely use a library like jQuery, and thus making this question pointless.
/** * Takes a form node and sends it over AJAX. * @param {HTMLFormElement} form - Form node to send * @param {function} callback - Function to handle onload. * this variable will be bound correctly. */function ajaxPost (form, callback) { var url = form.action, xhr = new XMLHttpRequest(); //This is a bit tricky, [].fn.call(form.elements, ...) allows us to call .fn //on the form's elements, even though it's not an array. Effectively //Filtering all of the fields on the form var params = [].filter.call(form.elements, function(el) { //Allow only elements that don't have the 'checked' property //Or those who have it, and it's checked for them. return typeof(el.checked) === 'undefined' || el.checked; //Practically, filter out checkboxes/radios which aren't checekd. }) .filter(function(el) { return !!el.name; }) //Nameless elements die. .filter(function(el) { return el.disabled; }) //Disabled elements die. .map(function(el) { //Map each field into a name=value string, make sure to properly escape! return encodeURIComponent(el.name) + '=' + encodeURIComponent(el.value); }).join('&'); //Then join all the strings by & xhr.open("POST", url); // Changed from application/x-form-urlencoded to application/x-form-urlencoded xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); //.bind ensures that this inside of the function is the XHR object. xhr.onload = callback.bind(xhr); //All preperations are clear, send the request! xhr.send(params);}
The above is supported in all major browsers, and IE9 and above.
Here's a nifty function I use to do exactly what you're trying to do:
HTML:
<form action="/cs/Satellite">...</form><input type="button" value="Vote now" onclick="javascript:AJAXPost(this)">
JS:
function AJAXPost(myself) { var elem = myself.form.elements; var url = myself.form.action; var params = ""; var value; for (var i = 0; i < elem.length; i++) { if (elem[i].tagName == "SELECT") { value = elem[i].options[elem[i].selectedIndex].value; } else { value = elem[i].value; } params += elem[i].name + "=" + encodeURIComponent(value) + "&"; } if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari xmlhttp=new XMLHttpRequest(); } else { // code for IE6, IE5 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.open("POST",url,false); xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); xmlhttp.setRequestHeader("Content-length", params.length); xmlhttp.setRequestHeader("Connection", "close"); xmlhttp.send(params); return xmlhttp.responseText;}
Nowadays using FormData
is the easiest method. You construct it with a reference to the Form
element, and it serializes everything for you.
MDN has an example of this here -- roughly:
const form = document.querySelector("#debarcode-form");form.addEventListener("submit", e => { e.preventDefault(); const fd = new FormData(form); const xhr = new XMLHttpRequest(); xhr.addEventListener("load", e => { console.log(e.target.responseText); }); xhr.addEventListener("error", e => { console.log(e); }); xhr.open("POST", form.action); xhr.send(fd);});
and if you want it as an object (JSON):
const obj = {};[...fd.entries()].forEach(entry => obj[entry[0]] = entry[1]);