doc/book/en/devweb/edition/form.rst
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Mon, 17 May 2010 11:04:52 +0200
branchstable
changeset 5526 4fcb0c132098
parent 5465 a838ac0ff890
child 5869 8a129b3a5aff
permissions -rw-r--r--
[facet] control i18nization of values on AttributeFacet
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
     1
HTML form construction
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
     2
----------------------
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
     3
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
     4
CubicWeb provides the somewhat usual form / field / widget / renderer abstraction
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
     5
to provide generic building blocks which will greatly help you in building forms
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
     6
properly integrated with CubicWeb (coherent display, error handling, etc...),
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
     7
while keeping things as flexible as possible.
4443
83ff2bb898a5 start documenting forms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2172
diff changeset
     8
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
     9
A ``form`` basically only holds a set of ``fields``, and has te be bound to a
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    10
``renderer`` which is responsible to layout them. Each field is bound to a
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    11
``widget`` that will be used to fill in value(s) for that field (at form
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    12
generation time) and 'decode' (fetch and give a proper Python type to) values
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    13
sent back by the browser.
4443
83ff2bb898a5 start documenting forms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2172
diff changeset
    14
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    15
The ``field`` should be used according to the type of what you want to edit.
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    16
E.g. if you want to edit some date, you'll have to use the
5400
b7ab099b128a [doc/book] various content fixes
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
    17
:class:`cubicweb.web.formfields.DateField`. Then you can choose among multiple
b7ab099b128a [doc/book] various content fixes
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
    18
widgets to edit it, for instance :class:`cubicweb.web.formwidgets.TextInput` (a
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    19
bare text field), :class:`~cubicweb.web.formwidgets.DateTimePicker` (a simple
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    20
calendar) or even :class:`~cubicweb.web.formwidgets.JQueryDatePicker` (the JQuery
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    21
calendar).  You can of course also write your own widget.
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    22
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    23
Exploring the available forms
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    24
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    25
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    26
A small excursion into a |cubicweb| shell is the quickest way to
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    27
discover available forms (or application objects in general).
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    28
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    29
.. sourcecode:: python
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    30
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    31
 >>> from pprint import pprint
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    32
 >>> pprint( session.vreg['forms'] )
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    33
 {'base': [<class 'cubicweb.web.views.forms.FieldsForm'>,
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    34
           <class 'cubicweb.web.views.forms.EntityFieldsForm'>],
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    35
  'changestate': [<class 'cubicweb.web.views.workflow.ChangeStateForm'>,
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    36
                  <class 'cubes.tracker.views.forms.VersionChangeStateForm'>],
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    37
  'composite': [<class 'cubicweb.web.views.forms.CompositeForm'>,
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    38
                <class 'cubicweb.web.views.forms.CompositeEntityForm'>],
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    39
  'deleteconf': [<class 'cubicweb.web.views.editforms.DeleteConfForm'>],
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    40
  'edition': [<class 'cubicweb.web.views.autoform.AutomaticEntityForm'>,
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    41
              <class 'cubicweb.web.views.workflow.TransitionEditionForm'>,
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    42
              <class 'cubicweb.web.views.workflow.StateEditionForm'>],
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    43
  'logform': [<class 'cubicweb.web.views.basetemplates.LogForm'>],
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    44
  'massmailing': [<class 'cubicweb.web.views.massmailing.MassMailingForm'>],
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    45
  'muledit': [<class 'cubicweb.web.views.editforms.TableEditForm'>],
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    46
  'sparql': [<class 'cubicweb.web.views.sparql.SparqlForm'>]}
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    47
4443
83ff2bb898a5 start documenting forms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2172
diff changeset
    48
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    49
The two most important form families here (for all pracitcal purposes)
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    50
are `base` and `edition`. Most of the time one wants alterations of
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    51
the AutomaticEntityForm (from the `edition` category).
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    52
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    53
The Automatic Entity Form
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    54
~~~~~~~~~~~~~~~~~~~~~~~~~
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    55
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    56
.. automodule:: cubicweb.web.views.autoform
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    57
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    58
Anatomy of a choices function
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    59
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4465
18fb359f5c7a fix wrong autoclass inclusion
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4443
diff changeset
    60
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    61
Let's have a look at the `ticket_done_in_choices` function given to
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    62
the `choices` parameter of the relation tag that is applied to the
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    63
('Ticket', 'done_in', '*') relation definition, as it is both typical
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    64
and sophisticated enough. This is a code snippet from the `tracker`_
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    65
cube.
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    66
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    67
.. _`tracker`: http://www.cubicweb.org/project/cubicweb-tracker
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    68
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    69
The ``Ticket`` entity type can be related to a ``Project`` and a
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    70
``Version``, respectively through the ``concerns`` and ``done_in``
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    71
relations. When a user is about to edit a ticket, we want to fill the
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    72
combo box for the ``done_in`` relation with values pertinent with
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    73
respect to the context. The important context here is:
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    74
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    75
* creation or modification (we cannot fetch values the same way in
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    76
  either case)
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    77
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    78
* ``__linkto`` url parameter given in a creation context
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    79
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    80
.. sourcecode:: python
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    81
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    82
    from cubicweb.web import formfields
