jQuery Populate

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

New links

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)

72 Comments

  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. 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. great plugin. saved me a lot of work. thanks dave.

  14. 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. 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://davestewart.io/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. 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

    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!

  40. 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

  41. 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.

  42. jim

    Hi Dave,

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

    Thanks, Jim

    • 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 :)

  43. 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

  44. Marc

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

    Cheers!

  45. 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,

  46. heinetz

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

    best,
    heinetz

  47. 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;

  48. heinetz

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

  49. 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

  50. OsakaWebbie

    Quick question: Your demo page says, in the section about data types:

    Checkbox (checkbox) Checks or unchecks the box String value

    But if the expected content of the string is the value of the checkbox, how is it possible to explicitly uncheck the box? I don't want to clear the whole form first, so this actually matters in my case. Thanks!

    (If you can toss me an email so I know you answered, that would be great.)

  51. OsakaWebbie

    Addendum: It doesn't appear that it will uncheck checkboxes at all, so I had to uncheck them before calling populate() to start with a clean slate. Then I couldn't figure out what value to use even to check the checkboxes – your only example is a group of checkboxes with the same name, therefore an array is used. But mine are independent single checkboxes with unique names. I had to put breakpoints in your code in Firebug to figure it out – it turns out that the magic value that will make the plugin code recognize it and check the checkbox is literally "checkboxValue". That's a bit hard to guess (!), so you might want to mention it in your docs.

  52. Wil Barath

    This is quite powerful already, but I have a suggestion:

    If $.populate() with empty args would return the same heirarchical JSON data which it requires, it would be great for working with the form data in a sensible way:
    data=$("#form").serializeArray();
    for (i in data){
    if (data[i]['name']=='the[cat][in][the][fedora]')) …

    is ooogly compared to
    data=$("#form").populate();
    hats=data.the.cat.in.the;
    (for i in hats){
    if (hat == 'fedora') …

    It would also be useful for re-populating a form after it had undergone some $.html() transformations.

    What do you think? This would be valuable to me, I would be happy to contribute to such an upgrade. It might necessitate renaming the plugin to something like jquery.formJSON so users recognise that it is for dealing with forms directly with JSON, both for read and write.

  53. Dear, Thanks in advance for your gear plugin. Your idea is very simple but the usage is high. I like these things. I also check your plugin with HTML5 tags like , and unfortunately not working very well. I think inside the populateFormElement function, the last witch-case for "button" and "textarea" from value = value == null ? " : value; element.value = value; should be change to value = $('button', this).text();.

    I am looking forward to hear from you, about this issue and other thing related to html.
    AGAIN TAHNKS

  54. There is code from Adrien gibrat on July 29th, 2009, I think it needs some modofcation, but it is quite very well. Still it doesn't support some HTML5 elements very well, like button.
    arguments.callee(name + '\\[' + key + '\\]', value[key]); => arguments.callee(value[key], name + '\\[' + key + '\\]');arguments.callee call the same anonymous function so based on definition $.populate = function (data, selector) it has to be all-right know.

  55. monica

    Thanks for the awesome plug-in! Is there a plan to make populate work with elements like div as well ? I'm using it with dform(dynamic form); had to parse the dom tree to get the dynamic form(id/class) to pass it to populate(). Neitherless I'm here to thank you :-)

  56. chaos

    Bug report:
    when in the form there is a "file" field, script tries to populate it and gets "Security error" from the browser, because entering value to "file" is forbidden. Then all the rest of the form leaves unpopulated. This could be corrected manually, if uncompressed script would be available. Sadly – it is not. So finally – script is useless…

  57. Hi Dave!

    I think I spotted a bug in your plugin. One of the options is labeled 'phpIndices', but in your parseJSON() function I notice a reference to 'options.useIndices', which is never defined. If you change 'useIndices' to 'phpIndices' the parseJSON appears to behave as described in your documentation (e.g. if phpIndices=true and you pass an array to populate() it will look for 'myvar[0]', 'myvar[1]', etc.).

    This plugin has helped me out enormously. Thanks!! –Jim

  58. 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.

  59. 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 = {};

  60. 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!

  61. 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

  62. 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"

  63. Mark

    Hi where do I find the

    $().populate();

    in the demo exampes.
    I've looked everywhere
    please advise.

    Thanks

  64. stxh

    Error when json string contened UTF-8 string (jQuery 2.x)
    After remove paresJSON function and let arr=$.paresJSON(obj) it worked.

Leave a Comment