doc/book/en/devweb/edition/dissection.rst
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Wed, 18 Aug 2010 16:53:05 +0200
branchstable
changeset 6120 c000e41316ec
parent 5475 b44bad36e609
child 7635 7dce83bc2df1
permissions -rw-r--r--
[book] some more documentation and cleanups * merged existing facets documentation with the one I've just written and put almost everything within the code * added a note about __depends__ and __recommends__ and about the recommends semantic (extracted from a post on the ml) * added a note about write security checking (extracted from a post on the ml) * fixed some dumb sphinx errors
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5475
b44bad36e609 [doc/book] refresh a bit the edit controller section
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5474
diff changeset
     1
b44bad36e609 [doc/book] refresh a bit the edit controller section
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5474
diff changeset
     2
.. _form_dissection:
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
     3
5474
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
     4
Dissection of a form
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
     5
--------------------
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
     6
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
     7
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
     8
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
     9
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
    10
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    11
.. _`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
    12
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    13
Patching the session object
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    14
~~~~~~~~~~~~~~~~~~~~~~~~~~~
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    15
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    16
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
    17
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
    18
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
    19
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
    20
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    21
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
    22
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
    23
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
    24
arises.
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
.. sourcecode:: python
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    27
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    28
 def monkey_patch_session(session):
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    29
     """ 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
    30
     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
    31
     data repository session
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    32
     """
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    33
     # for autoform selection
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    34
     session.json_request = False
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    35
     session.url = lambda: u'http://perdu.com'
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    36
     session.session = session
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    37
     session.form = {}
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    38
     session.list_form_param = lambda *args: []
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    39
     # for render
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    40
     session.use_fckeditor = lambda: False
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    41
     session._ressources = []
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    42
     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
    43
     session.external_resource = lambda x:{}
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    44
     session._tabcount = 0
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    45
     def next_tabindex():
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    46
         session._tabcount += 1
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    47
         return session._tabcount
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    48
     session.next_tabindex = next_tabindex
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    49
     return session
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
Populating the database
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    52
~~~~~~~~~~~~~~~~~~~~~~~
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    53
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    54
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
    55
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
    56
version.
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
.. sourcecode:: python
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    59
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    60
 >>> 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
    61
 >>> 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
    62
 ...  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
    63
 ...
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    64
 <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
    65
 <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
    66
 >>> 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
    67
             '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
    68
 >>> commit()
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
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
    71
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    72
.. sourcecode:: python
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    73
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    74
 >>> monkey_patch_session(session)
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    75
 >>> 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
    76
 >>> html = form.render()
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    77
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    78
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
    79
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
    80
internal fieldset omitted).
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
Looking at the html output
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    83
~~~~~~~~~~~~~~~~~~~~~~~~~~
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
The form enveloppe
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    86
''''''''''''''''''
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
.. sourcecode:: html
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    89
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    90
 <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
    91
 <div class="formBody">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    92
  <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
    93
        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
    94
        class="entityForm" cubicweb:target="eformframe">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    95
    <div id="progress">validating...</div>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    96
    <fieldset>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    97
      <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
    98
      <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
    99
      <input name="__domid" type="hidden" value="entityForm" />
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   100
      <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
   101
      <input name="eid" type="hidden" value="763" />
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   102
      <input name="__maineid" type="hidden" value="763" />
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   103
      <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
   104
             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
   105
      ...
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   106
    </fieldset>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   107
   </form>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   108
 </div>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   109
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   110
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
   111
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
   112
back correctly.
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   113
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   114
The `freezeFormButtons(...)` javascript callback defined on the
5475
b44bad36e609 [doc/book] refresh a bit the edit controller section
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5474
diff changeset
   115
``onlick`` event of the form element prevents accidental multiple
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   116
clicks in a row.
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   117
5474
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   118
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
   119
(situated in :mod:`cubicweb.web.views.basecontrollers`).
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   120
5474
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   121
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
   122
:ref:`validation_process`.
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   123
5475
b44bad36e609 [doc/book] refresh a bit the edit controller section
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5474
diff changeset
   124
.. _attributes_section:
b44bad36e609 [doc/book] refresh a bit the edit controller section
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5474
diff changeset
   125
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   126
The attributes section
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
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   129
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
   130
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
   131
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   132
.. sourcecode:: html
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   133
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   134
      <fieldset class="default">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   135
        <table class="attributeForm">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   136
          <tr class="title_subject_row">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   137
            <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
   138
            <td>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   139
              <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
   140
                     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
   141
            </td>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   142
          </tr>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   143
          ... (description field omitted) ...
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   144
          <tr class="priority_subject_row">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   145
            <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
   146
            <td>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   147
              <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
   148
                <option value="important">important</option>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   149
                <option selected="selected" value="normal">normal</option>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   150
                <option value="minor">minor</option>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   151
              </select>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   152
              <div class="helper">importance</div>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   153
            </td>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   154
          </tr>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   155
          ... (type field omitted) ...
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   156
          <tr class="concerns_subject_row">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   157
            <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
   158
            <td>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   159
              <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
   160
                <option selected="selected" value="760">Foo</option>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   161
              </select>
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
          </tr>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   164
          <tr class="done_in_subject_row">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   165
            <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
   166
            <td>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   167
              <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
   168
                <option value="__cubicweb_internal_field__"></option>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   169
                <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
   170
                <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
   171
              </select>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   172
              <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
   173
            </td>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   174
          </tr>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   175
        </table>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   176
      </fieldset>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   177
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   178
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   179
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
   180
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
   181
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
   182
associated widget.
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
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
   185
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
   186
observe:
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   187
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   188
* 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
   189
  (responsability of the form renderer)
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
* an html widget (input, select, ...) with:
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
  * 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
   194
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   195
  * a name built from the same pattern
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
  * possible values or preselected options
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   198
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   199
The relations section
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   200
'''''''''''''''''''''
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   201
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   202
.. sourcecode:: html
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   203
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   204
      <fieldset class="This ticket :">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   205
        <legend>This ticket :</legend>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   206
        <table class="attributeForm">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   207
          <tr class="_cw_generic_field_None_row">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   208
            <td colspan="2">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   209
              <table id="relatedEntities">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   210
                <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
   211
                <tr id="relationSelectorRow_763" class="separator">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   212
                  <th class="labelCol">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   213
                    <select id="relationSelector_763" tabindex="8"
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   214
                            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
   215
                      <option value="">select a relation</option>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   216
                      <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
   217
                      <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
   218
                      <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
   219
                      <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
   220
                      <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
   221
                      <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
   222
                    </select>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   223
                  </th>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   224
                  <td id="unrelatedDivs_763"></td>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   225
                </tr>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   226
              </table>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   227
            </td>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   228
          </tr>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   229
        </table>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   230
      </fieldset>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   231
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   232
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
   233
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
   234
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   235
* 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
   236
  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
   237
  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
   238
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   239
* 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
   240
  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
   241
  the last div
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   242
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   243
* 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
   244
  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
   245
  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
   246
  |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
   247
  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
   248
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   249
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   250
The buttons zone
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   251
''''''''''''''''
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
Finally comes the buttons zone.
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   254
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   255
.. sourcecode:: html
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   256
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   257
      <table width="100%">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   258
        <tbody>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   259
          <tr>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   260
            <td align="center">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   261
              <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
   262
                <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
   263
                validate
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   264
              </button>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   265
            </td>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   266
            <td style="align: right; width: 50%;">
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   267
              <button class="validateButton"
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   268
                      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
   269
                      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
   270
                <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
   271
                apply
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   272
              </button>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   273
              <button class="validateButton"
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   274
                      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
   275
                      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
   276
                <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
   277
                cancel
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   278
              </button>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   279
            </td>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   280
          </tr>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   281
        </tbody>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   282
      </table>
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   283
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   284
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
   285
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
   286
submits the form.
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   287
5475
b44bad36e609 [doc/book] refresh a bit the edit controller section
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5474
diff changeset
   288
.. _validation_process:
5474
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   289
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   290
The form validation process
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
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   293
Preparation
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   294
~~~~~~~~~~~
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
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
   297
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
   298
the DOM, it:
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   299
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   300
* 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
   301
  attribute (with the same value)
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   302
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   303
* 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
   304
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   305
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
   306
irrelevant attributes.
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   307
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   308
.. sourcecode::html
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   309
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   310
  <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
   311
        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
   312
        id="entityForm" cubicweb:target="eformframe"
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   313
        target="eformframe">
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
  </form>
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   316
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   317
Validation loop
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   318
~~~~~~~~~~~~~~~
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
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
   321
``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
   322
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
   323
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   324
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
   325
``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
   326
which is then immediately executed.
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   327
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   328
.. sourcecode:: html
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   329
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   330
 <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
   331
   <script type="text/javascript">
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   332
     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
   333
                                                [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
   334
                                                null);
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   335
   </script>
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   336
 </iframe>
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
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
   339
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
   340
parameters:
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
* 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
   343
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   344
* 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
   345
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   346
* an array containing:
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
  * 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
   349
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   350
    * 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
   351
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   352
  * on success:
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   353
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   354
    * 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
   355
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   356
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
   357
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
   358
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   359
Explanation
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
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   362
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
   363
two realities:
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   364
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   365
* 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
   366
  inclusion, tolerated by Firefox)
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   367
1fc46a6287a7 [doc/book] explain the form loop validation process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   368
* 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
   369
  ajax.