doc/book/en/devweb/edition/form.rst
author Aurelien Campeas <aurelien.campeas@logilab.fr>
Wed, 24 Oct 2012 12:08:21 +0200
branchstable
changeset 8582 b0e086f451b7
parent 8190 2a3c1b787688
permissions -rw-r--r--
prepare 3.15.5
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'>,
c6c9a80ad1dd [doc/book] dissection of a form chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5418
diff changeset
    38
                  <class 'cubes.tracker.views.forms.VersionChangeStateForm'>],
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