doc/book/devweb/edition/form.rst
author Philippe Pepiot <ph@itsalwaysdns.eu>
Tue, 31 Mar 2020 19:15:03 +0200
changeset 12957 0c973204033a
parent 12556 d1c659d70368
permissions -rw-r--r--
[server] prevent returning closed cursor to the database pool In since c8c6ad8 init_repository use repo.internal_cnx() instead of repo.system_source.get_connection() so it use the pool and we should not close cursors from the pool before returning it back. Otherwise we may have "connection already closed" error. This bug only trigger when connection-pool-size = 1. Since we are moving to use a dynamic pooler we need to get this fixed. This does not occur with sqlite since the connection wrapper instantiate new cursor everytime, but this occur with other databases.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5869
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5465
diff changeset
     1
.. _webform:
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5465
diff changeset
     2
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
     3
HTML form construction
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
     4
----------------------
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
     5
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
     6
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
     7
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
     8
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
     9
while keeping things as flexible as possible.
4443
83ff2bb898a5 start documenting forms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2172
diff changeset
    10
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    11
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
    12
``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
    13
``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
    14
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
    15
sent back by the browser.
4443
83ff2bb898a5 start documenting forms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2172
diff changeset
    16
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    17
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
    18
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
    19
: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
    20
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
    21
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
    22
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
    23
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
    24
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    25
Exploring the available forms
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    26
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    27
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    28
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
    29
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
    30
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    31
.. sourcecode:: python
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    32
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    33
 >>> from pprint import pprint
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    34
 >>> pprint( session.vreg['forms'] )
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    35
 {'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
    36
           <class 'cubicweb.web.views.forms.EntityFieldsForm'>],
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    37
  'changestate': [<class 'cubicweb.web.views.workflow.ChangeStateForm'>,
12556
d1c659d70368 [doc] replace legacy import to new style cube import in various places
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 10491
diff changeset
    38
                  <class 'cubicweb_tracker.views.forms.VersionChangeStateForm'>],
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    39
  '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
    40
                <class 'cubicweb.web.views.forms.CompositeEntityForm'>],
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    41
  '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
    42
  '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
    43
              <class 'cubicweb.web.views.workflow.TransitionEditionForm'>,
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    44
              <class 'cubicweb.web.views.workflow.StateEditionForm'>],
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    45
  '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
    46
  '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
    47
  '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
    48
  '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
    49
4443
83ff2bb898a5 start documenting forms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2172
diff changeset
    50
7643
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
    51
The two most important form families here (for all practical purposes) are `base`
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
    52
and `edition`. Most of the time one wants alterations of the
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
    53
:class:`AutomaticEntityForm` to generate custom forms to handle edition of an
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
    54
entity.
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
The Automatic Entity Form
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    57
~~~~~~~~~~~~~~~~~~~~~~~~~
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    58
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    59
.. 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
    60
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    61
Anatomy of a choices function
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    62
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4465
18fb359f5c7a fix wrong autoclass inclusion
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4443
diff changeset
    63
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    64
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
    65
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
    66
