author | Aurelien Campeas <aurelien.campeas@logilab.fr> |
Tue, 04 May 2010 15:46:36 +0200 | |
branch | stable |
changeset 5462 | a37127c8bf23 |
parent 5418 | doc/book/en/devweb/form.rst@4f0047cfecb5 |
permissions | -rw-r--r-- |
5368
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
1 |
HTML form construction |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
2 |
---------------------- |
1714
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
3 |
|
5368
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
4 |
CubicWeb provides the somewhat usual form / field / widget / renderer abstraction |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
5 |
to provide generic building blocks which will greatly help you in building forms |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
6 |
properly integrated with CubicWeb (coherent display, error handling, etc...), |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
7 |
while keeping things as flexible as possible. |
4443
83ff2bb898a5
start documenting forms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2172
diff
changeset
|
8 |
|
5462
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
9 |
A ``form`` basically only holds a set of ``fields``, and has te be bound to a |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
10 |
``renderer`` which is responsible to layout them. Each field is bound to a |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
11 |
``widget`` that will be used to fill in value(s) for that field (at form |
5368
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
12 |
generation time) and 'decode' (fetch and give a proper Python type to) values |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
13 |
sent back by the browser. |
4443
83ff2bb898a5
start documenting forms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2172
diff
changeset
|
14 |
|
5462
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
15 |
The ``field`` should be used according to the type of what you want to edit. |
5368
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
16 |
E.g. if you want to edit some date, you'll have to use the |
5400
b7ab099b128a
[doc/book] various content fixes
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5394
diff
changeset
|
17 |
:class:`cubicweb.web.formfields.DateField`. Then you can choose among multiple |
b7ab099b128a
[doc/book] various content fixes
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5394
diff
changeset
|
18 |
widgets to edit it, for instance :class:`cubicweb.web.formwidgets.TextInput` (a |
5368
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
19 |
bare text field), :class:`~cubicweb.web.formwidgets.DateTimePicker` (a simple |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
20 |
calendar) or even :class:`~cubicweb.web.formwidgets.JQueryDatePicker` (the JQuery |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
21 |
calendar). You can of course also write your own widget. |
1714
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
22 |
|
5368
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
23 |
|
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
24 |
.. automodule:: cubicweb.web.views.autoform |
1714
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
25 |
|
5462
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
26 |
Anatomy of a choices function |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
27 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
1714
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
28 |
|
5462
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
29 |
Let's have a look at the `ticket_done_in_choices` function given to |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
30 |
the `choices` parameter of the relation tag that is applied to the |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
31 |
('Ticket', 'done_in', '*') relation definition, as it is both typical |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
32 |
and sophisticated enough. This is a code snippet from the `tracker`_ |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
33 |
cube. |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
34 |
|
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
35 |
.. _`tracker`: http://www.cubicweb.org/project/cubicweb-tracker |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
36 |
|
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
37 |
The ``Ticket`` entity type can be related to a ``Project`` and a |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
38 |
``Version``, respectively through the ``concerns`` and ``done_in`` |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
39 |
relations. When a user is about to edit a ticket, we want to fill the |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
40 |
combo box for the ``done_in`` relation with values pertinent with |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
41 |
respect to the context. The important context here is: |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
42 |
|
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
43 |
* creation or modification (we cannot fetch values the same way in |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
44 |
either case) |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
45 |
|
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
46 |
* ``__linkto`` url parameter given in a creation context |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
47 |
|
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
48 |
.. sourcecode:: python |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
49 |
|
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
50 |
from cubicweb.web import formfields |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
51 |
|
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
52 |
def ticket_done_in_choices(form, field): |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
53 |
entity = form.edited_entity |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
54 |
# first see if its specified by __linkto form parameters |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
55 |
linkedto = formfields.relvoc_linkedto(entity, 'done_in', 'subject') |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
56 |
if linkedto: |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
57 |
return linkedto |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
58 |
# it isn't, get initial values |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
59 |
vocab = formfields.relvoc_init(entity, 'done_in', 'subject') |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
60 |
veid = None |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
61 |
# try to fetch the (already or pending) related version and project |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
62 |
if not entity.has_eid(): |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
63 |
peids = entity.linked_to('concerns', 'subject') |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
64 |
peid = peids and peids[0] |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
65 |
else: |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
66 |
peid = entity.project.eid |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
67 |
veid = entity.done_in and entity.done_in[0].eid |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
68 |
if peid: |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
69 |
# we can complete the vocabulary with relevant values |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
70 |
rschema = form._cw.vreg.schema['done_in'].rdef('Ticket', 'Version') |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
71 |
rset = form._cw.execute( |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
72 |
'Any V, VN ORDERBY version_sort_value(VN) ' |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
73 |
'WHERE V version_of P, P eid %(p)s, V num VN, ' |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
74 |
'V in_state ST, NOT ST name "published"', {'p': peid}, 'p') |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
75 |
vocab += [(v.view('combobox'), v.eid) for v in rset.entities() |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
76 |
if rschema.has_perm(form._cw, 'add', toeid=v.eid) |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
77 |
and v.eid != veid] |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
78 |
return vocab |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
79 |
|
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
80 |
The first thing we have to do is fetch potential values from the |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
81 |
``__linkto`` url parameter that is often found in entity creation |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
82 |
contexts (the creation action provides such a parameter with a |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
83 |
predetermined value; for instance in this case, ticket creation could |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
84 |
occur in the context of a `Version` entity). The |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
85 |
:mod:`cubicweb.web.formfields` module provides a ``relvoc_linkedto`` |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
86 |
utility function that gets a list suitably filled with vocabulary |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
87 |
values. |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
88 |
|
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
89 |
.. sourcecode:: python |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
90 |
|
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
91 |
linkedto = formfields.relvoc_linkedto(entity, 'done_in', 'subject') |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
92 |
if linkedto: |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
93 |
return linkedto |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
94 |
|
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
95 |
Then, if no ``__linkto`` argument was given, we must prepare the |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
96 |
vocabulary with an initial empty value (because `done_in` is not |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
97 |
mandatory, we must allow the user to not select a verson) and already |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
98 |
linked values. This is done with the ``relvoc_init`` function. |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
99 |
|
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
100 |
.. sourcecode:: python |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
101 |
|
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
102 |
vocab = formfields.relvoc_init(entity, 'done_in', 'subject') |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
103 |
|
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
104 |
But then, we have to give more: if the ticket is related to a project, |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
105 |
we should provide all the non published versions of this project |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
106 |
(`Version` and `Project` can be related through the `version_of` |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
107 |
relation). Conversely, if we do not know yet the project, it would not |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
108 |
make sense to propose all existing versions as it could potentially |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
109 |
lead to incoherences. Even if these will be caught by some |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
110 |
RQLConstraint, it is wise not to tempt the user with error-inducing |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
111 |
candidate values. |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
112 |
|
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
113 |
The "ticket is related to a project" part must be decomposed as: |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
114 |
|
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
115 |
* this is a new ticket which is created is the context of a project |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
116 |
|
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
117 |
* this is an already existing ticket, linked to a project (through the |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
118 |
`concerns` relation) |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
119 |
|
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
120 |
* there is no related project (quite unlikely given the cardinality of |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
121 |
the `concerns` relation, so it can only mean that we are creating a |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
122 |
new ticket, and a project is about to be selected but there is no |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
123 |
``__linkto`` argument) |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
124 |
|
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
125 |
.. note:: |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
126 |
|
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
127 |
the last situation could happen in several ways, but of course in a |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
128 |
polished application, the paths to ticket creation should be |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
129 |
controlled so as to avoid a suboptimal end-user experience |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
130 |
|
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
131 |
Hence, we try to fetch the related project. |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
132 |
|
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
133 |
.. sourcecode:: python |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
134 |
|
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
135 |
veid = None |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
136 |
if not entity.has_eid(): |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
137 |
peids = entity.linked_to('concerns', 'subject') |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
138 |
peid = peids and peids[0] |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
139 |
else: |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
140 |
peid = entity.project.eid |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
141 |
veid = entity.done_in and entity.done_in[0].eid |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
142 |
|
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
143 |
We distinguish between entity creation and entity modification using |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
144 |
the ``Entity.has_eid()`` method, which returns `False` on creation. At |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
145 |
creation time the only way to get a project is through the |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
146 |
``__linkto`` parameter. Notice that we fetch the version in which the |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
147 |
ticket is `done_in` if any, for later. |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
148 |
|
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
149 |
.. note:: |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
150 |
|
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
151 |
the implementation above assumes that if there is a ``__linkto`` |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
152 |
parameter, it is only about a project. While it makes sense most of |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
153 |
the time, it is not an absolute. Depending on how an entity creation |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
154 |
action action url is built, several outcomes could be possible |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
155 |
there |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
156 |
|
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
157 |
If the ticket is already linked to a project, fetching it is |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
158 |
trivial. Then we add the relevant version to the initial vocabulary. |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
159 |
|
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
160 |
.. sourcecode:: python |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
161 |
|
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
162 |
if peid: |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
163 |
rschema = form._cw.vreg.schema['done_in'].rdef('Ticket', 'Version') |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
164 |
rset = form._cw.execute( |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
165 |
'Any V, VN ORDERBY version_sort_value(VN) ' |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
166 |
'WHERE V version_of P, P eid %(p)s, V num VN, ' |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
167 |
'V in_state ST, NOT ST name "published"', {'p': peid}) |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
168 |
vocab += [(v.view('combobox'), v.eid) for v in rset.entities() |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
169 |
if rschema.has_perm(form._cw, 'add', toeid=v.eid) |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
170 |
and v.eid != veid] |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
171 |
|
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
172 |
.. warning:: |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
173 |
|
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
174 |
we have to defend ourselves against lack of a project eid. Given |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
175 |
the cardinality of the `concerns` relation, there *must* be a |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
176 |
project, but this rule can only be enforced at validation time, |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
177 |
which will happen of course only after form subsmission |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
178 |
|
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
179 |
Here, given a project eid, we complete the vocabulary with all |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
180 |
unpublished versions defined in the project (sorted by number) for |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
181 |
which the current user is allowed to establish the relation. Of |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
182 |
course, we take care *not* to provide a version the ticket is already |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
183 |
linked to (through ``done_in``). |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
184 |
|
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
185 |
|
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
186 |
Example of ad-hoc fields form |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
187 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
5368
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
188 |
|
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
189 |
We want to define a form doing something else than editing an entity. The idea is |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
190 |
to propose a form to send an email to entities in a resultset which implements |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
191 |
:class:`IEmailable`. Let's take a simplified version of what you'll find in |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
192 |
:mod:`cubicweb.web.views.massmailing`. |
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 |
Here is the source code: |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
195 |
|
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
196 |
.. sourcecode:: python |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
197 |
|
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
198 |
def sender_value(form): |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
199 |
return '%s <%s>' % (form._cw.user.dc_title(), form._cw.user.get_email()) |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
200 |
|
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
201 |
def recipient_choices(form, field): |
5462
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
202 |
return [(e.get_email(), e.eid) |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
203 |
for e in form.cw_rset.entities() |
5368
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
204 |
if e.get_email()] |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
205 |
|
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
206 |
def recipient_value(form): |
5462
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
207 |
return [e.eid for e in form.cw_rset.entities() |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
208 |
if e.get_email()] |
5368
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
209 |
|
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
210 |
class MassMailingForm(forms.FieldsForm): |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
211 |
__regid__ = 'massmailing' |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
212 |
|
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
213 |
needs_js = ('cubicweb.widgets.js',) |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
214 |
domid = 'sendmail' |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
215 |
action = 'sendmail' |
4443
83ff2bb898a5
start documenting forms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2172
diff
changeset
|
216 |
|
5368
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
217 |
sender = ff.StringField(widget=TextInput({'disabled': 'disabled'}), |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
218 |
label=_('From:'), |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
219 |
value=sender_value) |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
220 |
|
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
221 |
recipient = ff.StringField(widget=CheckBox(), |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
222 |
label=_('Recipients:'), |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
223 |
choices=recipient_choices, |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
224 |
value=recipients_value) |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
225 |
|
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
226 |
subject = ff.StringField(label=_('Subject:'), max_length=256) |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
227 |
|
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
228 |
mailbody = ff.StringField(widget=AjaxWidget(wdgtype='TemplateTextField', |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
229 |
inputid='mailbody')) |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
230 |
|
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
231 |
form_buttons = [ImgButton('sendbutton', "javascript: $('#sendmail').submit()", |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
232 |
_('send email'), 'SEND_EMAIL_ICON'), |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
233 |
ImgButton('cancelbutton', "javascript: history.back()", |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
234 |
stdmsgs.BUTTON_CANCEL, 'CANCEL_EMAIL_ICON')] |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
235 |
|
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
236 |
Let's detail what's going on up there. Our form will hold four fields: |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
237 |
|
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
238 |
* a sender field, which is disabled and will simply contains the user's name and |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
239 |
|
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
240 |
|
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
241 |
* a recipients field, which will be displayed as a list of users in the context |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
242 |
result set with checkboxes so user can still choose who will receive his mailing |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
243 |
by checking or not the checkboxes. By default all of them will be checked since |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
244 |
field's value return a list containing same eids as those returned by the |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
245 |
vocabulary function. |
4465
18fb359f5c7a
fix wrong autoclass inclusion
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4443
diff
changeset
|
246 |
|
5368
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
247 |
* a subject field, limited to 256 characters (hence we know a |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
248 |
:class:`~cubicweb.web.formwidgets.TextInput` will be used, as explained in |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
249 |
:class:`~cubicweb.web.formfields.StringField`) |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
250 |
|
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
251 |
* a mailbody field. This field use an ajax widget, defined in `cubicweb.widgets.js`, |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
252 |
and whose definition won't be shown here. Notice though that we tell this form |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
253 |
need this javascript file by using `needs_js` |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
254 |
|
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
255 |
Last but not least, we add two buttons control: one to post the form using |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
256 |
javascript (`$('#sendmail')` being the jQuery call to get the element with DOM id |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
257 |
set to 'sendmail', which is our form DOM id as specified by its `domid` |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
258 |
attribute), another to cancel the form which will go back to the previous page |
5388
9167751463d4
[doc/book] rename images with non suffix dots to please latex
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5368
diff
changeset
|
259 |
using another javascript call. Also we specify an image to use as button icon as a |
5368
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
260 |
resource identifier (see :ref:`external_resources`) given as last argument to |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
261 |
:class:`cubicweb.web.formwidgets.ImgButton`. |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
262 |
|
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
263 |
To see this form, we still have to wrap it in a view. This is pretty simple: |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
264 |
|
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
265 |
.. sourcecode:: python |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
266 |
|
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
267 |
class MassMailingFormView(form.FormViewMixIn, EntityView): |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
268 |
__regid__ = 'massmailing' |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
269 |
__select__ = implements(IEmailable) & authenticated_user() |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
270 |
|
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
271 |
def call(self): |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
272 |
form = self._cw.vreg['forms'].select('massmailing', self._cw, |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
273 |
rset=self.cw_rset) |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
274 |
self.w(form.render()) |
4443
83ff2bb898a5
start documenting forms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2172
diff
changeset
|
275 |
|
5368
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
276 |
As you see, we simply define a view with proper selector so it only apply to a |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
277 |
result set containing :class:`IEmailable` entities, and so that only users in the |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
278 |
managers or users group can use it. Then in the `call()` method for this view we |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
279 |
simply select the above form and write what its `.render()` method returns. |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
280 |
|
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
281 |
When this form is submitted, a controller with id 'sendmail' will be called (as |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
282 |
specified using `action`). This controller will be responsible to actually send |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
283 |
the mail to specified recipients. |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
284 |
|
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
285 |
Here is what it looks like: |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
286 |
|
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
287 |
.. sourcecode:: python |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
288 |
|
5400
b7ab099b128a
[doc/book] various content fixes
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5394
diff
changeset
|
289 |
class SendMailController(Controller): |
b7ab099b128a
[doc/book] various content fixes
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5394
diff
changeset
|
290 |
__regid__ = 'sendmail' |
5462
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
291 |
__select__ = (authenticated_user() & |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
292 |
match_form_params('recipient', 'mailbody', 'subject')) |
5368
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
293 |
|
5400
b7ab099b128a
[doc/book] various content fixes
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5394
diff
changeset
|
294 |
def publish(self, rset=None): |
b7ab099b128a
[doc/book] various content fixes
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5394
diff
changeset
|
295 |
body = self._cw.form['mailbody'] |
b7ab099b128a
[doc/book] various content fixes
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5394
diff
changeset
|
296 |
subject = self._cw.form['subject'] |
b7ab099b128a
[doc/book] various content fixes
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5394
diff
changeset
|
297 |
eids = self._cw.form['recipient'] |
b7ab099b128a
[doc/book] various content fixes
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5394
diff
changeset
|
298 |
# eids may be a string if only one recipient was specified |
b7ab099b128a
[doc/book] various content fixes
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5394
diff
changeset
|
299 |
if isinstance(eids, basestring): |
b7ab099b128a
[doc/book] various content fixes
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5394
diff
changeset
|
300 |
rset = self._cw.execute('Any X WHERE X eid %(x)s', {'x': eids}) |
b7ab099b128a
[doc/book] various content fixes
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5394
diff
changeset
|
301 |
else: |
b7ab099b128a
[doc/book] various content fixes
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5394
diff
changeset
|
302 |
rset = self._cw.execute('Any X WHERE X eid in (%s)' % (','.join(eids))) |
b7ab099b128a
[doc/book] various content fixes
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5394
diff
changeset
|
303 |
recipients = list(rset.entities()) |
b7ab099b128a
[doc/book] various content fixes
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5394
diff
changeset
|
304 |
msg = format_mail({'email' : self._cw.user.get_email(), |
b7ab099b128a
[doc/book] various content fixes
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5394
diff
changeset
|
305 |
'name' : self._cw.user.dc_title()}, |
b7ab099b128a
[doc/book] various content fixes
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5394
diff
changeset
|
306 |
recipients, body, subject) |
b7ab099b128a
[doc/book] various content fixes
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5394
diff
changeset
|
307 |
if not self._cw.vreg.config.sendmails([(msg, recipients]): |
b7ab099b128a
[doc/book] various content fixes
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5394
diff
changeset
|
308 |
msg = self._cw._('could not connect to the SMTP server') |
b7ab099b128a
[doc/book] various content fixes
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5394
diff
changeset
|
309 |
else: |
b7ab099b128a
[doc/book] various content fixes
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5394
diff
changeset
|
310 |
msg = self._cw._('emails successfully sent') |
b7ab099b128a
[doc/book] various content fixes
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5394
diff
changeset
|
311 |
raise Redirect(self._cw.build_url(__message=msg)) |
4443
83ff2bb898a5
start documenting forms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2172
diff
changeset
|
312 |
|
83ff2bb898a5
start documenting forms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2172
diff
changeset
|
313 |
|
5368
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
314 |
The entry point of a controller is the publish method. In that case we simply get |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
315 |
back post values in request's `form` attribute, get user instances according |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
316 |
to eids found in the 'recipient' form value, and send email after calling |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
317 |
:func:`format_mail` to get a proper email message. If we can't send email or |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
318 |
if we successfully sent email, we redirect to the index page with proper message |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
319 |
to inform the user. |
1714
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
320 |
|
5462
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
321 |
Also notice that our controller has a selector that deny access to it |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
322 |
to anonymous users (we don't want our instance to be used as a spam |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
323 |
relay), but also checks if the expected parameters are specified in |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
324 |
forms. That avoids later defensive programming (though it's not enough |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
325 |
to handle all possible error cases). |
5368
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
326 |
|
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
327 |
To conclude our example, suppose we wish a different form layout and that existent |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
328 |
renderers are not satisfying (we would check that first of course :). We would then |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
329 |
have to define our own renderer: |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
330 |
|
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
331 |
.. sourcecode:: python |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
332 |
|
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
333 |
class MassMailingFormRenderer(formrenderers.FormRenderer): |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
334 |
__regid__ = 'massmailing' |
4743
026a89520184
[book] a few autoclasses for renderers, misc tweaks
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
4465
diff
changeset
|
335 |
|
5368
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
336 |
def _render_fields(self, fields, w, form): |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
337 |
w(u'<table class="headersform">') |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
338 |
for field in fields: |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
339 |
if field.name == 'mailbody': |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
340 |
w(u'</table>') |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
341 |
w(u'<div id="toolbar">') |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
342 |
w(u'<ul>') |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
343 |
for button in form.form_buttons: |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
344 |
w(u'<li>%s</li>' % button.render(form)) |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
345 |
w(u'</ul>') |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
346 |
w(u'</div>') |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
347 |
w(u'<div>') |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
348 |
w(field.render(form, self)) |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
349 |
w(u'</div>') |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
350 |
else: |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
351 |
w(u'<tr>') |
5462
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
352 |
w(u'<td class="hlabel">%s</td>' % |
a37127c8bf23
[doc/book] copious choices example
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5418
diff
changeset
|
353 |
self.render_label(form, field)) |
5368
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
354 |
w(u'<td class="hvalue">') |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
355 |
w(field.render(form, self)) |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
356 |
w(u'</td></tr>') |
4743
026a89520184
[book] a few autoclasses for renderers, misc tweaks
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
4465
diff
changeset
|
357 |
|
5368
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
358 |
def render_buttons(self, w, form): |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
359 |
pass |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
360 |
|
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
361 |
We simply override the `_render_fields` and `render_buttons` method of the base form renderer |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
362 |
to arrange fields as we desire it: here we'll have first a two columns table with label and |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
363 |
value of the sender, recipients and subject field (form order respected), then form controls, |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
364 |
then a div containing the textarea for the email's content. |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
365 |
|
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
366 |
To bind this renderer to our form, we should add to our form definition above: |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
367 |
|
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
368 |
.. sourcecode:: python |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
369 |
|
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
370 |
form_renderer_id = 'massmailing' |
d321e4b62a10
[book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5350
diff
changeset
|
371 |
|
5418
4f0047cfecb5
[doc] reorganize for chapter structure
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5400
diff
changeset
|
372 |
API |
4f0047cfecb5
[doc] reorganize for chapter structure
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5400
diff
changeset
|
373 |
~~~ |
4f0047cfecb5
[doc] reorganize for chapter structure
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5400
diff
changeset
|
374 |
|
4f0047cfecb5
[doc] reorganize for chapter structure
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5400
diff
changeset
|
375 |
.. automodule:: cubicweb.web.formfields |
4f0047cfecb5
[doc] reorganize for chapter structure
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5400
diff
changeset
|
376 |
.. automodule:: cubicweb.web.formwidgets |
4f0047cfecb5
[doc] reorganize for chapter structure
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5400
diff
changeset
|
377 |
.. automodule:: cubicweb.web.views.forms |
4f0047cfecb5
[doc] reorganize for chapter structure
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5400
diff
changeset
|
378 |
.. automodule:: cubicweb.web.views.formrenderers |