jQuery Dynamic Form

Update march, 2011 : I recently received tons of questions in the comments. I’m sorry to say that I’m currently not able to provide support for jQuery Dynamic Form plugin. Nevertheless, if you find bugs, I invite you to send patches to me. I’ll test them and possibly update the plugin.

jQuery Dynamic Form is a plugin for jQuery. It gives the ability to dynamically add fields based on HTML template. Update version 1.0 is out and has been uploaded on Google Code. It includes two long awaited features : nested fields duplication, and data injection. I’ll update examples when I have time, however you already have a working example package in the zip, go download it ! http://code.google.com/p/jquery-dynamic-form/downloads/list

Links

Code

All #something are references to the node element ids in the HTML dource code.
 
$(document).ready(function(){
$("#duplicate").dynamicForm("#plus", "#minus", {limit:5});
$("#duplicate2").dynamicForm("#plus2", "#minus2", {limit:4});
$("#duplicate3").dynamicForm("#plus3", "#minus3",
{
limit:3,
createColor: 'yellow',
removeColor: 'red'
}
);
});
NB : The color effects of the third demo requires the jQuery UI Highlight Effect Module

Demo

#duplicate + and - are outside the duplicated node

[-] [+]
#duplicate2 + and - are inside the duplicated node

[-] [+]

#duplicate3 Multiple fields duplication
Address
[-] [+]
This entry was posted on Thursday, June 18th, 2009 at 10:52 am and is filed under . You can follow any comments to this entry through the RSS 2.0 feed. You can leave a comment, or trackback from your own site.