4443
83ff2bb898a5 start documenting forms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2172
diff changeset
    83
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    84
    def ticket_done_in_choices(form, field):
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    85
        entity = form.edited_entity
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    86
        # first see if its specified by __linkto form parameters
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    87
        linkedto = formfields.relvoc_linkedto(entity, 'done_in', 'subject')
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    88
        if linkedto:
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    89
            return linkedto
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    90
        # it isn't, get initial values
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    91
        vocab = formfields.relvoc_init(entity, 'done_in', 'subject')
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    92
        veid = None
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    93
        # try to fetch the (already or pending) related version and project
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    94
        if not entity.has_eid():
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    95
            peids = entity.linked_to('concerns', 'subject')
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    96
            peid = peids and peids[0]
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    97
        else:
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    98
            peid = entity.project.eid
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    99
            veid = entity.done_in and entity.done_in[0].eid
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   100
        if peid:
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   101
            # we can complete the vocabulary with relevant values
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   102
            rschema = form._cw.vreg.schema['done_in'].rdef('Ticket', 'Version')
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   103
            rset = form._cw.execute(
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   104
                'Any V, VN ORDERBY version_sort_value(VN) '
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   105
                'WHERE V version_of P, P eid %(p)s, V num VN, '
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   106
                'V in_state ST, NOT ST name "published"', {'p': peid}, 'p')
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   107
            vocab += [(v.view('combobox'), v.eid) for v in rset.entities()
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   108
                      if rschema.has_perm(form._cw, 'add', toeid=v.eid)
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   109
                      and v.eid != veid]
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   110
        return vocab
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   111
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   112
The first thing we have to do is fetch potential values from the
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   113
``__linkto`` url parameter that is often found in entity creation
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   114
contexts (the creation action provides such a parameter with a
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   115
predetermined value; for instance in this case, ticket creation could
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   116
occur in the context of a `Version` entity). The
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   117
:mod:`cubicweb.web.formfields` module provides a ``relvoc_linkedto``
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   118
utility function that gets a list suitably filled with vocabulary
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   119
values.
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   120
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   121
.. sourcecode:: python
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   122
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   123
        linkedto = formfields.relvoc_linkedto(entity, 'done_in', 'subject')
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   124
        if linkedto:
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   125
            return linkedto
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   126
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   127
Then, if no ``__linkto`` argument was given, we must prepare the
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   128
vocabulary with an initial empty value (because `done_in` is not
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   129
mandatory, we must allow the user to not select a verson) and already
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   130
linked values. This is done with the ``relvoc_init`` function.
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   131
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   132
.. sourcecode:: python
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   133
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   134
        vocab = formfields.relvoc_init(entity, 'done_in', 'subject')
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   135
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   136
But then, we have to give more: if the ticket is related to a project,
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   137
we should provide all the non published versions of this project
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   138
(`Version` and `Project` can be related through the `version_of`
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   139
relation). Conversely, if we do not know yet the project, it would not
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   140
make sense to propose all existing versions as it could potentially
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   141
lead to incoherences. Even if these will be caught by some
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   142
RQLConstraint, it is wise not to tempt the user with error-inducing
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   143
candidate values.
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   144
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   145
The "ticket is related to a project" part must be decomposed as:
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   146
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   147
* this is a new ticket which is created is the context of a project
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   148
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   149
* this is an already existing ticket, linked to a project (through the
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   150
  `concerns` relation)
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   151
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   152
* there is no related project (quite unlikely given the cardinality of
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   153
  the `concerns` relation, so it can only mean that we are creating a
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   154
  new ticket, and a project is about to be selected but there is no
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   155
  ``__linkto`` argument)
