Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert an HTML form field to a JSON object with inner objects

Given the following HTML form:

<form id="myform">
  Company: <input type="text" name="Company" value="ACME, INC."/>
  First Name: <input type="text" name="Contact.FirstName" value="Daffy"/>
  Last Name: <input type="text" name="Contact.LastName" value="Duck"/>
</form>

What is the best way serialize this form in javascript to a JSON object in the format:

{
  Company:"ACME, INC.",
  Contact:{FirstName:"Daffy", LastName:"Duck"}
}

Also note that there might be more than 1 "." sign in the field name.

like image 793
Tawani Avatar asked Mar 31 '10 12:03

Tawani


People also ask

How can I convert form data to JSON?

How to Convert Form Data to JSON With Object. fromEntries() Note: For both methods, we can use JSON. stringify() to convert the object into a JSON string, which we can then use to send JSON encoded data to APIs.

How do you store data from HTML form to JSON?

To send data from HTML form to JSON file we are using json_encode() function which returns a JSON encoded string. We are making an array of values that the user fills in the HTML form. Then we pass this array into json_encode() function. The json_encode() function returns a JSON encoded string.

Can we convert HTML to JSON?

HTML to JSON Converter is used to convert HTML document to JSON by extracting the rows from HTML tables & converting it to JSON format. HTML is parsed, data types are automatically detected & converted to appropriate format in the JSON output. And finally the JSON output is formatted & indented for easy viewing.

What is toJSON () in JSON?

if you need to read or clone all of a model's data attributes, use its toJSON() method. This method returns a copy of the attributes as an object (not a JSON string despite its name). (When JSON.


2 Answers

I think that what you'd do is this: for each input, first split the name at the separators (the '.' characters). Now, you have an array of names. You can then iterate through that array, making sure that your target "assembly" object (and sub-objects) have containers every time you come across a new name segment. When the array has 1 element in it, you simply add the value.

$.fn.extractObject = function() {
  var accum = {};
  function add(accum, namev, value) {
    if (namev.length == 1)
      accum[namev[0]] = value;
    else {
      if (accum[namev[0]] == null)
        accum[namev[0]] = {};
      add(accum[namev[0]], namev.slice(1), value);
    }
  }; 
  this.find('input, textarea, select').each(function() {
    add(accum, $(this).attr('name').split('.'), $(this).val());
  });
  return accum;
});
// ...

var object = $('#myform').extractObject();

I just sort-of made that up so there might be a bug or two; I can't remember whether all the browsers have "slice" but I think they do.

(edit: I forgot the all-important call to split())

like image 100
Pointy Avatar answered Sep 30 '22 10:09

Pointy


You can loop through the form fields by name, use String#split to split the names on dot, and build up your resulting structure. Concept code:

function serializeDeep(form) {
    var rv, obj, elements, element, index, names, nameIndex, value;

    rv = {};
    elements = form.elements;
    for (index = 0; index < elements.length; ++index) {
        element = elements[index];
        name = element.name;
        if (name) {
            value = $(element).val();
            names = name.split(".");
            obj = rv;
            for (nameIndex = 0; nameIndex < names.length; ++nameIndex) {
                name = names[nameIndex];
                if (nameIndex == names.length - 1) {
                    obj[name] = value;
                }
                else {
                    obj = obj[name] = obj[name] || {};
                }
            }
        }
    }
    return rv;
}

Note that that doesn't allow for fields with repeated names (which should create arrays), nor does it elegantly handle a situation where you use the names "foo" and "foo.bar". But it should get you started.

like image 42
T.J. Crowder Avatar answered Sep 30 '22 09:09

T.J. Crowder