9

I get ajax response as JSON and need to fill a form with it. How to do that in jQuery or something else ? Is something better than using $(json).each() ?

JSON:

{ 
  "id" : 12,
  "name": "Jack",
  "description": "Description"
}

Form to fill

<form>
  <input type="text" name="id"/>
  <input type="text" name="name"/>
  <input type="text" name="description"/>
</form>
marioosh
  • 27,328
  • 49
  • 143
  • 192

11 Answers11

10

Came here searching for a solution that didn't involve jQuery or a brunch of DOM scaning, but didn't find one... so here is my vanilla js solution brought to you other guys that probably ditched jQuery long ago.

const data = { 
  "id" : 12,
  "name": "Jack",
  "description": "Description",
  "nonExisting": "works too"
}

const { elements } = document.querySelector('form')

for (const [ key, value ] of Object.entries(data) ) {
  const field = elements.namedItem(key)
  field && (field.value = value)
}
<form>
  <input type="text" name="id"/>
  <input type="text" name="name"/>
  <input type="text" name="description"/>
</form>
Endless
  • 34,080
  • 13
  • 108
  • 131
9
var json={ 
  "id" : 12,
  "name": "Jack",
  "description": "Description"
};
for(key in json)
{
  if(json.hasOwnProperty(key))
    $('input[name='+key+']').val(json[key]);
}

srry i thought it was the id property that was set.

here: http://jsfiddle.net/anilkamath87/XspdN/

