jQuery “Populate” plugin

Populate a form or an element's child elements using a JSON object.

Posted on Tuesday, February 12th, 2008 at 12:37 pm

I don’t like mixing HTML and PHP when I build my forms. Instead I like to keep my HTML completely clean, then if a form needs to be pre-filled (for example retrieving a bunch of database results), get JavaScript to fill it in for me after the page has loaded.

This plugin supports full PHP naming and deep data structures, as well as checkbox arrays, other non-standard UI controls, and even standard HTML elements such as labels or divs.

The plugin can be used as part of your AJAX toolkit, or for separating server-side code from HTML by populating a form after the page has loaded eg:

$('form').populate({text:'text', radio:1})

and not inline as the page is processed, such as:

<input type="text" name="text" id="text" value="<?php echo $text; ?>" />
<input type="radio" name="radio" id="radio-1" checked="<?php echo $val == 1; ?>" />
<input type="radio" name="radio" id="radio-2" checked="<?php echo $val == 2; ?>" />

You can also populate non-form controls such as <div>s, by specifiying the id and an identifying attribute (defaults to id):

$('div').populate({'text-1':'text', 'text-2':'More text'})

This can be useful when you want to show the results of a database call, but don’t want the text to be editable.

Instructions and demos

View the jQuery Populate demo for a view a full set of instructions and a working demo, with examples of populating:

  • a simple form, using string variable types for textfields, radiobuttons, dropdowns and checkboxes
  • a complex form, using array variable types for checkbox arrays and multi-list boxes
  • a hierarchical form, using hierarchical JSON data

Update 29th November 2009

Thanks to everyone who spotted bugs and contributed their comments. The following features are added / bugs are now squished:

  • Now populates standard HTML elements within forms
  • Is now case-sensitive for element value comparisons (keith, 5030SDEC, Mark Croxton)
  • Now skips function references and undefined elements (Henning, Found-a-Bug)
  • Fixed debug trace for missing elements (Found-a-Bug)

Download

JavaScript

PHP

Demo files

Fixed debug trace for missing elements (Found-a-Bug)

Now skips function references and undefined elements (Henning, Found-a-Bug)

Now populates standard HTML elements

Is now case-insensitive for element value comparisons (keith, 5030SDEC, Mark Croxton)