('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
    67
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
    68
cube.
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    69
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    70
.. _`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
    71
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    72
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
    73
``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
    74
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
    75
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
    76
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
    77
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    78
* 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
    79
  either case)
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    80
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    81
* ``__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
    82
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    83
.. sourcecode:: python
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    84
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    85
    from cubicweb.web import formfields
4443
83ff2bb898a5 start documenting forms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2172
diff changeset
    86
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    87
    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
    88
        entity = form.edited_entity
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    89
        # first see if its specified by __linkto form parameters
7901
bdb81b1a8243 [linkto] update documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7643
diff changeset
    90
        linkedto = form.linked_to[('done_in', 'subject')]
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    91
        if linkedto:
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    92
            return linkedto
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    93
        # it isn't, get initial values
7901
bdb81b1a8243 [linkto] update documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7643
diff changeset
    94
        vocab = field.relvoc_init(form)
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    95
        veid = None
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    96
        # 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
    97
        if not entity.has_eid():
7901
bdb81b1a8243 [linkto] update documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7643
diff changeset
    98
            peids = form.linked_to[('concerns', 'subject')]
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    99
            peid = peids and peids[0]
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   100
        else:
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   101
            peid = entity.project.eid
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   102
            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
   103
        if peid:
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   104
            # 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
   105
            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
   106
            rset = form._cw.execute(
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   107
                '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
   108
                '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
   109
                '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
   110
            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
   111
                      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
   112
                      and v.eid != veid]
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   113
        return vocab
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   114
7901
bdb81b1a8243 [linkto] update documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7643
diff changeset
   115
The first thing we have to do is fetch potential values from the ``__linkto`` url
bdb81b1a8243 [linkto] update documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7643
diff changeset
   116
parameter that is often found in entity creation contexts (the creation action
bdb81b1a8243 [linkto] update documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7643
diff changeset
   117
provides such a parameter with a predetermined value; for instance in this case,
bdb81b1a8243 [linkto] update documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7643
diff changeset
   118
ticket creation could occur in the context of a `Version` entity). The
bdb81b1a8243 [linkto] update documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7643
diff changeset
   119
:class:`~cubicweb.web.formfields.RelationField` field class provides a
bdb81b1a8243 [linkto] update documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7643
diff changeset
   120
:meth:`~cubicweb.web.formfields.RelationField.relvoc_linkedto` method that gets a
bdb81b1a8243 [linkto] update documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7643
diff changeset
   121
list suitably filled with vocabulary values.
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   122
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   123
.. sourcecode:: python
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   124
7901
bdb81b1a8243 [linkto] update documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7643
diff changeset
   125
        linkedto = field.relvoc_linkedto(form)
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   126
        if linkedto:
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   127
            return linkedto
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   128
7901
bdb81b1a8243 [linkto] update documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7643
diff changeset
   129
Then, if no ``__linkto`` argument was given, we must prepare the vocabulary with
bdb81b1a8243 [linkto] update documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7643
diff changeset
   130
an initial empty value (because `done_in` is not mandatory, we must allow the
bdb81b1a8243 [linkto] update documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7643
diff changeset
   131
user to not select a verson) and already linked values. This is done with the
bdb81b1a8243 [linkto] update documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7643
diff changeset
   132
:meth:`~cubicweb.web.formfields.RelationField.relvoc_init` method.
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   133
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   134
.. sourcecode:: python
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   135
7901
bdb81b1a8243 [linkto] update documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7643
diff changeset
   136
        vocab = field.relvoc_init(form)
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   137
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   138
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
   139
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
   140
(`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
   141
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
   142
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
   143
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
   144
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
   145
candidate values.
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
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
   148
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   149
* 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
   150
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   151
* 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
   152
  `concerns` relation)
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   153
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   154
* 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
   155
  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
   156
  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
   157
  ``__linkto`` argument)
4443
83ff2bb898a5 start documenting forms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2172
diff changeset
   158
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   159
.. note::
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
   160
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   161
   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
   162
   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
   163
   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
   164
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   165
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
   166
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   167
.. sourcecode:: python
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   168
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   169
        veid = None
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   170
        if not entity.has_eid():
7901
bdb81b1a8243 [linkto] update documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7643
diff changeset
   171
            peids = form.linked_to[('concerns', 'subject')]
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   172
            peid = peids and peids[0]
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   173
        else:
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   174
            peid = entity.project.eid
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   175
            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
   176
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   177
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
   178
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
   179
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
   180