Baz1nga
  • 15,485
  • 3
  • 35
  • 61
  • Using that code snippet, `key` will leak to the global scope. Also it needs a `hasOwnProperty` check, to prevent issues when `Object.prototype` has been extended. – Mathias Bynens Aug 04 '11 at 07:34
  • 1
    Thanks. Also remember that a form element might be not only ``. it also may have `texarea`, select`, `radio` . so `[name='+key+']` might be wider than `input[name='+key+']` – Accountant م Aug 17 '17 at 20:37
5

Assuming data is the JSON object, you could use this inside the $.getJSON callback:

var $inputs = $('form input');
$.each(data, function(key, value) {
  $inputs.filter(function() {
    return key == this.name;
  }).val(value);
});
Mathias Bynens
  • 144,855
  • 52
  • 216
  • 248
  • 1
    What is `this[key]` supposed to do? You find the name in the `name` attribute, not in an attribute with the same name and value (except in the case when the `name` attribute actually contains the value `name`). – Guffa Aug 04 '11 at 07:42
  • @Guffa You’re absolutely right; I was confused for a second (since the first two examples are `name` and `id`, which would work as properties as well). Thanks, I’ve edited my answer. – Mathias Bynens Aug 04 '11 at 10:22
2

Pretty simple in pure JavaScript:

https://jsfiddle.net/ryanpcmcquen/u8v47hy9/

var data = {
  foo: 1,
  bar: 2
};
var inputs = Array.prototype.slice.call(document.querySelectorAll('form input'));

Object.keys(data).map(function (dataItem) {
  inputs.map(function (inputItem) {
    return (inputItem.name === dataItem) ? (inputItem.value = data[dataItem]) : false;
  });
});
<form>
  <input name="foo">
  <input name="bar">
</form>

Edit: This also works with other inputs such as select, simply by replacing document.querySelectorAll('form input') with document.querySelectorAll('form input, form select').

This also gets around the global leak in this answer: https://stackoverflow.com/a/6937576/2662028

alistair
  • 565
  • 5
  • 15
ryanpcmcquen
  • 6,285
  • 3
  • 24
  • 37
1

I'm using this method with iCheck elements. This method can work native check and radio inputs.

populateForm(frm, data) {
    console.log(data);

    $.each(data, function(key, value) {
        var ctrl = $("[name=" + key + "]", frm);
        switch (ctrl.prop("type")) {
            case "radio":
                if (
                    ctrl.parent().hasClass("icheck-primary") ||
                    ctrl.parent().hasClass("icheck-danger") ||
                    ctrl.parent().hasClass("icheck-success")
                ) {
                    // raido kutularında aynı isimden birden fazla denetçi olduğu için bunları döngüyle almak lazım
                    // multiple radio boxes has same name and has different id. for this we must look to each html element
                    $.each(ctrl, function(ctrlKey, radioElem) {
                        radioElem = $(radioElem);
                        console.log(radioElem);
                        console.log(radioElem.attr("value"));

                        if (radioElem.attr("value") == value) {
                            radioElem.iCheck("check");
                        } else {
                            radioElem.iCheck("uncheck");
                        }
                    });
                } else {
                    $.each(ctrl, function(ctrlKey, radioElem) {
                        radioElem = $(radioElem);
                        console.log(radioElem);
                        console.log(radioElem.attr("value"));

                        if (radioElem.attr("value") == value) {
                            radioElem.attr("checked", value);
                        } else {
                            radioElem.attr("checked", value);
                        }
                    });
                }
                break;

            case "checkbox":
                if (
                    ctrl.parent().hasClass("icheck-primary") ||
                    ctrl.parent().hasClass("icheck-danger") ||
                    ctrl.parent().hasClass("icheck-success")
                ) {
                    if (ctrl.attr("value") == value) {
                        ctrl.iCheck("check");
                    } else {
                        ctrl.iCheck("uncheck");
                    }
                } else {
                    ctrl.removeAttr("checked");
                    ctrl.each(function() {
                        if (value === null) value = "";
                        if ($(this).attr("value") == value) {
                            $(this).attr("checked", value);
                        }
                    });
                }
                break;
            default:
                ctrl.val(value);
        }
    });
}

Example form:

<form id="form1">
    <div className="form-group row">
        <label className="col-sm-3 col-form-label">
            {window.app.translate(
                "iCheck Radio Example 1"
            )}
        </label>
        <div className="col-sm-9">
            <div className="icheck-primary">
                <input
                    type="radio"
                    id="radio1_0"
                    name="radio1"
                    value="0"
                />
                <label for="radio1_0">
                    {window.app.translate(
                        "Radio 1 0"
                    )}
                </label>
            </div>
            <div className="icheck-primary">
                <input
                    type="radio"
                    id="radio1_1"
                    name="radio1"
                    value="1"
                />
                <label for="radio1_1">
                    {window.app.translate(
                        "Radio 1 1"
                    )}
                </label>
            </div>
            <div className="icheck-primary">
                <input
                    type="radio"
                    id="radio1_2"
                    name="radio1"
                    value="2"
                />
                <label for="radio1_2">
                    {window.app.translate(
                        "Radio 1 2"
                    )}
                </label>
            </div>
        </div>
    </div>

    <div className="form-group row">
        <label className="col-sm-3 col-form-label">
            {window.app.translate(
                "iCheck Radio Example 2"
            )}
        </label>
        <div className="col-sm-9">
            <div className="icheck-primary">
                <input
                    type="radio"
                    id="radio2_0"
                    name="radio2"
                    value="0"
                />
                <label for="radio2_0">
                    {window.app.translate(
                        "Radio 2 0"
                    )}
                </label>
            </div>
            <div className="icheck-primary">
                <input
                    type="radio"
                    id="radio2_1"
                    name="radio2"
                    value="1"
                />
                <label for="radio2_1">
                    {window.app.translate(
                        "Radio 2 1"
                    )}
                </label>
            </div>
            <div className="icheck-primary">
                <input
                    type="radio"
                    id="radio2_2"
                    name="radio2"
                    value="2"
                />
                <label for="radio2_2">
                    {window.app.translate(
                        "Radio 2 2"
                    )}
                </label>
            </div>
        </div>
    </div>


    <div className="form-group row">
        <label
            htmlFor="ssl"
            className="col-sm-3 col-form-label"
        >
            {window.app.translate("SSL")}
        </label>
        <div className="col-sm-9">
            <div className="form-group row">
                <div className="col-sm-12">
                    <div className="icheck-primary d-inline">
                        <input
                            type="checkbox"
                            id="ssl"
                            name="ssl"
                            value="1"
                        />
                        <label for="ssl" />
                    </div>
                </div>
            </div>
        </div>
    </div>


</form>

Example json data:

{
    "radio1": "3",
    "radio2": "1",
    "ssl": "0"
}

Edit: I tried populate plugin but it doesn't working with iCheck and other things for example select2, chosen, etc...

kodmanyagha
  • 932
  • 12
  • 20
1

jQuery Populate plugin and code proposed by @Mathias inspired me to make my own plugin:

Here my myPopulate plugin code. It use attr parameter as name of elements attribute on to use for identifying them.

(function($) {
    $.fn.myPopulate = function(json, attr) {
        var form = $(this);
        $.each(json, function(key, value) {
            form.children('[' + attr + '="' + key + '"]').val(value);
        });
    };
})(jQuery);

Using:

{ 
  "id" : 12,
  "name": "Jack",
  "description": "Description"
}

form1 (matching by name attribute):

<form>
    <input type="text" name="name" />
    <input type="text" name="id" />
    <textarea type="text" name="description" />
</form>
$('#form1').myPopulate(json, 'name');

form2 (matching by alt attribute):

<form id="form2">
    <input type="text" name="nick" alt="name" />
    <input type="text" name="identifier" alt="id" />
    <textarea type="text" name="desc" alt="description" />
</form>
$('#form2').myPopulate(json, 'alt');
marioosh
  • 27,328
  • 49
  • 143
  • 192
  • No need for `var form = $(this);`, just do `var form = this;` since `this` already refers to the jQuery collection at that point. – Mathias Bynens Aug 04 '11 at 10:23
0

I haven't seen a solution that accounts for a form with nested properties. Here it is.

//pass in the parent object name, if there is one
let parentName = 'optional';
SyncJsonToForm(data, parentName);

function SyncJsonToForm(obj, path = '') {
     let subpath = path === '' ? path : path + '.';
     $.each(obj, function (key, value) {
          let jsonPath = subpath + key;

          // to debug a particular field (or multiple fields), replace the following JsonPath(s) with the desired property(ies)
          if ([''].includes(jsonPath)) {
               console.log(jsonPath);
               debugger;
          }

          // update the value for the jsonPath
          $(`[name="${jsonPath}"]`).val(value);

          if (typeof value === "object") {
               SyncJsonToForm(value, jsonPath);
          }
     });
}
Isaac Adams
  • 150
  • 4
0

Just use a JSON plugin for jQuery - such as jquery-json.

mattkelly
  • 626
  • 3
  • 9
0

You might want to take a look at the jQuery Populate plugin.

Although if this is the only use case you have, you might as well do it manually.

Bertrand Marron
  • 21,501
  • 8
  • 58
  • 94
  • 2
    Old link http://www.keyframesandcode.com/resources/javascript/jQuery/demos/populate-demo.html not active any more. New link is: http://davestewart.io/resources/javascript/jQuery/demos/populate-demo.html – Abhishek Oza Jun 21 '18 at 11:37
  • New link: https://github.com/davestewart/jquery-populate – Kristen Dec 15 '22 at 15:49
0

You might also consider usage of jQuery templates for that purpose:

http://api.jquery.com/jQuery.template/

Alexander Beletsky
  • 19,453
  • 9
  • 63
  • 86
0

First you need to parse the JSON string so that you get an object that you can use:

var o = $.parseJSON(json);

(Note: You can also specify the data type 'json' in the AJAX call, then it will be parsed into an object already when you get the result.)

Then you can loop throught the properties in the object:

$.each(o, function(key, value){
  $('form [name=' + key + ']').val(value);
});
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • What is `o[e]` supposed to do? I think you mean `e`. (That’s what you get when using obfuscated variable names like that.) Also, you should quote the attribute value in the selector in case in contains special characters. Also, it’s not very efficient to look for `$('[name=foo]')` in the entire document; better to use context, or look for the inputs first, and then filter the cached collection. See [my answer](http://stackoverflow.com/questions/6937519/how-to-fill-form-with-json/6937611#6937611) for an example. – Mathias Bynens Aug 04 '11 at 07:25