4443
83ff2bb898a5 start documenting forms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2172
diff changeset
   156
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   157
.. note::
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
   158
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   159
   the last situation could happen in several ways, but of course in a
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   160
   polished application, the paths to ticket creation should be
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   161
   controlled so as to avoid a suboptimal end-user experience
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   162
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   163
Hence, we try to fetch the related project.
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   164
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   165
.. sourcecode:: python
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   166
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   167
        veid = None
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   168
        if not entity.has_eid():
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   169
            peids = entity.linked_to('concerns', 'subject')
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   170
            peid = peids and peids[0]
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   171
        else:
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   172
            peid = entity.project.eid
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   173
            veid = entity.done_in and entity.done_in[0].eid
4743
026a89520184 [book] a few autoclasses for renderers, misc tweaks
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4465
diff changeset
   174
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   175
We distinguish between entity creation and entity modification using
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   176
the ``Entity.has_eid()`` method, which returns `False` on creation. At
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   177
creation time the only way to get a project is through the
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   178
``__linkto`` parameter. Notice that we fetch the version in which the
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   179
ticket is `done_in` if any, for later.
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   180
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   181
.. note::
4743
026a89520184 [book] a few autoclasses for renderers, misc tweaks
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4465
diff changeset
   182
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   183
  the implementation above assumes that if there is a ``__linkto``
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   184
  parameter, it is only about a project. While it makes sense most of
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   185
  the time, it is not an absolute. Depending on how an entity creation
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   186
  action action url is built, several outcomes could be possible
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   187
  there
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   188
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   189
If the ticket is already linked to a project, fetching it is
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   190
trivial. Then we add the relevant version to the initial vocabulary.
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   191
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   192
.. sourcecode:: python
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   193
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   194
        if peid:
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   195
            rschema = form._cw.vreg.schema['done_in'].rdef('Ticket', 'Version')
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   196
            rset = form._cw.execute(
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   197
                'Any V, VN ORDERBY version_sort_value(VN) '
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   198
                'WHERE V version_of P, P eid %(p)s, V num VN, '
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   199
                'V in_state ST, NOT ST name "published"', {'p': peid})
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   200
            vocab += [(v.view('combobox'), v.eid) for v in rset.entities()
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   201
                      if rschema.has_perm(form._cw, 'add', toeid=v.eid)
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   202
                      and v.eid != veid]
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   203
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   204
.. warning::
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   205
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   206
   we have to defend ourselves against lack of a project eid. Given
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   207
   the cardinality of the `concerns` relation, there *must* be a
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   208
   project, but this rule can only be enforced at validation time,
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   209
   which will happen of course only after form subsmission
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   210
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   211
Here, given a project eid, we complete the vocabulary with all
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   212
unpublished versions defined in the project (sorted by number) for
5465
a838ac0ff890 [doc/book] not anymore ...
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5464
diff changeset
   213
which the current user is allowed to establish the relation.
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   214
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   215
APIs
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   216
~~~~
5418
4f0047cfecb5 [doc] reorganize for chapter structure
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5400
diff changeset
   217
4f0047cfecb5 [doc] reorganize for chapter structure
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5400
diff changeset
   218
.. automodule:: cubicweb.web.formfields
4f0047cfecb5 [doc] reorganize for chapter structure
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5400
diff changeset
   219
.. automodule:: cubicweb.web.formwidgets
4f0047cfecb5 [doc] reorganize for chapter structure
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5400
diff changeset
   220
.. automodule:: cubicweb.web.views.forms
4f0047cfecb5 [doc] reorganize for chapter structure
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5400
diff changeset
   221
.. automodule:: cubicweb.web.views.formrenderers
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   222
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   223