57 Responses to “jQuery “Populate” plugin”

  1. David |

    Hi
    It’s possible put one example complete for this plugin on your site, or demo ??
    David.

  2. Dave Stewart |

    Hi David,
    Sure. Am in deadline hell right now though, so might take a week or so.
    If you just download the files, though, you should have everything you need to get started.

  3. David |

    Hi Dave,
    I try the plugin jquery.populate and for me not work.
    I have:

    jQuery(document).ready(function($) {
    $('div.example').populate({'text-1':'text', 'text-2':'More text'})
    })

    but not work?
    Why?

  4. David |

    Hi Dave,
    I try the plugin jquery.populate and for me not work.
    I have:

    jQuery(document).ready(function($) {
    $(’div.example’).populate({’text-1′:’text’, ‘text-2′:’More text’})
    })

    but not work?
    Why?

  5. Dave Stewart |

    Hi again David.
    I designed populate to be used with forms mainly, and the div stuff was an afterthought.

    However, it looks as if something is up, but I’ll get onto soon, and hopefully I’ll have something up and working in the next week or so.

  6. Vipul |

    Hi Dave,

    Any luck getting the demo up sometime soonish ?

    Cheers,

    Vipul

  7. Dave Stewart |

    Funny you should mention that – I’m doing the demo now! Check back later today or perhaps tomorrow…

  8. Greg Greenhaw |

    jquery form populate does not populate checkboxes and radio buttons in safari.

    Also it would be cool to recognize max length on fields that are array and apply a value between them. For example if you have a json data like {”phone”:”3105551212″} and there were 3 fields like phone[0],phone[1],phone[2] it would split the phone up based off each fields max length

  9. Dave Stewart |

    Damn… whadya know. I’ll look into it when I get a moment. Thanks for flagging it :)

  10. Tirta |

    Dave, a bug report from me. The populate doesnt work with *radio and combo boxes* in Safari for Mac. I don’t know if the status of this bug with Safari for Windows. And Populate works perfectly with Firefox and Opera.

  11. Dave Stewart |

    OK

    thanks guys for reporting the safari bug! Strange that it made it so far without being detected. I’m pretty good at testing on the major browsers so surprised that this made it through, especially after ALL this time!

    Anyway – bug fixed. It was due to safari not implementing the item() method on collection elements.

    Thanks again,
    Dave

  12. wdm |

    Great plugin!

    Found a bug — it seems to break if the field name=”length”

  13. jan berger |

    great plugin. saved me a lot of work. thanks dave.

  14. Henning |

    Hey,
    I use populate to build up what once shall become a web-application ;)
    I had a hard time getting .populate() working properly in FF and mainly IE. I managed to figure out, that this was due to the wide range of objects running through the main loop in function populateFormElement().
    So there are two fixes which got me rich of these errors:
    One insert in line 123 of the uncompressed version:

    if(typeof element == “undefined” || typeof == “function”)
    continue;

    This actually was enough to make the FF running (and hopefully it will speed up the script as well)…

    IE was a bit more tricky but targeting a similar problem. I edited lines 161 to 168 of the uncompressed file to look like this:

    case ‘text’:
    case ‘button’:
    case ‘textarea’:
    case ’submit’:
    value = value == null ? ” : value;
    element.value = value;
    break;
    case ‘div’:
    element.innerHTML = value;
    break;
    default:
    break;

    The point is that often IE seemed to throw an error as he had to work on a function or non-Formelement and apply something like this:
    element.value = value;

    Whatsoever. This is what is currently working for me. Maybe one of you may find my contribution useful for his or her own problem or you, Dave, can use it as an idea for future improvement.

    Thanks for this great Plugin!

    Bye,

    Henning

  15. Keith |

    Great plugin. I’m having a problem with selects in IE7. Your demo works fine but on my implementation the selects are showing up blank. I have State and Country values in uppercase. It seems like the problem is in the select case statement

    line 158 of uncompressed:

    element.value = value.toString().toLowerCase() || value;

    removing the toLowerCase() seems to resolve this for me.

  16. Dave Stewart |

    Hi Keith and Henning,
    Thanks for the posts. I’ll take a look!
    Cheers,
    Dave

  17. Tyler |

    Hey Dave,

    This plugin is just what I need however I’m having issues getting it to work. No JS errors, just a blank form! Would it be possible to post a simple .zip with nothing but the js includes, a tiny html form and the jquery populate call? Something super super simple?

    Thanks so much for your hard work!

    Cheers,

    Tyler

  18. Dave Stewart |

    Hi Tyler,
    Good idea. Maybe I’ll do that in the next few days, and will drop you a mail when done
    :D

  19. Dave Stewart |

    OK, the demos are up. Good suggestions folks.

  20. Dave Phipps |

    Hi Dave,

    I have just started using the populate plugin with jquery 1.3.2 and it populates my form perfectly except for select drop downs. It doesn’t change them to the value in the json string. Here is an example of my json string:

    {”UNIQUENO”:63421, “DATAPROTECTEXTDISCLOSE”:”Y”, “STATUS”:”Active”, “DATAPROTECTWEBPUBLISH”:”Y”}

    The UniqueNo is just a text field but the others are all single select dropdowns.

    Is this a problem with my json string or is there some issue with populate and jquery 1.3.2? I noticed that your demos are using 1.2.1?

    Cheers,

    Dave

  21. 5030SDEC |

    Seems like populate select box doesn’t work if value is not lowercase…

    This work:
    Test

    This *DOES NOT* work
    Test

  22. Dave Stewart |

    Hey guys,

    Sorry you’re having trouble there.

    Dave, can you post a link to some live code? There shouldn’t be any problems. I used this code and it was fine:

    {"UNIQUENO":63421, "DATAPROTECTEXTDISCLOSE":"Y", "STATUS":"Active", "DATAPROTECTWEBPUBLISH":"Y"}

    <select class="select" id="STATUS" name="STATUS">
    <option value="">Select</option>
    <option value="active">Active</option>
    <option value="inactive">Inactive</option>
    </select>

    DEC, yes, populate may have issues with some elements that are lower case. I was adhering to the HTML specs by converting everything to lower case, but it’s not very user-friendly. Do a search in the code and remove the toLowerCase() checks and that might solve it. In the meantime I’ll take another look.

  23. Eric |

    I can’t find the code for results.php (with the simple demo)…and you don’t have it in your demo zip file!

  24. Dave Stewart |

    Hi Eric,
    Ah, it’s just a simple print_r() that dumps the submitted form variables to the browser window. I can post it if you like…

  25. Eric |

    If you could, please? I don’t know what to pass onto the function…

  26. Dave Stewart |

    OK, that’s done. All it does is print out the form variables though, and you need to run it on the server to do so.

  27. Pete Helgren |

    Great plugin! I got it to work and then I had an idea for an improvement that takes it past the current implementation (maybe you know if there is already plugin that does this).

    Here is what I need:

    When there is a known set of fields this works great. Each field is mapped to a JSON element. But when you have an array of data, the current implementation of Populate only sets on the select or checked attribute. What if populate could create a list of fields based on an array? That is what I am after. For example, an employee may have a single email address or they may have 10 (or more). Since I can’t anticipate how many, it would be great if Populate could just create a list of fields anchored by the div or field id. At the very least it would be great to get a list of items generated but even better would be a list of fields.

    I know this goes beyond the current scope of what you are trying to accomplish, but it would be very helpful if variable arrays could rendered in the form “automagically”. I may look around for a plugin that does this but it seems a nice enhancement for populate.

  28. Dave Stewart |

    Thanks Pete!

    Yeah, it does the job alright.

    Your plugin suggestion is kind of the opposite of Populate, but shouldn’t be too hard to accomplish. I guess the thing they have in common is the JSON format.

    Take a look at this, which is similar to what you described. It’s unfinished, and one of the issues was always “how much functionality to add?”

    http://www.keyframesandcode.com/resources/html/form-builder/html/form%20creator%2008.html

    Really, I should break the code out into a library, but as with a lot of my stuff, as I said, it’s unfinished!!

  29. Pete Helgren |

    I gave it a shot although my javascript and jQuery skills are pretty bad. Here is what I did with the assumption that the incoming arrays are key:value pairs and a anchors the placement of them (roughly).

    I added this hack to populateformelement

    // might be a div so check for it’s existance
    objref = document.getElementById(name.substring(0,name.length-2));
    // check that the named element exists in the form
    var name = getElementName(name); // handle non-php naming
    var element = form[name] || objref;

    And then at about line 160

    case ‘DIV’:

    for(var j = 0; j < value.length; j++)

    {
    var fields = value[j].split(”:”);
    var fieldname = fields[0];
    var fieldvalue = fields[1];
    var divname = name.substring(0,name.length-2);
    // Append the fields here
    $(”#”+divname).append(”" + fieldname + “  ” );
    }
    break;

    I can’t say that it will work in all cases but it does what I need which is to populate a div with a list of key – value pairs that allows for editing.

    Thanks!

  30. Adrien gibrat |

    Hello,
    I’ve found your plugin very usefull, but i tought i was’nt using the power of jQuery as it should… So i rewrited itfrom scratch:

    packed version (668bytes!)
    (function($){$.populate=function(h,i){$.each(h,function(b,c){var d=typeof c,e=$(i+’ [name='+b+'],’+i+’ [name='+b+'\\[\\]]’),f=e.is(’:radio,:checkbox’);if(d===’boolean’&&f)e.attr({checked:c?’checked’:null});else if(d===’object’&&!$.isArray(c))for(var g in c)arguments.callee(b+’\\['+g+'\\]‘,c[g]);else e.val(f?$.makeArray(c).map(function(a){return a.toString()}):c)})};$.fn.extend({populate:function(b,c){if(!b)return this.reset();var d=this.selector;if(typeof b===’string’)$.getJSON(b,c,function(a){$.populate(a,d)});else if(typeof b===’object’)$.populate(b,d);return this},reset:function(){return this.filter(’form’).each(function(){this.reset()}).end()}})})(jQuery);

    Full version:
    (function($){
    $.populate = function(data, selector){
    $.each(data, function(name, value){
    var type = typeof value,
    element = $(selector+’ [name='+name+'],’+selector+’ [name='+name+'\\[\\]]’),
    check = element.is(’:radio,:checkbox’);
    if (type === ‘boolean’ && check)
    element.attr({checked: value ? ‘checked’ : null});
    else if (type === ‘object’ && !$.isArray(value))
    for (var key in value)
    arguments.callee(name+’\\['+key+'\\]‘, value[key]);
    else
    element.val(check ? $.makeArray(value).map(function(key){return key.toString();}) : value);
    });
    };
    $.fn.extend({
    populate: function(data, options){
    if (!data)
    return this.reset();
    var selector = this.selector;
    if (typeof data === ’string’)
    $.getJSON(data, options, function(data){ $.populate(data, selector); });
    else if (typeof data === ‘object’)
    $.populate(data, selector);
    return this;
    },
    reset: function(){
    return this.filter(’form’).each(function(){this.reset();}).end();
    }
    });
    })(jQuery);

  31. Adrien gibrat |

    my version don’t use id, but names, as only names are realy required in forms… and using id (especially if different from names) in forms is a very bad idea (you can’t have multiple edit form in the same page by example… and the php array result submited from the form could be different from the one use to populate it: not good!).

    my version target a use with form, and not text… but it should be easy to add text/html injection to an element with a certain class if no form element match the given name….

  32. Adrien gibrat |

    Sorry, just a test, hoping the layout will be better! (you should provide a preview)

    (function($){
    $.populate = function(data, selector){
    $.each(data, function(name, value){
    var type = typeof value,
    element = $(selector+' [name='+name+'],'+selector+' [name='+name+'\\[\\]]'),
    check = element.is(':radio,:checkbox');
    if (type === 'boolean' && check)
    element.attr({checked: value ? 'checked' : null});
    else if (type === 'object' && !$.isArray(value))
    for (var key in value)
    arguments.callee(name+'\\['+key+'\\]', value[key]);
    else
    element.val(check ? $.makeArray(value).map(function(key){return key.toString();}) : value);
    });
    };
    $.fn.extend({
    populate: function(data, options){
    if (!data)
    return this.reset();
    var selector = this.selector;
    if (typeof data === 'string')
    $.getJSON(data, options, function(data){ $.populate(data, selector); });
    else if (typeof data === 'object')
    $.populate(data, selector);
    return this;
    },
    reset: function(){
    return this.filter('form').each(function(){this.reset();}).end();
    }
    });
    })(jQuery);

  33. Everett |

    Maybe I’m blind, but in the stand-alone demos, I’m not seeing where you’re adding the one-liner: “$(’#form’).populate({first_name:’Dave’,last_name:’Stewart’})”

    It’s trivial to JSON encode a PHP array, but you didn’t make it clear where this appears… only a reference that it must come after the form. What is really needed here is an example of where to add our own JSON encoded array to a form. I don’t think it’s helpful to print out the JSON text into a text field merely for display purposes.

    This is a good plugin, and it is right on in its aim to preserve the MVC architecture for form handling, but the documentation still needs some clarification.

  34. Dave Stewart |

    Sorry guys – not really been paying any attention to the blog or my plugins for a long while!

    Thanks for commenting though :)

  35. Found-a-Bug |

    Nice little form population script. I wish something like this was moved to jQuery core…

    There’s a bug when using the debug option. Namely, undefined fields always get debugged to console even when debug is false, because the debug option isn’t consulted before the debug function is called.

    Other than that, great job.

  36. Mark Croxton |

    Found a bug – the select menu (single) selected value is converted to lowercase, so won’t match the original html value if it has uppercase characters!

    Problem line 158:
    element.value = value.toString().toLowerCase() || value;

    Change to:
    element.value = value.toString() || value;

  37. Dave Stewart |

    Thanks chaps, I’ll take a look at these in the next week or so as I have a few updates to do and will see if I can add a fix or two

  38. Found-a-Bug |

    Two issues actually:

    1. Internet Explorer will throw an error if an element is undefined in the for loop of populateFormElement(). Add the following below the var element = elements[e]; line:

    if(!element) continue; //Prevents undefined errors in IE

    2. also in populateFormElement(), the ‘No such element as…’ is always traced when triggered regardless of debug settings.

  39. Dave Stewart |

    Sweet, thanks for the spot. Populate needs a wee update, so I’ll make sure it gets one.
    Thanks

  40. Dave Stewart |

    Just to let everyone know, I’ve finally got round to updating the plugin. Also, I’ve added support for regular HTML elements, so you should now be able to update labels, error messages, or anything else within a form that is not a regular HTML form control.

    Enjoy!

  41. imarichardson |

    Great plugin but I’m having an unexplainable behavior. I add the populator call to my page and I see the field value show instantaneously before disappearing. It’s as if the value gets added then immediately removed. As I mentioned I can see it blink and then disappear.

    Javascript:

    $( "#firstName" ).val( value );

    HTML

  42. Dave Stewart |

    Hey imarichardson,

    Not too sure what you’re doing there. That looks like jQuery not Populate code!

    Email me with some details if you like.

  43. jim |

    Hi Dave,

    Is there a license or copyright or something similar that is associated with your code?

    Thanks, Jim

  44. Dave Stewart |

    Nope – just a use if you want to. I should probably put one in as someone else commented on that. I’m not so anal that I care, but apparently others do :)

  45. Zane |

    Just letting you know that I was getting some weird errors and had to change a line of code:

    var parseJSON = function (obj, path)

    That was what I changed the parseJSON function line to. It eliminated my issue and didnt seem to introduce any other problems. Just letting you know in case you wanted to add that into your next release. Thanks

  46. Marc |

    Just a quick note to say that you’ve helped me learn a better (and cleaner) way to develop web apps.

    Cheers!

  47. sas |

    Hello,
    Thanks for the plugin.
    I had a problem which arises when the plugin tries to populate form fields that do not exist in the form but do exist in the json/js data array.
    for example:
    json data elements are: firstname, lastname, email
    form fields: firstname, lastname

    When the plugin gives js error on IE since it cannot fiend the form field.

    Here is a small patch – line 125:
    if(element == undefined)
    {
    debug(’No such element as ‘ + name);
    return false;
    }

    This will ensure that the plugin will return and not try to populate a non-existing form field.

    Thanks,

  48. Dave Stewart |

    Thanks Sas. Probably about time I had a maintenance-look at this plugin anyway ;)

  49. heinetz |

    IE6 throws an error, when trying to poplulate the value of a textarea.

    best,
    heinetz

  50. heinetz |

    this is, what it did for me:

    #180 case ’select’:
    #181 case ’select-one’:
    #182 element.value = value.toString() || value;
    #183 break;
    #184
    #185 /*new*/case ‘textarea’:
    #186 /*new*/ alert(value);
    #187 /*new*/ value = value == null ? ” : value;
    #188 /*new*/ element.innerHTML = value;
    #189 /*new*/ break;
    #190
    #191 case ‘text’:
    #192 case ‘button’:
    #193 /*old*///case ‘textarea’:
    #194 case ’submit’:
    #195 default:
    #196 value = value == null ? ” : value;
    #197 element.value = value;

  51. heinetz |

    … and you ‘ll see nice alerts whenever populating textareas ;)

  52. Jovan Popovic |

    Hi Dave,

    I have tried this plugin and it looks great. I have few questions about the plugin.
    1. On the demo page in text area example you wrote that “This functionality is currently buggy, and is undergoing review!”. I have placed textarea and it works fine. What is a bug here?
    2. Is there a chance to accept non-string types in JSON. I have check box with values true and false and I need to put something like { Selected: “true” } instead of {Selected: true} in JSON. I don’t see why you have this constraint because to resolve this you will need to change line in the “checkbox” case branch:

    element.checked |= element.value == values[j];

    to

    element.checked |= element.value == values[j].toString();

    I think that the same issue is for select lists. Usually values of select lists are numbers so it is a problem to convert them to string each time, espessially if we are using some library that automatically generate JSON based on actual object.

    Regards,
    Jovan

  53. Bill |

    After spending time fighting with this, I finally gave up.

    I found http://code.google.com/p/jquery-load-json/ works out of the box in my situation.

  54. alex |

    The arr variable is initialized with an JS array. This creates a lot of parasite properties coming from the Array prototype (for instance the ‘all’ function).

    // ——————————————————————————————
    // convert hierarchical JSON to flat array

    var arr = [];
    parseJSON(obj);

    if(options.debug)
    {
    _populate =
    {
    arr: arr,
    obj: obj,
    elements: []
    }
    }

    This produces a lot a bugs under IE since the form['all'] returns something in ie!!!
    Why don’t we use an object instead like this :
    var arr = {};

  55. Phil |

    There’s a bug on line 200 when attempting to fill a select box and a passed in value is null – it should be:

    element.value = (value == null ? ” : (value.toString() || value));

    The same problem exists for radio values.

    Apart from that, though, awesome library!

  56. Chris S. |

    Having a strange problem with populate plug-in. Have used it successfully before but am having the following issue.

    this works fine: $(’#signupForm’).populate({’FNAME’:'firstname’,'LNAME’:'lastname’,'EMAIL’:'test@test.com’});

    but this throws an exception:
    var frmValues = “{’FNAME’:'firstname’,'LNAME’:'lastname’,'EMAIL’:'test@test.com’}”;
    $(’#signupForm’).populate(frmValues);

    the exception I am getting is:
    Uncaught Error: Syntax error, unrecognized expression: #

    so works with a hard codes json value but not as a variable – any thoughts?

    using latest populate plugin with jquery 1.8.3

  57. James Murray |

    I found a small bug.

    In the parseJSON method, in the assignment of values, you make reference to “options.useIndices” the option name is “options.phpIndices”

Make a comment or suggestion...

  • Anti-spam: enter the characters in the image (required).