I want to share with the company my own plugin that simplifies working with dynamic forms and is called jqDynaForm. By dynamic forms, I mean forms in which the user can add additional fields or field blocks as needed. Of course, in each place it is allowed to add only pre-authorized types of blocks. Here are examples of these simplest forms:
1. Contact form in which there is a "telephone" field. The user can add a few additional fields for phones, if the desire arises.
2. Invoice for payment. There is a fixed set of fields, such as “payer name” and “account number”. In addition, there is a table with positions. Each position consists of the following fields: "name", "quantity", "price". The user can add an arbitrary number of additional positions.
')
Let's look at working with jqDynaForm on the example of such an account. Here is an example of this form:

Let's look at the HTML code that needs to be prepared for the plugin:
<h1>Simple form demo</h1> <div id="smallForm"> <h2>Invoice</h2> <p>Number: <input name="number" size="6"> Payer: <input name="payer"></p> <h3>Products</h3> <div data-holder-for="product"></div> <p> </p> <input type="button" value="Save" id="saveSmallForm"> </div> <div style="display:none"> <div data-name="product" data-label="Product" class="product"> <input name="title" style="width:600px"> Price: <input name="price" style="width:100px; text-align:right"> X <input name="amount" class="short" value="1" style="width:50px"> </div> </div>
Throw out all the excess, to make it clearer:
<div> … … <div data-holder-for="<_>"></div> <input type="button" value="Save"> </div> <div data-name="_"> … … </div>
Those. we have a certain basic form with a fixed set of fields. Inside this form we place a holder, DIV, marked with the “data-holder-for” attribute. The attribute value specifies the name of the block that can be inserted here. HTML code of this block is set separately from the form and is marked with the data-name attribute.
Buttons for adding, deleting items, drag-and-drop behavior for sorting and transferring are completely configured by the plugin.
API
To get the values ​​of the form fields you need to make the following call.
var json = $(<>).jqDynaForm('get');
and it will return a JSON object of the following structure:
{ "number": "123", "payer": "Fake Incorporated", "productArray": [ { "title": "HP Pavilion g7-2010nr 17.3-Inch", "price": "499.99", "amount": "3" }, { "title": "Samsung Galaxy Tab 2 (7-Inch, Wi-Fi)", "price": "248.00", "amount": "1" }, { "title": "HP Envy 4-1030us 14-Inch Ultrabook", "price": "779.99", "amount": "1" } ] }
Note that duplicate nested blocks are automatically placed in arrays. The key values ​​in the fields are the name attribute in the INPUT and SELECT tags.
If you already have such a ready-made JSON object (formed by a script, or read from a database), then you can recreate the form with one call.
$(<__>).jqDynaForm('set', json);
After this call, we get the original form with filled fields and nested blocks formed. Of course, if you have the correct initial form and prepared blocks of fields.
The example is more complicated
In fact, the structure of the form can be much more complicated, because you can place holders not only in the basic form, but also inside the dynamic blocks. The holder can even refer to himself, form a tree-like recursive structure. Here is an example of a more complex form:

Features
I will list the most important features:
- Arbitrary HTML form code without special restrictions
- Strict specification of block nesting hierarchy structure
- Creating nesting in several levels
- Creating recursive structures
- Actions on the structure when filling out the form: Adding a block, deleting a block, sorting and dragging the block to another permitted place.
- Transformation of the form of any structure into a JSON object
- Recreating a form from a JSON object
- Creating a form without the need for programming. Customization is set by special attributes.
I also plan to add the following features:
- Simplified field validation mechanism for regular expressions
- External event handlers
Work with JSON
How to work with the resulting JSON structure. You can process it in JavaScript, you can send it to a server and turn it into a tree structure, for example, in a php-array.
Typically, field values ​​are stored in databases. With the classic "flat" forms everything is clear. This form is great to fit into one entry in the relational database table. And here the form is tree-like, and the data structure, respectively, is also tree-like. Storage options are many, here are some:
- Using MongoDB (The Most Beautiful Option)
- Store the JSON object as text in a regular relational database. But this is not always acceptable if it is necessary to execute queries to individual form fields. Therefore, consider the following compromise
- Storage of top-level fields in the fields of a relational database, and all fields of nested blocks in the form of a textual representation of JSON objects in additional fields of the same record of a relational database.
- The most boring option is to create for each type of block of fields a separate table in the relational database and populate these tables “manually”, bypassing the JSON object.
What motivated me to create this plugin
I do a lot of web application development. Many applications contain a large number of forms. Creating form handlers is often time consuming. There are all sorts of solutions that simplify the creation of ordinary, flat shapes. But when dynamic forms are required, then standard solutions, as a rule, do not help much.
Here is the typical course of working on a nightmare style project. The following requirements are received from the Customer with a certain period:
- Make a form for storing company data. There you only need the fields "name", "city", "street", "house".
- Oh! It turns out the company may have many branches. Make it possible to specify the address of each branch separately in the form.
- We thought here, we still need to, in each company in the form it was possible to write down several projects that it carried out.
- Please add a contact person to each branch. And ... Added? And how to specify the name of a person for each phone? ... We need to be able to ask a lot of contact persons in each branch and each indicate a separate phone.
In order to avoid the nightmare of constant programming of all these buttons - “add”, “delete”, “transfer”, not to suffer with the formation of dynamic structures, it is convenient to process the field values, I thought about creating this plug-in.
Sources
I warn you in advance that the plugin is still raw. But if society has an interest, then I plan to refine it and post the following versions.
Project page is on
Google CodeDownload the
working example and source code here.And here, you can
play with a live example.PS: I will be glad to know your opinion.