=====
Forms
=====

One of the key concepts of the framework is the concept of form.
Forms are based on HTML templates that generally determine their layout.

You can define form templates for viewing and editing data, as well as
for specifying filters. For reports, form templates for editing 
report parameters can be specified. Form templates are defined in the
*index.html* file, located in the root folder of the project. See 
:doc:`Form templates <form_templates>`
for details

For example, the edit form of the Customers catalog in the
:doc:`Demo project </intro/demo_project>`


.. image:: /programming/_images/customer_edit.png
	:align: center
	:alt: Customer edit form

is based on the following template:

.. code-block:: html

    <div class="customers-edit">
        <div class="modal-body">
            <div class="edit-body">
            </div>
        </div>
        <div class="modal-footer">
            <button type="button" id="cancel-btn" class="btn pull-right">
                <i class="icon-remove"></i> Cancel
            </button>
            <button type="button" id="ok-btn" class="btn pull-right">
                <i class="icon-ok"></i> OK<small class="muted">&nbsp;[Ctrl+Enter]</small>
            </button>
        </div>
    </div>
    
To create a form you can use a ``create_prefix_form`` method, where 
``prefix`` is a type of the form (view, edit, filter, param). For example, the
:doc:`create_edit_form </refs/client/item/m_create_edit_form>`
will create an edit form.

The method finds corresponding html template. If ``container`` (a Jquery object) 
parameter is specified, the method empties it and appends the html template to 
it, otherwise, it creates an empty modal form and appends the template to the 
form. After this it assigns item's ``prefix_form`` attibute to the template, 
triggers an ``on_prefix_form_created`` events, shows the form and triggers 
``on_prefix_form_shown`` events. See :doc:`Form events <form_events>` for details.

.. note::

    Usually the create form method is used internally by other items method.

Below is an example of the ``on_edit_form_created`` event handler:

.. code-block:: js

    function on_edit_form_created(item) {
        item.create_inputs(item.edit_form.find(".edit-body"));
        item.edit_form.find("#cancel-btn").on('click', function() { 
            item.cancel_edit() 
        });
        item.edit_form.find("#ok-btn").on('click', function() { 
            item.apply_record() 
        });
    }

In this example, the 
:doc:`edit_form </refs/client/item/at_edit_form>`
attribute, that is a JQuery object representing the form, is used to find 
elements on the form - a div element with edit-body class and two buttons. 

Then the 
:doc:`create_inputs </refs/client/item/m_create_inputs>`
method is used to create inputs in the div element and the JQuery ``on`` method 
attaches event handlers to the buttons.

So 
:doc:`cancel_edit </refs/client/item/m_cancel_edit>`
and
:doc:`apply_record </refs/client/item/m_apply_record>` methods will be executed 
when user clicks on the buttons. This methods cancel or apply changes made to 
the record respectively and call the 
:doc:`close_edit_form </refs/client/item/m_close_edit_form>`
method to close the form.

The ``close_prefix_form``, where ``prefix`` is the type of the form, closes the
form of this type. But before form is closed the ``on_prefix_form_close_query`` 
and ``on_prefix_form_closed`` events are triggered. After form is closed it is 
removed from the DOM.

The methods to create and close forms are used internally by other methods:

* :doc:`view </refs/client/item/m_view>` - the method check if the javascript 
  modules of an item and its owner are loaded (see 
  :doc:`Dynamic JS modules loading parameter </admin/project/parameters>`
  of the project), and if not, it loads them, after that it creates a view form 
  of an item.
  
* :doc:`append_record </refs/client/item/m_append_record>`,
  :doc:`insert_record </refs/client/item/m_insert_record>` and
  :doc:`edit_record </refs/client/item/m_edit_record>` methods - this methods
  set an item in an insert or edit mode respectively (see
  :doc:`Modifying datasets </programming/data/modifying_datasets>`
  ) and after that create an edit form of an item.
  
* :doc:`apply_record </refs/client/item/m_apply_record>` - this method makes an
  asyncronious call to the server to write data changes to the database and, when 
  changes are written, closes edit form.

* :doc:`cancel_edit </refs/client/item/m_cancel_edit>` - cancel changes and 
  closes an edit form
