jQuery Form Builder Plugin

Trellis Development (a parent company of web-based products which I co-founded) has been developing a custom content management system which needed a form creation tool. I adapted a form builder that I created for a previous project as a jQuery 1.3 plugin. It loads in existing form structure data through an XML file (which would be generated on the server) and passes the changes as a serialized array back to the server.

View the Demonstration
Get source from github

I’ve forked the code from the cms to serve as a stand-alone plugin. It’s extremely easy to setup, as all you need to do is to activate it on an un/ordered list item element. Then, write your backend code to handle the incoming array as you need, and output the xml data for when the form loads.

<ul id="form-builder"></ul>
		'save_url': 'save.php',
		'load_url': 'form-a.xml'

The save_url is the url that the ajax will be sent to when the user saves the form. The form information is serialized so that the backend programming may handle it as an array.

The load_url is the url of an xml file that describes any existing form information, and the system uses it to restore the fields.

This requires jQuery 1.3+ and uses the scrollTo plugin for nice scrolling.

Please report all issues and feature suggestions at https://snowy-evening.com/botsko/jquery-form-builder/

This is the first revision that’s external to our cms so I’ve labeled it 0.1.

Possibly related posts:

  1. jQuery Serialize List Plugin


  1. This is one awesome blog.Much thanks again. Keep writing.

    Comment by Zackary Vankomen — May 20, 2010 @ 10:16 am

  2. Thanks for this it is very handy. I am trying to extend it by adding a required dependency on a previous item entry (an Other option if you like, but with other uses too) if that previous item was a radiobutton, checbox or list field, but am struggling to add the additional fields to the js serializeFormList function. As soon as I do, the deserialize and hash functions in Formbuilder.php fall to bits. Any help appreciated…

    Comment by Craig — June 18, 2010 @ 12:31 am

  3. Not to worry, discovered the survey string was going over 5K and the DB retrieval routine was truncating it. Fixed now.

    Thanks again, this is a great bit of code.

    Comment by Craig — June 18, 2010 @ 2:23 am

  4. It doesn’t work on IE :( What can I do to fix it?

    Comment by Yuliana — June 19, 2010 @ 7:20 am

  5. I’m not sure. The version we’re using in our core application works properly in IE. Can you provide any details about what’s happening? I don’t have IE quite handy at this moment but can do further tests if needed.

    Comment by Michael Botsko — June 21, 2010 @ 9:20 am

  6. I have this… $j is because i have a function for no conflict with prorotype and works fine in FF but not in IE8

    					'save_url': 'url('Edit'); ?&gt;',
    					'load_url': 'url('details' . $id . '/load'); ?&gt;',

    Help me please :’(

    Comment by Yuliana — June 22, 2010 @ 12:13 pm

  7. Well without trying it yet, I can say that the extra comma that follows the load_url segment should not be there. IE tends to break with commas of a list when there’s no next item. I’ll make sure that’s not in my code…

    Comment by Michael Botsko — June 22, 2010 @ 12:28 pm

  8. i feel so ashamed.. i wouldnt have imagined it
    thank u very much!!!!!!

    Comment by Yuliana — June 22, 2010 @ 3:12 pm

  9. Not a problem. It’s caused me enough headaches in the past that I have a good idea when it’s lurking in code.

    Comment by Michael Botsko — June 22, 2010 @ 3:15 pm

  10. Hey, great stuff! Thanks for sharing :)

    I just have a problem, how to initiate save process? The “save” button won’t work, won’t call the example-save.php script.

    Comment by Relja — June 25, 2010 @ 12:24 am

  11. The process works using an ajax call to save the serialized form data back to the form. I’d recommend that you use a debugging tool to watch and make sure that request is happening or not. I’m pretty sure it works properly from the latest code downloads.

    Comment by Michael Botsko — June 25, 2010 @ 8:01 am

  12. This is pretty slick. Is there a way for the javascript to generate the HTML that the user sees from the XML that populates the editable view?

    Comment by Joe — July 27, 2010 @ 1:23 am

  13. There’s no support for that in this version of the application but you could add in support for that. If you would like to contribute any changes back, please feel free.

    Comment by Michael Botsko — July 27, 2010 @ 7:35 am

  14. [...] me from building a special purpose application. Thanks to Michael Botsko for making a good jQuery Form builder. People like him build tools that let people like me try and make a [...]

    Pingback by Fred Trotter » Blog Archive » My Health2.0 submission goes to eleven — September 19, 2010 @ 2:05 pm

  15. Dear Michael,

    The form builder is great! However, I am not sure if the form (fields/values) can be edited after it has been serialized and saved in the database.

    In case I’d like to modify my form after I have saved it. I’d like to simply retrieve the serialized value from my db, unserialize it & allow it to appear again the jQuery format (with the values accordingly) & save once I have edited the form.

    I’m relatively new to jQuery – your guidance will be greatly appreciated!

    Comment by Mischa — February 28, 2011 @ 8:39 pm

  16. Please look through the code in the example-load.php file. The system already handles this for you – unserializing it, and loading it into the form again using an XML structure.

    Comment by Michael Botsko — March 1, 2011 @ 7:36 am

  17. I am loading a form by grabbing the data via AJAX. I have this line…

    	save_url': '../library/blocks/forms/ajax.php?q=form_save&amp;fn='+$("#sel_edit_form").val(),
    	'load_url': '../library/blocks/forms/ajax.php?q=form_load&amp;fn='+$("#sel_edit_form").val()

    trouble is that when I save, it saves once for each form I have loaded. How do I fix that?

    Comment by Mike S. — April 15, 2011 @ 1:15 pm

  18. The save action should only be tied with the element with the #form-builder id – do you have multiple forms like that? Please make sure your html is valid and if it is, I’ll look at the javascript and see if there’s any open issues for that.

    Comment by Michael Botsko — April 16, 2011 @ 8:33 am

  19. Thanks for the reply! I let the user choose a form from a select box, when the value of the select box changes I make an AJAX call to a PHP page that renders the form then call:

    ‘save_url’: ‘../library/blocks/forms/ajax.php?q=form_save&amp;fn=’+$(“#sel_edit_form”).val(),
    ‘load_url’: ‘../library/blocks/forms/ajax.php?q=form_load&amp;fn=’+$(“#sel_edit_form”).val()

    So each time I attach it to the same object #form-builder. I also tried creating a new object each time by appending the form name to #form-builder but had the same result. Everything else is working beautifully and thank you for that, you saved me a lot of coding.

    Comment by Mike S. — April 18, 2011 @ 3:20 pm

  20. This is how I tried to make a new object each time, I did this so I could remove the object from the DOM. That does not solve the problem though. I would prefer to rewrite one object called form-builder but would settle for any solution to this issue of saving once for each time I change forms. Thanks so much!

    	$previous_id = false;
    	function load_form(){
    		$fb_id = 'form-builder-'+$("#sel_edit_form").val();
    		$previous_id = $fb_id;
    		$objFormBuilder = '';
    		$("#form-wrap ul").sortable({ opacity: 0.6, cursor: 'move'});
    		if($("#sel_edit_form").val() != ''){			
    				'save_url': '../library/blocks/forms/ajax.php?q=form_save&amp;fn='+$("#sel_edit_form").val(),
    				'load_url': '../library/blocks/forms/ajax.php?q=form_load&amp;fn='+$("#sel_edit_form").val()

    Comment by Mike S. — April 18, 2011 @ 4:04 pm

  21. OMG…

    I finally figured it out, totally my fault. Stupid stupid stupid stupid… I change this:

       return false;

    To this:

       return false;

    In order to pull the button out. Sorry to have wasted your time. Thank you again for the wonderful script and class!

    Comment by Mike S. — April 18, 2011 @ 4:13 pm

  22. Not a problem. Glad you found the solution.

    Comment by Michael Botsko — April 18, 2011 @ 4:19 pm

  23. Ok, so this is weird now… The Delete links for fields, when I click on them ask for confirmation once for each time I have changed forms. And, the show/hide link will do the same. It’s kind of funny, change the form 5 times and click it -> Open Close Open Close Open. Argh. I didn’t change the code for those, any ideas?

    Comment by Mike S. — April 18, 2011 @ 4:46 pm

  24. Hi,

    This is an awesome bit of code. The only thing I am trying to work out is how to produce a ‘saved’ message once it saves the form.

    Is there an easy way to do this?



    Comment by Mike — April 19, 2011 @ 8:53 am

  25. You can place any messaging code into the save ajax success callback, around line 384 of the js file. Someday when I get around to updating the code I’ll allow an external callback function to be passed in instead.

    Comment by Michael Botsko — April 19, 2011 @ 9:31 am

  26. I’d have to look at the implementation but the click event should only be firing on a single element. However, the animate effects are called on elements with a specific ID – if you’ve wound up having multiple IDs (which is very likely since this wasn’t built for multiple forms on a single page) then it’s likely triggering all of those elements.

    Comment by Michael Botsko — April 19, 2011 @ 9:33 am

  27. Hey thanks again, good tip. I was able to fix all of my issues with this and it has turned out to be a terrifc addition to my application!

    Comment by Mike S. — April 19, 2011 @ 4:47 pm

  28. Awesome! Thank you!

    Comment by Michael Botsko — April 19, 2011 @ 4:48 pm

  29. Thanks for the reply.

    Line 284

    success: function(xml){ }

    How would I put a call back in and then get the value in the front end script?

    Comment by Mike — April 20, 2011 @ 1:16 am

  30. Right now there is no direct callback support but you can either add your code here, or modify this function to call one of your own.

    Comment by Michael Botsko — April 20, 2011 @ 12:20 pm

  31. Ok thanks.

    Thought I’d post my solution here:

    Replace line 384 with:

    function ChangeText(){
        var curtextval = document.getElementById("formBuilderReturn");
        curtextval.innerHTML = "Saved"
        $('#formBuilderReturn').fadeOut(2000, function() {})

    Then add a div to your formbuilder with the id of: “formBuilderReturn”

    That will return ‘Saved’ and then fade the div out

    Comment by Mike — April 21, 2011 @ 1:14 am

  32. Sorry code was wrong. This is the correct code.

    Replace line 384 with:

    function ChangeText(){
        var curtextval = document.getElementById("formBuilderReturn");
        curtextval.innerHTML = ""
        curtextval.style.display = "block"
        curtextval.innerHTML = "Saved"
    	$('#formBuilderReturn').fadeOut(3000, function() {})

    Then add a div to your formbuilder with the id of: “formBuilderReturn”

    That will return ‘Saved’ and then fade the div ou

    Comment by Mike — April 21, 2011 @ 1:35 am

  33. Glad you were able to get it working. I’m curious to why you’ve use standard javascript for the function instead of jQuery – the plugin is based on jQuery so it’s naturally already present and doing the code would be less verbose through it. Maybe something like:

    function ChangeText(){

    Comment by Michael Botsko — April 21, 2011 @ 8:40 am

  34. Michael, I love it. Works great. I have one question: I have multiple forms and want to use the “form_id” from my database to identify the forms. What would be the best way to pass around the form_id (along with the form_hash and form_structure) so that’s it available when I need to put the results back into the database?
    Right now the sql in my save_form page just runs an update and overwrites the same form (since I don’t have an ID to tell it what row to update).

    Comment by Brandon — May 19, 2011 @ 12:42 pm

  35. It depends on what you mean by multiple forms – for example the original product with this program had a page which displayed all of the available forms for editing, and clicking on one would pass the id along to the actual editing page, which would then use that id for loading. If you’re talking about managing multiple forms on a single page, there will be issues because the plugin wasn’t written originally with that intent.

    Comment by Michael Botsko — May 19, 2011 @ 12:49 pm

  36. Right, just selecting from a list of forms to load, not multiple forms loaded on the same page.

    The part where I select the form from a list and load it is no problem. I just don’t know how to pass the id to the save page. I normally have a hidden field in the form that passes the ID to the action.

    Comment by Brandon — May 19, 2011 @ 1:12 pm

  37. I believe we just appended the form id to the save_url via php and handled that in the database query. Maybe not the way I’d do it today, but that would work.

    Comment by Michael Botsko — May 19, 2011 @ 1:14 pm

  38. Ha, yes, that was easy:

    ‘save_url’: ‘form-save.php?form_id=’

    Thanks a million Michael.

    Comment by Brandon — May 19, 2011 @ 1:30 pm

  39. Michael, it is awesome, I have one question how to generate XML from your form?
    I’m relatively new to jQuery – your guidance will be greatly appreciated!

    Comment by sentana — May 24, 2011 @ 8:53 am

  40. Please review the examples provided with source code. There is a php class provided that will generate the proper XML for form loading.

    Comment by Michael Botsko — May 24, 2011 @ 11:57 am

  41. Please someone has it in asp.net, I loved the script but I really dont know php.

    Comment by Eduardo — June 2, 2011 @ 9:01 am

  42. I need to use some characters like ‘Ş’ or ‘ı’, i think its some encoding problem how can i fix this?

    Ş character looks like %u015E when i save the form.

    Comment by Enes — July 20, 2011 @ 5:43 pm

  43. It really works great in FF & Chrome but not working in IE, Opera and Safari.

    anyone got any idea?

    Comment by zeyar — July 21, 2011 @ 3:18 am

  44. hi Michael,

    first, very appreciate your contribution and its awesome.
    I got some problem with IE7,IE8 (i am not very surprised) but also not work in Safari and Opera too.

    any idea about that?

    Comment by Zeyar — July 21, 2011 @ 8:03 pm

  45. Just pushed an update that resolve these issues. Thanks!

    Comment by Michael Botsko — July 22, 2011 @ 9:34 am

  46. We have not officially added support for special characters, but we’re now attempting to properly encode them before sending through to PHP. We’ll eventually need to convert those back.

    Comment by Michael Botsko — July 22, 2011 @ 9:36 am

  47. wow. really nice. i’ll check them out.

    Comment by kozeyar — July 23, 2011 @ 6:48 am

  48. Thank you Michael!!
    Its really works now. Bless you mate!

    Comment by kozeyar — July 23, 2011 @ 6:52 am

  49. I am having trouble with the output. It works great, but the generate_html function doesn’t seem to output anythign useful. Same thing on the demo site. Is there any example code for this?

    Comment by Richard Lester — July 27, 2011 @ 10:25 am

  50. We recently added some updates which may have broken that – thought it was working but I’ll need to check it tonight.

    Comment by Michael Botsko — July 27, 2011 @ 10:26 am

  51. I wrote my own form display (have some strict requirements). I am wondering though where I would add my own fields. For instance, I want to make a separator field. So the user can create a separator that is nothing more than a line of text that the output will make all pretty. :)

    Comment by Richard Lester — July 28, 2011 @ 1:10 pm

  52. Not sure if we’ll have time to add that but we’ll consider it! Thanks!

    Comment by Michael Botsko — July 29, 2011 @ 7:14 am

  53. Thanks for the update. That fixed a couple of the issues I was having with the multiplying radio boxes, etc.

    I am having the same problems as Richard though. The html output is not working. I logged the problem at the issues link above.


    Comment by Brandon — July 31, 2011 @ 10:56 am

  54. Found the problem with the html output. I’m guessing I can’t paste the code here, but I had to change all instances of $field|`class`| to $field|`cssClass`| in formbuilder.php.

    Now if I can only get the “required” box in the admin section to stay checked, I will be fully rocking this awesome plugin!

    Comment by Brandon — August 1, 2011 @ 8:18 pm

  55. Hi Michael,

    I am all absolutely fine with saving to the database and integration and so on. But got problem regenerate from the database (sorry we are using .net for back-end).

    Can I have xml structure and example? so that can I can save to and load from xml.

    (example-xml.php seems not working, that is why)

    Cheers and always appreciate your contribution!

    Comment by Zeyar — August 2, 2011 @ 4:40 am

  56. Im wanting to extend the controlBox function, so I can alter the html and not have to edit the core files. Is there any way to do this? the function is being returned, so I’m not sure if that’s possible or not

    Comment by andy — August 20, 2011 @ 9:27 am

  57. We don’t have much support for extending yet, sorry.

    Comment by Michael Botsko — August 22, 2011 @ 9:01 am

  58. Hi great script. I have one question. How would I merge saved data with post data and email the form on submit.

    Comment by Mike — September 13, 2011 @ 6:51 pm

  59. Not entirely sure what you mean but you could always load the saved data, allow the form post, and then send the email?

    Comment by Michael Botsko — September 13, 2011 @ 8:11 pm

  60. If I do that I’m only getting form values and field names. I would like to submit Field titles also. Eg: Your Email: value, Your Name:value etc, otherwize it would be hard to guess what each form field represents

    Comment by Mike — September 14, 2011 @ 6:14 am

  61. Is the field name close enough? Just format that properly and it should work for that. Otherwise, you’d have to the load/parse the original form array and extract it from there.

    Comment by Michael Botsko — September 14, 2011 @ 7:37 am

  62. Hi, this scripts works fine with the fake values when I upload these values from database . But once I save the values in database by calling the save method, the values get updated in database but when I try to load these values it doesn’t work. Please help me in this regard.
    Following are the saved database values
    form_hash: c7ede2c89b823fa0fdd4e400e24279fe13b8c1a2
    form_stucture: a:4:{i:0;a:2:{s:8:”cssClass”;s:12:”a_input_text”;s:8:”required”;s:5:”false”;}i:1;a:2:{s:8:”cssClass”;s:12:”a_input_text”;s:8:”required”;s:4:”true”;}i:2;a:2:{s:8:”cssClass”;s:10:”a_checkbox”;s:8:”required”;s:5:”false”;}i:3;a:2:{s:8:”cssClass”;s:7:”a_radio”;s:8:”required”;s:4:”true”;}}

    Comment by Mohsin — September 15, 2011 @ 1:19 pm

  63. Above are the values stored in database after calling the save function. But when i tried to reload the page with the saved values i couldn’t see anything :(

    Comment by Mohsin — September 15, 2011 @ 1:40 pm

  64. Hi i debug the issue my self, I have made some changes in css, that was causing the issue. It’s working fine now. Thanks a lot. You code has save my lot of time and efforts. Thanks again :) May God bless you

    Comment by Mohsin — September 15, 2011 @ 1:49 pm

  65. Very useful & works out of the box for me.

    I have a question about functionality – it seems you can export as serialised data directly from javascript, but you cannot import from serialised data directly.

    I see you’ve got PHP handlers to do JSON & XML. But why not have options to export and import directly from Javascript as JSON or XML?

    Thanks – very cool plugin!

    Comment by Rodders — September 28, 2011 @ 9:04 am

  66. oh – i see you can import json & xml with fromJson() & fromXml() functions, but why not have the option to export directly to these formats too, rather than just as serialised array?

    Comment by Rodders — September 28, 2011 @ 9:10 am

  67. Because it unfortunately was not originally designed that way. I had wanted to support json originally it was still supposed to support pre-PHP5, which required a third party library for json encoding. We needed to get it working faster and because it was built as part of a larger cms, the xml was used for other things. Anyway, now we have a nice disconnect like you’ve mentioned. Someday I would like to make it use only JSON both in saving, and loading.

    Comment by Michael Botsko — September 30, 2011 @ 12:17 pm

  68. Hi, nice plugin :) I’ve embedded this into the backend of my CMS and works nicely in terms of creating and saving the forms to db. When a created form is shown in the front end of the site, how can I handle the processing of it? i.e validating, then sending the form to an email address?

    Comment by ChrisB — October 6, 2011 @ 7:00 am

  69. Hi Michael,

    I’ve added a simple jsonify plugin based on your export plugin that I’m using, so I store the json in database directly and skip the intermediate conversion steps.

    If you want, I’d like to contribute this code back. What is the best way for me to do this?

    Comment by Rodders — October 13, 2011 @ 3:11 am

  70. Putting the code on github and submitting a pull request is the best way, otherwise just send it me or publish it somewhere. Thanks!

    Comment by Michael Botsko — October 13, 2011 @ 9:15 am

  71. hi there is bug in formation.php file at lines 499 and 545 if default is not define then this error is coming just put


    Comment by webmasterdubai.com — November 2, 2011 @ 11:56 pm

  72. Hi

    Can i use javascript to just generate a JSON representation of the serialized form? i dont want to use php, i want to somehow generate json from the serialized form when its POSTED and then process it? Could you guide me in the right direction?

    Comment by Ali Raza — November 24, 2011 @ 7:10 am

  73. You can simply change the save method to serialize it all as json and send it wherever else you want it to go. You’d have to obviously write your own rendering system.

    Comment by Michael Botsko — November 28, 2011 @ 10:08 am

  74. [...] need to write an extension application on top of my popular jQuery Form Builder plugin so I finally took the time necessary to perform some long-wanted updates. The xml-based form [...]

    Pingback by jQuery Form Builder 0.4 | Botsko.net – Web Development in Portland, Oregon — December 15, 2011 @ 12:08 pm

  75. Hi,
    I tried your demo but the “save” button doesn’t work for me.
    The example-save.php isn’t called.
    Locally, I’ve changed the example-save.php but it seems it’s never called.

    Comment by Cricket — February 28, 2012 @ 1:03 pm

  76. Hi Michael,

    I need to develop an online survey tool for my dissertation. I thought I could use your form builder to create the surveys, but I’m a total newbie.

    Can you please give me some instructions on how to setup the form builder. I can’t get it working..I need a very very fast response. PLease.


    Comment by Fawwaaz — March 28, 2012 @ 3:01 am

  77. Hi,
    in Formbuilder.php, loadCheckboxGroup, there is $item['default'], but the default field isn’t in the produced json. Did you mean “baseline”?

    Comment by franium — May 15, 2012 @ 2:03 am

  78. Hi Michael,

    This is so cool and very usable, we are using this code as a form builder in a startup.


    Comment by netdev — May 18, 2012 @ 8:03 pm

  79. How can i add upload file element?

    Comment by jas — June 18, 2012 @ 12:46 am

  80. Hi,

    Would appreciate if someone can share a sample xml file (having form structure data).

    I have reviewed the docs in the git link provided, but couldn’t find any such samples.


    Comment by satish — June 29, 2012 @ 9:29 pm

  81. The system no longer uses xml, but rather json. The example json renderer will take the fake form value array and will render the json object: https://github.com/botskonet/jquery.formbuilder/blob/master/example-json.php

    Comment by Michael Botsko — July 2, 2012 @ 6:52 am

  82. Great plugin Mr. Botsko, thank you. I’ve taken the plugin and your custom serialize function and written a processor in Coldfusion that converts your php array to a Coldfusion array that will serialize the json correctly. In my application though, I need the user to add 1 field at a time in a modal window so that I can validate each field that is added to the builder. I append the single field of json to the existing json and everything is saved nicely, awaiting to be reloaded in a “read-only” version of the plugin that will allow for only the sorting of the fields. So far so good, except that try and ajax a new “read-only” formbuilder it’s as if the old formbuilder that was loaded initially is still remembered in the browser, and some of the buttons on the new one don’t work correctly (specifically the remove and hide buttons). I also tried to remove the “my-form-builder” div and load it into a new div, which worked but the same problem exists. I can’t seem to unload the plugin and reload it with new json without refreshing the page. So my question is how do I unload the plugin entirely, and reload the plugin on the same page without having to refresh the page? Sorry for the long question, I am hoping you or someone can shed some light. I greatly appreciate it and thanks again for this excellent formbuilder base plugin!

    Comment by Nick K — July 12, 2012 @ 3:53 pm

  83. Thanks for your comments, glad you like the plugin. I haven’t added any way to refresh the incoming data without calling the original load methods again. It would be easier to add an api the method that would trigger a refresh with a new set of json data that unloading/reloading. If you end up adding the feature, fork the project on github and send a pull request and we’ll add that.

    Comment by Michael Botsko — July 13, 2012 @ 7:44 am

  84. Hi Michael,

    I use Vantage by AppThemes, which use your jQuery Form Builder plugin to make custom fields in the posts that are made. It has input_text, Textare, checkbos, and select. I’d like to make forms which are grouped with a header for each. Is it possible for you to give me a hint on what I need to add to your code and which function I need to work on to get an extra option when building a form – an option to just make a heading – no input?

    I’m looking at fn.formbuilder = function, the first one in form-builder.js

    I assume I would have to add something like

    body += ‘‘ + l10n.text + ‘‘;

    around line 29 and around line 61 something like

    case ‘input_text’:
    appendHeading(values, required);

    and around line 78 something like

    // Heading type=”heading”
    var appendTextInput = function (values, required) {
    field += ” + l10n.label + ”;
    id = last_id;
    field += ”;
    help = ”;
    appendFieldLi(l10n.text, field, required, help);

    further down around line 384 …

    case ‘heading’:
    serialStr += opts.prepend + ‘[' + li_count + '][values]=’ + encodeURIComponent($(‘#’ + $(this).attr(‘id’) + ‘ input[type=text]‘).val());

    I know the code I’m writing here is wrong, but I got the general idea what to do, just not what to write that is correct. Any chance of any help?

    Would make the plugin even better with this option, imo :-)

    Thx for the great work, Michael! Have a great summer!

    Comment by Ray — July 20, 2012 @ 5:18 pm

RSS feed for comments on this post. TrackBack URL

Leave a comment