``__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
   181
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
   182
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   183
.. note::
4743
026a89520184 [book] a few autoclasses for renderers, misc tweaks
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4465
diff changeset
   184
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   185
  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
   186
  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
   187
  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
   188
  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
   189
  there
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   190
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   191
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
   192
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
   193
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   194
.. sourcecode:: python
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   195
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   196
        if peid:
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   197
            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
   198
            rset = form._cw.execute(
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   199
                '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
   200
                '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
   201
                '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
   202
            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
   203
                      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
   204
                      and v.eid != veid]
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   205
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   206
.. warning::
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   207
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   208
   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
   209
   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
   210
   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
   211
   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
   212
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   213
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
   214
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
   215
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
   216
7643
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   217
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   218
Building self-posted form with custom fields/widgets
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   219
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   220
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   221
Sometimes you want a form that is not related to entity edition. For those,
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   222
you'll have to handle form posting by yourself. Here is a complete example on how
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   223
to achieve this (and more).
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   224
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   225
Imagine you want a form that selects a month period. There are no proper
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   226
field/widget to handle this in CubicWeb, so let's start by defining them:
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   227
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   228
.. sourcecode:: python
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   229
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   230
    # let's have the whole import list at the beginning, even those necessary for
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   231
    # subsequent snippets
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   232
    from logilab.common import date
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   233
    from logilab.mtconverter import xml_escape
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   234
    from cubicweb.view import View
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7901
diff changeset
   235
    from cubicweb.predicates import match_kwargs
