Reputation: 5615
I was wondering how is it popssible to populate forms using JSON?
I have a JSON string which I get using php's json_encode()
And I want to use the JSON string to populate form controls (such as textarea or text input).
How can I achieve such thing without using external plugins (like jQuery populate plugin, which I saw).
EDIT: JSON format:
[{"id":"41","parent_id":null,"node_name":"name","slug":"","lft":"3","rgt":"4"}]
This is what I get from json_encode()
Upvotes: 36
Views: 59365
Reputation: 23
And this is valid (following Alexander Gs solution), if you have a select with multiple options: (assuming that your JSON has something like
{"key":["value1","value2"]}
in it.)
function populateForm(frm, data) {
jQuery.each(data, function(key, value){
var $ctrl = jQuery('[name='+key+']', frm);
if($ctrl.is('select')){
jQuery("option",$ctrl).each(function(){
$this = this;
if (typeof value === "object") {
jQuery.each( value, function(i, l) {
if ($this.value === l) { $this.selected=true; }
})
}
else if (this.value === value) { this.selected=true; }
})
}
else {
switch($ctrl.prop("type"))
{
case "text" : case "hidden": case "textarea":
$ctrl.val(value);
break;
case "radio" : case "checkbox":
$ctrl.each(function(){
if(jQuery(this).attr('value') === value) { jQuery(this).attr("checked",value); } });
break;
}
}
});
}
Just replace jQuery with $ if needed.
Upvotes: 0
Reputation: 2724
Here are my two cents. :) An iterator for multi-dimensional form data:
var prefill = function(field, value) {
if (['array', 'object'].includes(typeof value)) {
$.each(value, function(index, node) {
prefill(field+'['+index+']', node);
});
return;
}
$(':input[name="'+ field +'"]').val(value);
};
Example for <input name="key">
or <input name="key[..]">
:
$.each(json, function(key, value) {
prefill(key, value);
});
Example for <input name="data[key][..]">
:
$.each(json, function(key, value) {
prefill('data['+ key +']', value);
});
Upvotes: 0
Reputation: 842
There is a problem here with textarea
, then I change it to a default
switch value
Use this to assign values to Many Controls :
function populate(frm, data) {
$.each(data, function(key, value) {
var ctrl = $('[name='+key+']', frm);
switch(ctrl.prop("type")) {
case "radio": case "checkbox":
ctrl.each(function() {
if($(this).attr('value') == value) $(this).attr("checked",value);
});
break;
default:
ctrl.val(value);
}
});
}
Upvotes: 63
Reputation: 276
Thanks Nowshath. It worked for me. I added a extra check in your version to be able to populate select options as well.
function populateForm(frm, data) {
$.each(data, function(key, value){
var $ctrl = $('[name='+key+']', frm);
if($ctrl.is('select')){
$("option",$ctrl).each(function(){
if (this.value==value) { this.selected=true; }
});
}
else {
switch($ctrl.attr("type"))
{
case "text" : case "hidden": case "textarea":
$ctrl.val(value);
break;
case "radio" : case "checkbox":
$ctrl.each(function(){
if($(this).attr('value') == value) { $(this).attr("checked",value); } });
break;
}
}
});
}; // end of populateForm() function
Upvotes: 14
Reputation: 3784
This is an apendix to @Nowshath's answer
populateForm(form, data) {
$.each(data, function(key, value) {
if(value !== null && typeof value === 'object' ) {
this.populateForm(form, value);
}
else {
var ctrl = $('[name='+key+']', form);
switch(ctrl.prop("type")) {
case "radio": case "checkbox":
ctrl.each(function() {
$(this).prop("checked",value);
});
break;
default:
ctrl.val(value);
}
}
}.bind(this));
}
Upvotes: 4
Reputation: 166
I had the same problem and have developed the version shown above a little further. Now it is possible to have individual checkboxes that return the value as well as groups that returns an array of names. The coding is tested, used and working correctly.
function populateForm($form, data)
{
//console.log("PopulateForm, All form data: " + JSON.stringify(data));
$.each(data, function(key, value) // all json fields ordered by name
{
//console.log("Data Element: " + key + " value: " + value );
var $ctrls = $form.find('[name='+key+']'); //all form elements for a name. Multiple checkboxes can have the same name, but different values
//console.log("Number found elements: " + $ctrls.length );
if ($ctrls.is('select')) //special form types
{
$('option', $ctrls).each(function() {
if (this.value == value)
this.selected = true;
});
}
else if ($ctrls.is('textarea'))
{
$ctrls.val(value);
}
else
{
switch($ctrls.attr("type")) //input type
{
case "text":
case "hidden":
$ctrls.val(value);
break;
case "radio":
if ($ctrls.length >= 1)
{
//console.log("$ctrls.length: " + $ctrls.length + " value.length: " + value.length);
$.each($ctrls,function(index)
{ // every individual element
var elemValue = $(this).attr("value");
var elemValueInData = singleVal = value;
if(elemValue===value){
$(this).prop('checked', true);
}
else{
$(this).prop('checked', false);
}
});
}
break;
case "checkbox":
if ($ctrls.length > 1)
{
//console.log("$ctrls.length: " + $ctrls.length + " value.length: " + value.length);
$.each($ctrls,function(index) // every individual element
{
var elemValue = $(this).attr("value");
var elemValueInData = undefined;
var singleVal;
for (var i=0; i<value.length; i++){
singleVal = value[i];
console.log("singleVal : " + singleVal + " value[i][1]" + value[i][1] );
if (singleVal === elemValue){elemValueInData = singleVal};
}
if(elemValueInData){
//console.log("TRUE elemValue: " + elemValue + " value: " + value);
$(this).prop('checked', true);
//$(this).prop('value', true);
}
else{
//console.log("FALSE elemValue: " + elemValue + " value: " + value);
$(this).prop('checked', false);
//$(this).prop('value', false);
}
});
}
else if($ctrls.length == 1)
{
$ctrl = $ctrls;
if(value) {$ctrl.prop('checked', true);}
else {$ctrl.prop('checked', false);}
}
break;
} //switch input type
}
}) // all json fields
} // populate form
Upvotes: 0
Reputation: 1084
In case anyone is looking to populate from a multidimensional json format, such as the result of $.serializeJSON[ https://github.com/marioizquierdo/jquery.serializeJSON ], here's a function to convert to a flat format.
function json2html_name_list(json, result, parent){
if(!result)result = {};
if(!parent)parent = '';
if((typeof json)!='object'){
result[parent] = json;
} else {
for(var key in json){
var value = json[key];
if(parent=='')var subparent = key;
else var subparent = parent+'['+key+']';
result = json2html_name_list(value, result, subparent);
}
}
return result;
}
Usecase example with the functions above:
populateForm($form, json2html_name_list(json))
With all the examples above though:
var $ctrl = $('[name='+key+']', frm);
needs to be changed to
var $ctrl = $('[name="'+key+'"]', frm);
to prevent a syntax error with jQuery
Take note list arrays have to be written with numbers(e.g. fruit[0], instead of fruit[]) in order to be work with this function.
Upvotes: 2
Reputation: 345
I found the original script didn't play nice with array[] names because of missing quotes in the name selector:
var $ctrl = $('[name="'+key+'"]', frm);
Upvotes: 0
Reputation: 41
With little improvements (except radio buttons):
function resetForm($form)
{
$form.find('input:text, input:password, input:file, select, textarea').val('');
$form.find('input:radio, input:checkbox').removeAttr('checked').removeAttr('selected');
}
function populateForm($form, data)
{
resetForm($form);
$.each(data, function(key, value) {
var $ctrl = $form.find('[name='+key+']');
if ($ctrl.is('select')){
$('option', $ctrl).each(function() {
if (this.value == value)
this.selected = true;
});
} else if ($ctrl.is('textarea')) {
$ctrl.val(value);
} else {
switch($ctrl.attr("type")) {
case "text":
case "hidden":
$ctrl.val(value);
break;
case "checkbox":
if (value == '1')
$ctrl.prop('checked', true);
else
$ctrl.prop('checked', false);
break;
}
}
});
};
Upvotes: 4
Reputation: 509
For a weird but valid JSON syntax like
[{'name':<field_name>,'value':<field_value>},
{'name':<field_name>,'value':<field_value>},
{'name':<field_name>,'value':<field_value>},
{'name':<field_name>,'value':<field_value>}]
look at this http://jsfiddle.net/saurshaz/z66XF/
We had this weird syntax being used in our application and we got around by writing the logic as above.
Upvotes: 0
Reputation: 700322
For just text controls (i.e. no radios or checkboxes), you can make a simple version of a populate function:
function populate(frm, data) {
$.each(data, function(key, value){
$('[name='+key+']', frm).val(value);
});
}
Usage example:
populate('#MyForm', $.parseJSON(data));
Demo: http://jsfiddle.net/Guffa/65QB3/3/
Upvotes: 27
Reputation: 7249
This can get pretty complicated. It's best to use a tool to parse your JSON. You can create simple forms pretty easily, but you still need to parse it.
Check this plugin out instead: http://neyeon.com/2011/01/creating-forms-with-json-and-jquery/
Or you can use ext4.
Upvotes: 0