Skip to content Skip to sidebar Skip to footer

Serialize HTML Form To JSON With Pure JavaScript

I have seen this method of serializing a form to JSON and it's working fine. My question is: How can I achieve this with pure JavaScript, without using any jQuery code? I am sorry

Solution 1:

You can try something like this:

    function formToJson(){
        var formElement = document.getElementsByTagName("form")[0],
            inputElements = formElement.getElementsByTagName("input"),
            jsonObject = {};
        for(var i = 0; i < inputElements.length; i++){
            var inputElement = inputElements[i];
            jsonObject[inputElement.name] = inputElement.value;

        }
        return JSON.stringify(jsonObject);
    }

This solution works only if you have a single form on the page, to make it more general the function could e.g. take the form element as an argument.


Solution 2:

You can use Array.reduce, something like

// get array of all fields and/or selects (except the button)
const getFields = () => Array.from(document.querySelectorAll("input, select"))
    .filter(field => field.type.toLowerCase() !== "button");

// get id, name or create random id from field properties
const getKey = field => field.name 
  || field.id 
  || `unknown-${Math.floor(1000 * Math.random()).toString(16)}`;

// get data, simple object
const getFormData = () => getFields()
    .reduce( (f2o, field) => ({...f2o, [getKey(field)]: field.value}), {} );

// log the result
const logResult = txt => document.querySelector("#result").textContent = txt;

// get data, array of field objects
const getMoreFormData = () => getFields()
  .reduce( (f2o, field) =>
    f2o.concat({
        id: field.id || "no id",
        name: field.name || "no name",
        idGenerated: getKey(field),
        type: field.type, 
        value: field.value }
      ),
    [] );

// handling for buttons
document.addEventListener("click", evt => {
  if (evt.target.nodeName.toLowerCase() === "button") {
    console.clear();
    logResult(/simple/.test(evt.target.textContent)
     ? JSON.stringify(getFormData(), null, " ")
     : JSON.stringify(getMoreFormData(), null, " ")
    );
  }
} );
<form action="#" method="post">
  <div>
    <label for="name">Name</label>
    <input type="text" name="name" id="name" value="Pete"/>
  </div>
  <div>
    <label for="email">Email</label>
    <input type="text" name="email" id="email" value="pete@here.com"/>
  </div>
  <div>
    <label for="password">Password</label>
    <input type="password" name="password" id="password" />
  </div>
  <div>
    <label>Field without name or id</label>
    <input type="number" value="12345" />
  </div>
</form>

<p>
  <button>Data simple object</button> <button>Data fields array</button>
</p>

<pre id="result"></pre>

Solution 3:

Remember that for checkboxes, value attribute can be either on or off string. This is unwanted. Here is my solution, based on this codepen.

let json = Array.from(form.querySelectorAll('input, select, textarea'))
    .filter(element => element.name)
    .reduce((json, element) => {
        json[element.name] = element.type === 'checkbox' ? element.checked : element.value;
        return json;
    }, {});

OR

let json = {};
Array.from(form.querySelectorAll('input, select, textarea'))
    .filter(element => element.name)
    .forEach(element => {
        json[element.name] = element.type === 'checkbox' ? element.checked : element.value;
    });

OR (with typescript)

export type FormJson = {[key: string]: boolean | string};

export const toJson = (form: HTMLFormElement): FormJson => 
    Array.from(form.querySelectorAll<HTMLFormElement>('input, select, textarea'))
        .filter(element => element.name)
        .reduce<FormJson>((json, element) => {
            json[element.name] = element.type === 'checkbox' ? element.checked : element.value;
            return json;
        }, {});

Post a Comment for "Serialize HTML Form To JSON With Pure JavaScript"