doc/book/en/devweb/edition/dissection.rst
author Aurelien Campeas <aurelien.campeas@logilab.fr>
Wed, 05 May 2010 15:29:39 +0200
branchstable
changeset 5474 1fc46a6287a7
parent 5464 c6c9a80ad1dd
child 5475 b44bad36e609
permissions -rw-r--r--
[doc/book] explain the form loop validation process
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
     1
5474
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
     2
Dissection of a form
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
     3
--------------------
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
     4
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
     5
This is done (again) with a vanilla instance of the `tracker`_
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
     6
cube. We will populate the database with a bunch of entities and see
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
     7
what kind of job the automatic entity form does.
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
     8
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
     9
.. _`tracker`: http://www.cubicweb.org/project/cubicweb-tracker
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    10
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    11
Patching the session object
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    12
~~~~~~~~~~~~~~~~~~~~~~~~~~~
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    13
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    14
In order to play interactively with web side application objects, we
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    15
have to cheat a bit: we will decorate the session object with some
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    16
missing artifacts that should belong to a web request object. With
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    17
that we can instantiate and render forms interactively.
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    18
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    19
The function below does the minimum to allow going through this
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    20
exercice. Some attributes or methods may be missing for other
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    21
purposes. It is nevertheless not complicated to enhance it if need
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    22
arises.
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    23
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    24
.. sourcecode:: python
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    25
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    26
 def monkey_patch_session(session):
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    27
     """ useful to use the cw shell session object
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    28
     with web appobjects, which expect more than a plain
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    29
     data repository session
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    30
     """
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    31
     # for autoform selection
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    32
     session.json_request = False
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    33
     session.url = lambda: u'http://perdu.com'
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    34
     session.session = session
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    35
     session.form = {}
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    36
     session.list_form_param = lambda *args: []
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    37
     # for render
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    38
     session.use_fckeditor = lambda: False
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    39
     session._ressources = []
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    40
     session.add_js = session.add_css = lambda *args: session._ressources.append(args)
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    41
     session.external_resource = lambda x:{}
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    42
     session._tabcount = 0
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    43
     def next_tabindex():
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    44
         session._tabcount += 1
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    45
         return session._tabcount
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    46
     session.next_tabindex = next_tabindex
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    47
     return session
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    48
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    49
Populating the database
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    50
~~~~~~~~~~~~~~~~~~~~~~~
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    51
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    52
We should start by setting up a bit of context: a project with two
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    53
unpublished versions, and a ticket linked to the project and the first
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    54
version.
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    55
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    56
.. sourcecode:: python
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    57
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    58
 >>> p = rql('INSERT Project P: P name "cubicweb"')
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    59
 >>> for num in ('0.1.0', '0.2.0'):
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    60
 ...  rql('INSERT Version V: V num "%s", V version_of P WHERE P eid %%(p)s' % num, {'p': p[0][0]})
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    61
 ...
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    62
 <resultset 'INSERT Version V: V num "0.1.0", V version_of P WHERE P eid %(p)s' (1 rows): [765L] (('Version',))>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    63
 <resultset 'INSERT Version V: V num "0.2.0", V version_of P WHERE P eid %(p)s' (1 rows): [766L] (('Version',))>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    64
 >>> t = rql('INSERT Ticket T: T title "let us write more doc", T done_in V, '
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    65
             'T concerns P WHERE V num "0.1.0"', P eid %(p)s', {'p': p[0][0]})
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    66
 >>> commit()
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    67
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    68
Now let's see what the edition form builds for us.
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    69
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    70
.. sourcecode:: python
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    71
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    72
 >>> monkey_patch_session(session)
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    73
 >>> form = session.vreg['forms'].select('edition', session, rset=rql('Ticket T'))
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    74
 >>> html = form.render()
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    75
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    76
This creates an automatic entity form. The ``.render()`` call yields
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    77
an html (unicode) string. The html output is shown below (with
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    78
internal fieldset omitted).
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    79
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    80
Looking at the html output
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    81
~~~~~~~~~~~~~~~~~~~~~~~~~~
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    82
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    83
The form enveloppe
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    84
''''''''''''''''''
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    85
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    86
.. sourcecode:: html
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    87
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    88
 <div class="iformTitle"><span>main informations</span></div>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    89
 <div class="formBody">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    90
  <form action="http://crater:9999/validateform" method="post" enctype="application/x-www-form-urlencoded"
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    91
        id="entityForm" onsubmit="return freezeFormButtons(&#39;entityForm&#39;);"
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    92
        class="entityForm" cubicweb:target="eformframe">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    93
    <div id="progress">validating...</div>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    94
    <fieldset>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    95
      <input name="__form_id" type="hidden" value="edition" />
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    96
      <input name="__errorurl" type="hidden" value="http://perdu.com#entityForm" />
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    97
      <input name="__domid" type="hidden" value="entityForm" />
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    98
      <input name="__type:763" type="hidden" value="Ticket" />
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    99
      <input name="eid" type="hidden" value="763" />
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   100
      <input name="__maineid" type="hidden" value="763" />
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   101
      <input name="_cw_edited_fields:763" type="hidden"
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   102
             value="concerns-subject,done_in-subject,priority-subject,type-subject,title-subject,description-subject,__type,_cw_generic_field" />
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   103
      ...
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   104
    </fieldset>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   105
   </form>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   106
 </div>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   107
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   108
The main fieldset encloses a set of hidden fields containing various
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   109
metadata, that will be used by the `edit controller` to process it
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   110
back correctly.
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   111
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   112
The `freezeFormButtons(...)` javascript callback defined on the
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   113
``conlick`` event of the form element prevents accidental multiple
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   114
clicks in a row.
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   115
5474
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   116
The ``action`` of the form is mapped to the ``validateform`` controller
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   117
(situated in :mod:`cubicweb.web.views.basecontrollers`).
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   118
5474
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   119
A full explanation of the validation loop is given in
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   120
:ref:`validation_process`.
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   121
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   122
The attributes section
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   123
''''''''''''''''''''''
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   124
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   125
We can have a look at some of the inner nodes of the form. Some fields
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   126
are omitted as they are redundant for our purposes.
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   127
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   128
.. sourcecode:: html
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   129
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   130
      <fieldset class="default">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   131
        <table class="attributeForm">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   132
          <tr class="title_subject_row">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   133
            <th class="labelCol"><label class="required" for="title-subject:763">title</label></th>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   134
            <td>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   135
              <input id="title-subject:763" maxlength="128" name="title-subject:763" size="45"
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   136
                     tabindex="1" type="text" value="let us write more doc" />
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   137
            </td>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   138
          </tr>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   139
          ... (description field omitted) ...
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   140
          <tr class="priority_subject_row">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   141
            <th class="labelCol"><label class="required" for="priority-subject:763">priority</label></th>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   142
            <td>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   143
              <select id="priority-subject:763" name="priority-subject:763" size="1" tabindex="4">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   144
                <option value="important">important</option>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   145
                <option selected="selected" value="normal">normal</option>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   146
                <option value="minor">minor</option>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   147
              </select>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   148
              <div class="helper">importance</div>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   149
            </td>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   150
          </tr>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   151
          ... (type field omitted) ...
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   152
          <tr class="concerns_subject_row">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   153
            <th class="labelCol"><label class="required" for="concerns-subject:763">concerns</label></th>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   154
            <td>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   155
              <select id="concerns-subject:763" name="concerns-subject:763" size="1" tabindex="6">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   156
                <option selected="selected" value="760">Foo</option>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   157
              </select>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   158
            </td>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   159
          </tr>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   160
          <tr class="done_in_subject_row">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   161
            <th class="labelCol"><label for="done_in-subject:763">done in</label></th>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   162
            <td>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   163
              <select id="done_in-subject:763" name="done_in-subject:763" size="1" tabindex="7">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   164
                <option value="__cubicweb_internal_field__"></option>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   165
                <option selected="selected" value="761">Foo 0.1.0</option>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   166
                <option value="762">Foo 0.2.0</option>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   167
              </select>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   168
              <div class="helper">version in which this ticket will be / has been  done</div>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   169
            </td>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   170
          </tr>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   171
        </table>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   172
      </fieldset>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   173
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   174
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   175
Note that the whole form layout has been computed by the form
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   176
renderer. It is the renderer which produces the table
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   177
structure. Otherwise, the fields html structure is emitted by their
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   178
associated widget.
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   179
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   180
While it is called the `attributes` section of the form, it actually
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   181
contains attributes and *mandatory relations*. For each field, we
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   182
observe:
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   183
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   184
* a dedicated row with a specific class, such as ``title_subject_row``
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   185
  (responsability of the form renderer)
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   186
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   187
* an html widget (input, select, ...) with:
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   188
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   189
  * an id built from the ``rtype-role:eid`` pattern
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   190
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   191
  * a name built from the same pattern
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   192
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   193
  * possible values or preselected options
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   194
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   195
The relations section
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   196
'''''''''''''''''''''
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   197
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   198
.. sourcecode:: html
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   199
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   200
      <fieldset class="This ticket :">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   201
        <legend>This ticket :</legend>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   202
        <table class="attributeForm">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   203
          <tr class="_cw_generic_field_None_row">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   204
            <td colspan="2">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   205
              <table id="relatedEntities">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   206
                <tr><th>&#160;</th><td>&#160;</td></tr>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   207
                <tr id="relationSelectorRow_763" class="separator">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   208
                  <th class="labelCol">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   209
                    <select id="relationSelector_763" tabindex="8"
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   210
                            onchange="javascript:showMatchingSelect(this.options[this.selectedIndex].value,763);">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   211
                      <option value="">select a relation</option>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   212
                      <option value="appeared_in_subject">appeared in</option>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   213
                      <option value="custom_workflow_subject">custom workflow</option>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   214
                      <option value="depends_on_object">dependency of</option>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   215
                      <option value="depends_on_subject">depends on</option>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   216
                      <option value="identical_to_subject">identical to</option>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   217
                      <option value="see_also_subject">see also</option>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   218
                    </select>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   219
                  </th>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   220
                  <td id="unrelatedDivs_763"></td>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   221
                </tr>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   222
              </table>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   223
            </td>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   224
          </tr>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   225
        </table>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   226
      </fieldset>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   227
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   228
The optional relations are grouped into a drop-down combo
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   229
box. Selection of an item triggers a javascript function which will:
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   230
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   231
* show already related entities in the div of id `relatedentities`
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   232
  using a two-colown layout, with an action to allow deletion of
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   233
  individual relations (there are none in this example)
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   234
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   235
* provide a relation selector in the div of id `relationSelector_EID`
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   236
  to allow the user to set up relations and trigger dynamic action on
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   237
  the last div
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   238
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   239
* fill the div of id `unrelatedDivs_EID` with a dynamically computed
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   240
  selection widget allowing direct selection of an unrelated (but
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   241
  relatable) entity or a switch towards the `search mode` of
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   242
  |cubicweb| which allows full browsing and selection of an entity
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   243
  using a dedicated action situated in the left column boxes.
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   244
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   245
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   246
The buttons zone
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   247
''''''''''''''''
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   248
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   249
Finally comes the buttons zone.
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   250
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   251
.. sourcecode:: html
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   252
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   253
      <table width="100%">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   254
        <tbody>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   255
          <tr>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   256
            <td align="center">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   257
              <button class="validateButton" tabindex="9" type="submit" value="validate">
5474
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   258
                <img alt="OK_ICON" src="http://myapp/datafd8b5d92771209ede1018a8d5da46a37/ok.png" />
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   259
                validate
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   260
              </button>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   261
            </td>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   262
            <td style="align: right; width: 50%;">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   263
              <button class="validateButton"
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   264
                      onclick="postForm(&#39;__action_apply&#39;, &#39;button_apply&#39;, &#39;entityForm&#39;)"
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   265
                      tabindex="10" type="button" value="apply">
5474
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   266
                <img alt="APPLY_ICON" src="http://myapp/datafd8b5d92771209ede1018a8d5da46a37/plus.png" />
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   267
                apply
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   268
              </button>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   269
              <button class="validateButton"
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   270
                      onclick="postForm(&#39;__action_cancel&#39;, &#39;button_cancel&#39;, &#39;entityForm&#39;)"
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   271
                      tabindex="11" type="button" value="cancel">
5474
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   272
                <img alt="CANCEL_ICON" src="http://myapp/datafd8b5d92771209ede1018a8d5da46a37/cancel.png" />
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   273
                cancel
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   274
              </button>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   275
            </td>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   276
          </tr>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   277
        </tbody>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   278
      </table>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   279
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   280
The most notable artifacts here are the ``postForm(...)`` calls
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   281
defined on click events on these buttons. This function basically
5474
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   282
submits the form.
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   283
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   284
.. validation_process::
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   285
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   286
The form validation process
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   287
---------------------------
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   288
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   289
Preparation
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   290
~~~~~~~~~~~
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   291
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   292
After the (html) document is loaded, the ``setFormsTarget`` javascript
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   293
function dynamically transforms the DOM as follows. For all forms of
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   294
the DOM, it:
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   295
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   296
* sets the ``target`` attribute where there is a ``cubicweb:target``
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   297
  attribute (with the same value)
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   298
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   299
* appends an empty `IFRAME` element at the end
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   300
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   301
Let us have a look again at the form element. We have omitted some
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   302
irrelevant attributes.
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   303
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   304
.. sourcecode::html
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   305
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   306
  <form action="http://crater:9999/validateform" method="post"
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   307
        enctype="application/x-www-form-urlencoded"
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   308
        id="entityForm" cubicweb:target="eformframe"
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   309
        target="eformframe">
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   310
  ...
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   311
  </form>
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   312
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   313
Validation loop
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   314
~~~~~~~~~~~~~~~
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   315
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   316
On form submission, the form.action is invoked. Basically, the
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   317
``validateform`` controller is called and its output lands in the
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   318
specified ``target``, the iframe that was previously prepared.
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   319
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   320
Hence, the main page is not replaced, only the iframe contents. The
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   321
``validateform`` controller only outputs a tiny javascript fragment
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   322
which is then immediately executed.
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   323
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   324
.. sourcecode:: html
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   325
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   326
 <iframe width="0px" height="0px" name="eformframe" id="eformframe" src="javascript: void(0)">
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   327
   <script type="text/javascript">
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   328
     window.parent.handleFormValidationResponse('entityForm', null, null,
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   329
                                                [false, [2164, {"name-subject": "required field"}], null],
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   330
                                                null);
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   331
   </script>
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   332
 </iframe>
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   333
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   334
The ``window.parent`` part ensures the javascript function is called
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   335
on the right context (that is: the form element). We will describe its
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   336
parameters:
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   337
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   338
* first comes the form id (`entityForm`)
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   339
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   340
* then two optional callbacks for the success and failure case
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   341
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   342
* an array containing:
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   343
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   344
  * a boolean which indicates status (success or failure), and then, on error:
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   345
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   346
    * an array structured as ``[eid, {'rtype-role': 'error msg'}, ...]``
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   347
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   348
  * on success:
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   349
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   350
    * an url (string) representing the next thing to jump to
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   351
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   352
Given the array structure described above, it is quite simple to
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   353
manipulate the DOM to show the errors at appropriate places.
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   354
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   355
Explanation
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   356
~~~~~~~~~~~
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   357
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   358
This mecanism may seem a bit overcomplicated but we have to deal with
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   359
two realities:
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   360
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   361
* in the (strict) XHTML world, there are no iframes (hence the dynamic
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   362
  inclusion, tolerated by Firefox)
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   363
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   364
* no (or not all) browser(s) support file input field handling through
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   365
  ajax.