7643
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   236
    from cubicweb.web import RequestError, ProcessFormError
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   237
    from cubicweb.web import formfields as fields, formwidgets as wdgs
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   238
    from cubicweb.web.views import forms, calendar
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   239
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   240
    class MonthSelect(wdgs.Select):
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   241
        """Custom widget to display month and year. Expect value to be given as a
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   242
        date instance.
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   243
        """
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   244
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   245
        def format_value(self, form, field, value):
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   246
            return u'%s/%s' % (value.year, value.month)
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   247
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   248
        def process_field_data(self, form, field):
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   249
            val = super(MonthSelect, self).process_field_data(form, field)
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   250
            try:
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   251
                year, month = val.split('/')
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   252
                year = int(year)
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   253
                month = int(month)
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   254
                return date.date(year, month, 1)
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   255
            except ValueError:
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   256
                raise ProcessFormError(
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   257
                    form._cw._('badly formated date string %s') % val)
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   258
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   259
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   260
    class MonthPeriodField(fields.CompoundField):
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   261
        """custom field composed of two subfields, 'begin_month' and 'end_month'.
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   262
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   263
        It expects to be used on form that has 'mindate' and 'maxdate' in its
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   264
        extra arguments, telling the range of month to display.
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   265
        """
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   266
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   267
        def __init__(self, *args, **kwargs):
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   268
            kwargs.setdefault('widget', wdgs.IntervalWidget())
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   269
            super(MonthPeriodField, self).__init__(
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   270
                [fields.StringField(name='begin_month',
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   271
                                    choices=self.get_range, sort=False,
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   272
                                    value=self.get_mindate,
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   273
                                    widget=MonthSelect()),
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   274
                 fields.StringField(name='end_month',
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   275
                                    choices=self.get_range, sort=False,
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   276
                                    value=self.get_maxdate,
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   277
                                    widget=MonthSelect())], *args, **kwargs)
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   278
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   279
        @staticmethod
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   280
        def get_range(form, field):
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   281
            mindate = date.todate(form.cw_extra_kwargs['mindate'])
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   282
            maxdate = date.todate(form.cw_extra_kwargs['maxdate'])
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   283
            assert mindate <= maxdate
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   284
            _ = form._cw._
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   285
            months = []
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   286
            while mindate <= maxdate:
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   287
                label = '%s %s' % (_(calendar.MONTHNAMES[mindate.month - 1]),
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   288
                                   mindate.year)
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   289
                value = field.widget.format_value(form, field, mindate)
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   290
                months.append( (label, value) )
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   291
                mindate = date.next_month(mindate)
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   292
            return months
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   293
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   294
        @staticmethod
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   295
        def get_mindate(form, field):
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   296
            return form.cw_extra_kwargs['mindate']
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   297
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   298
        @staticmethod
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   299
        def get_maxdate(form, field):
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   300
            return form.cw_extra_kwargs['maxdate']
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   301
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   302
        def process_posted(self, form):
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   303
            for field, value in super(MonthPeriodField, self).process_posted(form):
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   304
                if field.name == 'end_month':
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   305
                    value = date.last_day(value)
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   306
                yield field, value
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   307
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   308
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   309
Here we first define a widget that will be used to select the beginning and the
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   310
end of the period, displaying months like '<month> YYYY' but using 'YYYY/mm' as
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   311
actual value.
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   312
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   313
We then define a field that will actually hold two fields, one for the beginning
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   314
and another for the end of the period. Each subfield uses the widget we defined
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   315
earlier, and the outer field itself uses the standard
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   316
:class:`IntervalWidget`. The field adds some logic:
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   317
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   318
* a vocabulary generation function `get_range`, used to populate each sub-field
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   319
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   320
* two 'value' functions `get_mindate` and `get_maxdate`, used to tell to
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   321
  subfields which value they should consider on form initialization
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   322
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   323
* overriding of `process_posted`, called when the form is being posted, so that
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   324
  the end of the period is properly set to the last day of the month.
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   325
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   326
Now, we can define a very simple form:
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   327
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   328
.. sourcecode:: python
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   329
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   330
    class MonthPeriodSelectorForm(forms.FieldsForm):
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   331
        __regid__ = 'myform'
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   332
        __select__ = match_kwargs('mindate', 'maxdate')
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   333
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   334
        form_buttons = [wdgs.SubmitButton()]
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   335
        form_renderer_id = 'onerowtable'
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   336
        period = MonthPeriodField()
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   337
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   338
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   339
where we simply add our field, set a submit button and use a very simple renderer
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   340
(try others!). Also we specify a selector that ensures form will have arguments
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   341
necessary to our field.
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   342
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   343
Now, we need a view that will wrap the form and handle post when it occurs,
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   344
simply displaying posted values in the page:
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   345
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   346
.. sourcecode:: python
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   347
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   348
    class SelfPostingForm(View):
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   349
        __regid__ = 'myformview'
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   350
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   351
        def call(self):
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   352
            mindate, maxdate = date.date(2010, 1, 1), date.date(2012, 1, 1)
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   353
            form = self._cw.vreg['forms'].select(
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   354
                'myform', self._cw, mindate=mindate, maxdate=maxdate, action='')
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   355
            try:
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   356
                posted = form.process_posted()
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   357
                self.w(u'<p>posted values %s</p>' % xml_escape(repr(posted)))
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   358
            except RequestError: # no specified period asked
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   359
                pass
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   360
            form.render(w=self.w, formvalues=self._cw.form)
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   361
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   362
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   363
Notice usage of the :meth:`process_posted` method, that will return a dictionary
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   364
of typed values (because they have been processed by the field). In our case, when
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   365
the form is posted you should see a dictionary with 'begin_month' and 'end_month'
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   366
as keys with the selected dates as value (as a python `date` object).
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   367
f3e3892fc7e3 [book, form] include complete example of self-posted form with custom field/widget + minor other changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5869
diff changeset
   368
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   369
APIs
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   370
~~~~
5418
4f0047cfecb5 [doc] reorganize for chapter structure
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5400
diff changeset
   371
4f0047cfecb5 [doc] reorganize for chapter structure
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5400
diff changeset
   372
.. automodule:: cubicweb.web.formfields
4f0047cfecb5 [doc] reorganize for chapter structure
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5400
diff changeset
   373
.. automodule:: cubicweb.web.formwidgets
4f0047cfecb5 [doc] reorganize for chapter structure
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5400
diff changeset
   374
.. automodule:: cubicweb.web.views.forms
4f0047cfecb5 [doc] reorganize for chapter structure
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5400
diff changeset
   375
.. 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
   376
5464
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
   377