122 comments

  1. Comment 3350

    Marek

    Hello Stéphane,
    Your plugin saves a lot of time. It’s really cool!

    I’ve got a little issue with nested dynamic content.
    I’ve created a nested form which has structure like the one below

    Any help highly appreciated. :)

    form {
    rule [+] [-] {
    output [+] [-] {
    output_field1 ();
    output_filed2();

    output_filter [+] [-] {
    filter_field1();
    }
    }
    }
    submit();
    }

    All works fine when I’ve got only one rule (rule0) on screen. I can add separate output objects with a filter object inside. Also filter objects are duplicated independently within outputs. However when I duplicate a new rule (rule1) and if I try to add filter within rule1 whole form destroys and reloads the page showing only rule0.

    Additionally, when I try to populate the form with data it works only untill output level. The filter level is empty.

    Please see below the code.

    <script type="text/javascript" src="lib/jquery/jquery.min.js"></script>
    <script type="text/javascript" src="lib/jquery/jquery-dynamic-form.js"></script>
    <script type="text/javascript">
    $(document).ready(function(){
          //Activate the main dynamic form
          var mainDynamicForm = $("#rule").dynamicForm("#plus", "#minus", {
                  limit:2,
                  formPrefix:"ruleList",
                  afterClone:function(clone){
                       if(window.console && window.console.log){
                            console.log("I'm a clone", clone);
                       }
                  },
                  createColor:"green"
          });
          //Activate two netsted dynamic Output forms
          $("#outputTemplate").dynamicForm("#plus2", "#minus2", {limit:5});
          $("#filterTemplate").dynamicForm("#plus3", "#minus3", {limit:5});
    </script>
    (...)

    <form method="post" action="#" value="Post">
        <fieldset id="rule">
            <legend>Rule</legend>
            <p><label for="ruleset_name">Rule name: </label><input id="ruleset_name" type="text" name="ruleset_name" size="50"></p>

            <fieldset id="outputTemplate">
                <legend>Output</legend>
                <p id='output'><input id="output" type="hidden" name="output"/>
                    <label for="compressed">Compressed : </label><input id="compressed" type="checkbox" name="compressed" /><br />
                    <label for="location">Location : </label><input id="location" type="text" value="location" name="location" size="80" /><br />
                    <fieldset id="filterTemplate">
                        <legend>Filter</legend>
                        <p id='filter'><input id="filter" type="hidden" name="filter"/>
                            <label for="desc">Description : </label><input id="desc" type="text" value="NULL" name="desc" size="80" />
                        </p>
                        <span><a id="minus3" href="">[-]</a> <a id="plus3" href="">[+]</a></span></p>
                    </fieldset> <!-- End of Filter -->
                </p>
                <p><span><a id="minus2" href="">[-]</a> <a id="plus2" href="">[+]</a></span></p>
            </fieldset> <!-- End of Output set -->
            <p><span><a id="minus" href="">[-]</a> <a id="plus" href="">[+]</a></span></p>
        </fieldset> <!-- End of Rule -->
        <input type="submit" />
    </form>
  2. Comment 3349

    Marek

    Hello Stéphane,
    Your plugin saves a lot of time. It’s really cool!

    I’ve got a little issue with nested dynamic content.
    I’ve created a nested form which has structure like the one below

    form {
    rule [+] [-] {
    output [+] [-] {
    output_field1 ();
    output_filed2();

    output_filter [+] [-] {
    filter_field1();
    }
    }
    }
    submit();
    }

    All works fine when I’ve got only one rule (rule0) on screen. I can add separate output objects with a filter object inside. Also filter objects are duplicated independently within outputs. However when I duplicate a new rule (rule1) and if I try to add filter within rule1 whole form destroys and reloads the page showing only rule0.

    Additionally, when I try to populate the form with data it works only untill output level. The filter level is empty.

    Please see below the code.

    <script type="text/javascript" src="lib/jquery/jquery.min.js"></script>
    <script type="text/javascript" src="lib/jquery/jquery-dynamic-form.js"></script>
    <script type="text/javascript">
    $(document).ready(function(){
          //Activate the main dynamic form
          var mainDynamicForm = $("#rule").dynamicForm("#plus", "#minus", {
                  limit:2,
                  formPrefix:"ruleList",
                  afterClone:function(clone){
                       if(window.console && window.console.log){
                            console.log("I'm a clone", clone);
                       }
                  },
                  createColor:"green"
          });
          //Activate two netsted dynamic Output forms
          $("#outputTemplate").dynamicForm("#plus2", "#minus2", {limit:5});
          $("#filterTemplate").dynamicForm("#plus3", "#minus3", {limit:5});
    </script>
    (...)

    <form method="post" action="#" value="Post">
        <fieldset id="rule">
            <legend>Rule</legend>
            <p><label for="ruleset_name">Rule name: </label><input id="ruleset_name" type="text" name="ruleset_name" size="50"></p>

            <fieldset id="outputTemplate">
                <legend>Output</legend>
                <p id='output'><input id="output" type="hidden" name="output"/>
                    <label for="compressed">Compressed : </label><input id="compressed" type="checkbox" name="compressed" /><br />
                    <label for="location">Location : </label><input id="location" type="text" value="location" name="location" size="80" /><br />
                    <fieldset id="filterTemplate">
                        <legend>Filter</legend>
                        <p id='filter'><input id="filter" type="hidden" name="filter"/>
                            <label for="desc">Description : </label><input id="desc" type="text" value="NULL" name="desc" size="80" />
                        </p>
                        <span><a id="minus3" href="">[-]</a> <a id="plus3" href="">[+]</a></span></p>
                    </fieldset> <!-- End of Filter -->
                </p>
                <p><span><a id="minus2" href="">[-]</a> <a id="plus2" href="">[+]</a></span></p>
            </fieldset> <!-- End of Output set -->
            <p><span><a id="minus" href="">[-]</a> <a id="plus" href="">[+]</a></span></p>
        </fieldset> <!-- End of Rule -->
        <input type="submit" />
    </form>
  3. Comment 3348

    Tai Nguyen

    Hi Stephane,

    I’ve been playing with your script a little more and am pretty sure I’ve found a bug. I’m trying to make a form with 2 levels of nesting and am seeing the form mysteriously reset itself when a certain level of nested elements have been created. I actually created a third level just to test if the bug only happens on the last level – it doesn’t. The code itself is modified from your demo code on Google Code and is pretty straightforward.

    If you click the Element “plus”, you’ll see that it creates a nested Sub Element and within that, a nested Final. That Final element has both a plus and a minus, which it shouldn’t. It should only have a plus. Clicking on the plus will reset the form.

    http://pastebin.com/qGeMwiZH

  4. Comment 3342

    Tai Nguyen

    Hi Stephane,

    First of all, thanks not only for the great script but also for being very responsive with your support.

    I think someone else asked but but I would also like to know, how can I programmatically clone fields? I would like to use the afterclone feature to create other fields which themselves can be duplicated. The nested fields are separated both visually and in the code so they can’t be nested as I understand nesting as it works now. Hmmm, could I possibly use afterclone to move the nested elements? Did I just answer my own question?

  5. Comment 3304

    Is there a way to disable the renaming of certain input fields? I’m trying to integrate this with ExpressionEngine and Freeform (an EE plugin) however FreeForm expects the field name to match its setting.

    I’m trying to concatenate the multiple fields into one field and then submit it via a hidden field, however since my hidden field is an input it is also getting renamed.

  6. Comment 3251

    Live

    Hi Stephane, I’m a beginner and know a little about jquery, php and mysql.

    Thank you for your script and hard work, it really looks promising.

    But here’s my main goal, I want to integrate this to an invoice system, where it gets its items from a MySQL database, selling office supplies.

    1. I need your script in case the user needs to add more items to the list of items in the Invoice.

    But it really looks complicated, is there a simple version of this one, where I just add/remove items from your demo?

    2. Lastly, sorry for asking too much, will Autocomplete / Autosuggest work with this one? If so, do all added items input field also have Autocomplete?

    Do you have a code for it and how to integrate autocomplete with your code?

    Thank you for your time. More power to your blogs! :)

  7. Comment 3178

    Tolu

    Can u please explain the script used in collecting the submitted data because i”m having issue trying to use it to inject user filled data back into the form elements, should a user move back and forth from a page that uses this dynamic form

  8. Comment 3107

    mrgorefest

    Is it possible to add a callback to [-] and [+] buttons?
    I want that when a user delete an item, it’s deleted from the database too.

  9. Comment 2316

    George Chloros

    Mr Stéphane Roucheray I found your plug in very useful and thanks a lot for your contribution.
    I have tried to set in a form, addable and removable input elements in second and third sub level in this form but it wasn’t possible.

    Do you have any advice for this situation?
    thanks in advance
    George

  10. Comment 1934

    Bob

    Hi there,

    First I want to say thank you to Stéphane. This is a real awesome plug-in. Thanks for the good work and the effort :)

    I’m pretty new to jQuery and I have been bustin my balls to inject some data to the form. It actually almost works. He is generation the fieldsets, but he is not filling them with the provided data.

    Here the Code:
    var lolo = [
    {
    "name" : "A",
    "length" : "B",
    "breite" : "C"
    },
    {
    "name" : "A",
    "length" : "B",
    "breite" : "C"
    },
    {
    "name" : "A",
    "length" : "B",
    "breite" : "C"
    }
    ];

    $(“#kontakt”).dynamicForm(“#plus”, “#minus”, {
    limit:10,
    createColor:”green”,
    removeColor:”red”,
    data:lolo

    });

    And the fieldset:

    Geben Sie hier die gewünschten Felder an
    Name des Textfeldes :
    Zeichenlänge :
    Breite des Textfeldes :

    Does anybody have an idea how to fix that? I would be really grateful! I wish you a nice sunday.

  11. Comment 1788

    Ty

    Great plugin, I am however currently trying to use it with jquery datepicker, however there appears to be a conflict. Do you have any idea how to resolve this?

    Thank you

  12. Comment 1498

    M

    Hi,

    I have two forms on my page… One of them is using your plugin and the other is not. When I submit the one that is not using your plugin it gets wrapped in multiple arrays.

    For example, here is the post with your plugin enabled (but not applied to this form):

    array(1) { ["formfm"]=> array(1) { ["formfm"]=> array(1) { ["data"]=> string(9) “2d3138,25″ } } }

    When I disable your plugin, on the other form, then my post looks like this:

    array(1) { ["data"]=> string(9) “2d3138,25″ }

    I love this plugin, but I am really finding the nested array thing a tad frustrating to work with on the PHP side of things. Not that I can’t handle writing PHP code to parse the nested arrays… I just wish I could get back to the basic post data (I really find it overkill to parse multiple arrays to get to my posted data).

    Here is my JS:

    $(‘form#fm’)
    .dynamicForm(“.plus”, “.minus”, {
    createColor: ‘yellow’,
    removeColor: ‘red’,
    limit: 100
    });

    As you can see, I am applying your plugin to the whole form (and not elements within the form).

    Anyway, I kinda wish I could just turn off this feature… I am working with a framework and it has some built-in $POST/$GET methods… Unfortunately, it does not work with forms that use this plugin.

    Questions:

    1. Why would your plugin affect a form on the page that does not use your plugin?

    2. How hard would it be to just turn off the nested array thing? I just want normal posted array data! :)

    I love this plugin though!

    Thanks!!!!
    M

  13. Comment 1363

    Mike

    I wanted to add masking to some duplicated form fields, and ran into issues between FF and IE 7

    I solved it like this

    Is there a better way?

    Thanks

  14. Comment 1260

    Lenny

    Hi Stéphane,

    Thank you for sharing this awesome plugin!!

    I did notice a small issue when testing it with the example code you’ve provided. For the block of the “phone2Template” if I remove the first clone (i.e. with id: phone2Template0), leaving the s with ids: phone2Template & phone2Template1 in tact and then add a new clone, the new clone will have the same id (and name) as the second clone that i didn’t remove (i.e. there’s 2 with id: phone2Template1). This will cause problems when submitting the form, because the values of last block of with id: phone2Template1 will override the original one.

    Is that a bug or is it what it is meant to do?

    Thank you very much for your help!

  15. Comment 1226

    Wild Man

    Thanks for the plugin.

    I did have one question. Is there a way to have a” remove” option for each field so you remove any value (except the first one)? Or is this something you do as a call back to insert the remove options? Regardless of approach, was wondering if you had some examples.

    I guess it would also be nice to have an add link insert in the middle as well. Thanks in advance.

  16. Comment 994

    This is a very useful jq plugin, thank you for sharing it.

    I have a couple of questions.

    1) I think I might have misunderstood something. I didn’t have much time to look over the code but it seems to have an option for a array named “subDynamicForm”.
    I can only guess that this is so we don’t have to create each subgroup manually?

    I have created a test page that is currently missing the initialization code for the plugin.
    This is done on purpose as I am trying to figure the best way to do this.

    The example has a name and lastname that aren’t part of subgroups and aren’t loaded from an array and a phone array with 2 options.

    Could you please show me the best way to complete this?

    The only sane way I figured to do this requires that I alter the plugin code.

    2) Have you ever dealt with a situation you wanted to clear the form to its initial state?
    (Reset all form inputs to default values and only have one copy of each subgroup)
    Say that I inject a json with 5 phones and then inject another with 2, there will be still 5 phone groups the 2 from the second injection and 3 left overs from the first inject.

    Thank you vercy much in advance.
    George

      • Comment 1000

        Hi George,

        My answers :
        1 – You don’t have subgroups in your code but two separate groups. A subgroups is for example when you have several people each having several phone numbers (Look there to see an example : http://code.google.com/p/jquery-dynamic-form/source/browse/trunk/index.php). From what I see in your HTML structure you have two groups, one for adding people and another for adding phone numbers (which is quit different).
        So in the case of the HTML structure you gave I would do two separated dynamic form. First rename the class of the second plus en minus button (the ones for the phone number) in order for them not to match the firsts one. And the code is :

        $("#form-details-name").dynamicForm(".plus", ".minus", {
            limit :10,
            data:
                [{
                    firstname: 'firstname value',
                    lastname: 'lastname value'
                }]
            });

        $("#form-details-phonenumber").dynamicForm(".plus1", ".minus1", {
            limit :10,
            data:
                [
                    {type: 'landline', number: '00000'},
                    {type: 'mobile', number: '111111'}
                ]
         });

        2 – One way to achieve this would be to call several time the click event on the minus button but this is not so clever or ideal. Other than that there is no internal method to do that. Sorry.

  17. Comment 906

    Jonathan

    Hi Stéphane,

    Thank you for your really awesome plugin :) Managed do a lot with it.

    Have you tried it with the latest jquery ui-autocomplete from release 1.8.2 ?

    When I combine ui-autocomplete, jeditable and your plugin, I have the following problem : the cloned autocomplete input allows for the user to select from a suggested list matching whatever is typed but the _renderItem function is not fired…

    }).data( “autocomplete” )._renderItem = function( ul, item ) {
    return $( “” )
    .data( “item.autocomplete”, item )
    .append( “” + item.label + ” ” + item.desc + “” )
    .appendTo( ul );
    };

    With the original input, it works fine. Any idea ?
    Thanks

    Jonathan

  18. Comment 835

    hainlp

    Code below work in Dreamwaever, but in asp.net is not, please help me

    Untitled Document

    $ = jQuery;
    $(document).ready(function(){
    $(“#duplicate3″).dynamicForm(“#plus3″, “#minus3″, {limit:3, createColor: ‘yellow’,removeColor: ‘red’});
    });

    #duplicate3 Multiple fields duplication

    Address
    address :

    postal code :

    city :

    [-] [+]

  19. Comment 815

    ORDER OF CALLING dynamicForm IS IMPORTANT.

    If people_email is a subsection of people, the order of the following is important:

    $(“people”).dynamicForm(“people_plus”, “people_minus”, {limit:5});
    $(“people_email”).dynamicForm(“people_email_plus”, “people_email_minus”, {limit:5});

    If you switch the order:
    $(“people_email”).dynamicForm(“people_email_plus”, “people_email_minus”, {limit:5});
    $(“people”).dynamicForm(“people_plus”, “people_minus”, {limit:5});

    It will not work (the email field gets added to the first section people ). I’m not sure if this is a bug or as designed.

    Just trying to help if anybody has this issue.

    • Comment 842

      This is not a bug. This is now by design because it would have been a lot more complex to be able to do that in any order. BTW thanks for pointing it out, I’ll update the documentation !

  20. Comment 808

    when i use multiple fields inside a fieldset with id=”form” the name gets weird like this

    name=”phone[form][0][name]“. Why is this happening?
    Im supposed to see name=”name[]“. thanks

  21. Comment 788

    Arthur

    Hello Stéphane,
    Thank you for great plugin!
    I have a little question:
    my form:

    [-] [+]

    script:

    $(document).ready(function(){
    $(“#fs1″).dynamicForm(“#plus”, “#minus”, {});
    });

    and result (body of the request):
    { t1: ‘sometext’, fs1: { fs1: { ’0′: [Object], ’1′: [Object] } }}
    I can’t understand why it redoubles fs1 object:
    … fs1: { fs1: …
    instead of making single object like this:
    { t1: ‘sdf’, fs1: { ’0′: [Object], ’1′: [Object] } }
    maybe I do something wrong?

  22. Comment 767

    mehmet

    hello stephane.i wanna thank you for ur nice forms.i like that and i want to use jquery dinamik form( #duplicate3 Multiple fields duplication) but i have to modify it.I want change it when user visit the page form must be hidden after user press + sign form must come and user see form and he can use form in the page.how can i do that.can u say me?but my english not so good ,so use basic words plz

    • Comment 776

      @Mehmet If I fully understand what you mean : you want the form to be hidden when the page load with only the plus sign visible. When the user click the first time on the plus sign, it should show the hidden form. Then, on the following clicks the form must be duplicated.
      If this is what you mean you can proceed like that :

      1. Hide the form using the CSS properties “display:none;”
      2. Assign the plus sign a click event where you show the form and at the same time initiate the dynamic form :
        function onClickPlusSign(){
          $(this).unbind('click', onClickPlusSign);
          $("#duplicate3").dynamicForm("#plus3",  "#minus3");
        }

        $("#plus3").click(onClickPlusSign);

Leave a comment