form serialize javascript (no framework)

form serialize javascript (no framework)

Wondering is there a function in javascript without jquery or any framework that allows me to serialize the form and access the serialized version?

Solutions/Answers:

Solution 1:

The miniature from-serialize library doesn’t rely on a framework. Other than something like that, you’ll need to implement the serialization function yourself. (though at a weight of 1.2 kilobytes, why not use it?)

Solution 2:

Here is pure JavaScript approach:

var form = document.querySelector('form');
var data = new FormData(form);
var req = new XMLHttpRequest();
req.send(data);

Though it seems to be working only for POST requests.

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

Solution 3:

For modern browsers only

If you target browsers that support the URLSearchParams API (most recent browsers) and FormData(formElement) constructor (most recent browsers except Edge), use this:

new URLSearchParams(new FormData(formElement)).toString()

Everywhere except IE

For browsers that support URLSearchParams but not the FormData(formElement) constructor, use this FormData polyfill and this code (works everywhere except IE):

new URLSearchParams(Array.from(new FormData(formElement))).toString()

Example

var form = document.querySelector('form');
var out = document.querySelector('output');

function updateResult() {
  try {
    out.textContent = new URLSearchParams(Array.from(new FormData(form)));
    out.className = '';
  } catch (e) {
    out.textContent = e;
    out.className = 'error';
  }
}

updateResult();
form.addEventListener('input', updateResult);
body { font-family: Arial, sans-serif; display: flex; flex-wrap: wrap; }
input[type="text"] { margin-left: 6px; max-width: 30px; }
label + label { margin-left: 10px; }
output { font-family: monospace; }
.error { color: #c00; }
div { margin-right: 30px; }
<!-- FormData polyfill for older browsers -->
<script src="https://unpkg.com/formdata-polyfill@3.0.17/formdata.min.js"></script>
<div>
  <h3>Form</h3>
  <form id="form">
    <label>x:<input type="text" name="x" value="1"></label>
    <label>y:<input type="text" name="y" value="2"></label>
    <label>
    z:
    <select name="z">
      <option value="a" selected>a</option>
      <option value="b" selected>b</option>
    </select>
  </label>
  </form>
</div>
<div>
  <h3>Query string</h3>
  <output for="form"></output>
</div>

Compatible with IE 10

For even older browsers (e.g. IE 10), use the FormData polyfill, an Array.from polyfill if necessary and this code:

Array.from(
  new FormData(formElement),
  e => e.map(encodeURIComponent).join('=')
).join('&')

Solution 4:

function serialize (form) {
    if (!form || form.nodeName !== "FORM") {
            return;
    }
    var i, j, q = [];
    for (i = form.elements.length - 1; i >= 0; i = i - 1) {
        if (form.elements[i].name === "") {
            continue;
        }
        switch (form.elements[i].nodeName) {
            case 'INPUT':
                switch (form.elements[i].type) {
                    case 'text':
                    case 'tel':
                    case 'email':
                    case 'hidden':
                    case 'password':
                    case 'button':
                    case 'reset':
                    case 'submit':
                        q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value));
                        break;
                    case 'checkbox':
                    case 'radio':
                        if (form.elements[i].checked) {
                                q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value));
                        }                                               
                        break;
                }
                break;
                case 'file':
                break; 
            case 'TEXTAREA':
                    q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value));
                    break;
            case 'SELECT':
                switch (form.elements[i].type) {
                    case 'select-one':
                        q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value));
                        break;
                    case 'select-multiple':
                        for (j = form.elements[i].options.length - 1; j >= 0; j = j - 1) {
                            if (form.elements[i].options[j].selected) {
                                    q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].options[j].value));
                            }
                        }
                        break;
                }
                break;
            case 'BUTTON':
                switch (form.elements[i].type) {
                    case 'reset':
                    case 'submit':
                    case 'button':
                        q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value));
                        break;
                }
                break;
            }
        }
    return q.join("&");
}

Source: http://code.google.com/p/form-serialize/source/browse/trunk/serialize-0.1.js

Solution 5:

Here’s a slightly modified version of TibTibs’:

function serialize(form) {
    var field, s = [];
    if (typeof form == 'object' && form.nodeName == "FORM") {
        var len = form.elements.length;
        for (i=0; i<len; i++) {
            field = form.elements[i];
            if (field.name && !field.disabled && field.type != 'file' && field.type != 'reset' && field.type != 'submit' && field.type != 'button') {
                if (field.type == 'select-multiple') {
                    for (j=form.elements[i].options.length-1; j>=0; j--) {
                        if(field.options[j].selected)
                            s[s.length] = encodeURIComponent(field.name) + "=" + encodeURIComponent(field.options[j].value);
                    }
                } else if ((field.type != 'checkbox' && field.type != 'radio') || field.checked) {
                    s[s.length] = encodeURIComponent(field.name) + "=" + encodeURIComponent(field.value);
                }
            }
        }
    }
    return s.join('&').replace(/%20/g, '+');
}

Disabled fields are discarded and names are also URL encoded. Regex replace of %20 characters takes place only once, before returning the string.

The query string is in identical form to the result from jQuery’s $.serialize() method.

Solution 6:

I started with the answer from Johndave Decano.

This should fix a few of the issues mentioned in replies to his function.

  1. Replace %20 with a + symbol.
  2. Submit/Button types will only be submitted if they were clicked to
    submit the form.
  3. Reset buttons will be ignored.
  4. The code seemed redundant to me since it is doing essentially the
    same thing regardless of the field types. Not to mention
    incompatibility with HTML5 field types such as ‘tel’ and ’email’,
    thus I removed most of the specifics with the switch statements.

Button types will still be ignored if they don’t have a name value.

function serialize(form, evt){
    var evt    = evt || window.event;
    evt.target = evt.target || evt.srcElement || null;
    var field, query='';
    if(typeof form == 'object' && form.nodeName == "FORM"){
        for(i=form.elements.length-1; i>=0; i--){
            field = form.elements[i];
            if(field.name && field.type != 'file' && field.type != 'reset'){
                if(field.type == 'select-multiple'){
                    for(j=form.elements[i].options.length-1; j>=0; j--){
                        if(field.options[j].selected){
                            query += '&' + field.name + "=" + encodeURIComponent(field.options[j].value).replace(/%20/g,'+');
                        }
                    }
                }
                else{
                    if((field.type != 'submit' && field.type != 'button') || evt.target == field){
                        if((field.type != 'checkbox' && field.type != 'radio') || field.checked){
                            query += '&' + field.name + "=" + encodeURIComponent(field.value).replace(/%20/g,'+');
                        }   
                    }
                }
            }
        }
    }
    return query.substr(1);
}

This is how I am currently using this function.

<form onsubmit="myAjax('http://example.com/services/email.php', 'POST', serialize(this, event))">