Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

form serialize javascript (no framework)

People also ask

How do you serialize data in JavaScript?

In JavaScript, for example, you can serialize an object to a JSON string by calling the function JSON. stringify() . CSS values are serialized by calling the function CSSStyleDeclaration. getPropertyValue() .

What is form serialize JavaScript?

Definition and Usage The serialize() method creates a URL encoded text string by serializing form values. You can select one or more form elements (like input and/or text area), or the form element itself. The serialized values can be used in the URL query string when making an AJAX request.

How do you serialize data in a form?

To serialize a FormData object into a query string, pass it into the new URLSearchParams() constructor. This will create a URLSearchParams object of encoded query string values. Then, call the URLSearchParams. toString() method on it to convert it into a query string.

Why do we need to serialize objects in JavaScript?

Serialization enables us to keep data for use in the running process or other processes if needed. We store the data, then deserialize when it is used elsewhere.


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


For modern browsers only

If you target browsers that support the URLSearchParams API (most recent browsers) and FormData(formElement) constructor (most recent browsers), 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/[email protected]/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('&')

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?)


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


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.


If you need to submit form "myForm" using POST in json format you can do:

const formEntries = new FormData(myForm).entries();
const json = Object.assign(...Array.from(formEntries, ([x,y]) => ({[x]:y})));
fetch('/api/foo', {
  method: 'POST',
  body: JSON.stringify(json)
});

The second line converts from an array like:

[["firstProp", "firstValue"], ["secondProp", "secondValue"], ...and so on... ]

...into a regular object, like:

{"firstProp": "firstValue", "secondProp": "secondValue", ...and so on ... }

...it does this conversion by passing in a mapFn into Array.from(). This mapFn is applied to each ["a","b"] pair and converts them into {"a": "b"} so that the array contains a lot of object with only one property in each. The mapFn is using "destructuring" to get names of the first and second parts of the pair, and it is also using an ES6 "ComputedPropertyName" to set the property name in the object returned by the mapFn (this is why is says "[x]: something" rather than just "x: something".

All of these single property objects are then passed into arguments of the Object.assign() function which merges all the single property objects into a single object that has all properties.

Array.from(): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from

Destructuring in parameters: https://simonsmith.io/destructuring-objects-as-function-parameters-in-es6/

More on computed property names here: Variable as the property name in a JavaScript object literal?