Using jQuery and JSON to populate forms?
I was wondering how is it popssible to populate forms using JSON?
I have a JSON string which I get using ph开发者_如何学Pythonp'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()
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);
}
});
}
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/
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
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;
}
}
});
};
This is an apendix to @Nowshath's answer
This works for multilevel objects as well
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));
}
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.
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.
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.
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);
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
精彩评论