doc/book/en/development/devweb/form.rst
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Wed, 21 Apr 2010 16:53:47 +0200
branchstable
changeset 5368 d321e4b62a10
parent 5350 49c065ae225e
child 5388 9167751463d4
permissions -rw-r--r--
[book] start documenting the HTML form system
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
     1
HTML form construction
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
     2
----------------------
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
     3
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
     4
CubicWeb provides the somewhat usual form / field / widget / renderer abstraction
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
     5
to provide generic building blocks which will greatly help you in building forms
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
     6
properly integrated with CubicWeb (coherent display, error handling, etc...),
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
     7
while keeping things as flexible as possible.
4443
83ff2bb898a5 start documenting forms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2172
diff changeset
     8
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
     9
A **form** basically only holds a set of **fields**, and has te be bound to a
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    10
**renderer** which is responsible to layout them. Each field is bound to a
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    11
**widget** that will be used to fill in value(s) for that field (at form
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
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    15
The **field** should be used according to the type of what you want to edit.
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
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    17
:class:`~cubicweb.web.formfields.DateField`. Then you can choose among multiple
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    18
widgets to edit it, for instance :class:`~cubicweb.web.formwidgets.TextInput` (a
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.formfields
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    25
.. automodule:: cubicweb.web.formwidgets
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    26
.. automodule:: cubicweb.web.views.forms
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    27
.. automodule:: cubicweb.web.views.autoform
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    28
.. automodule:: cubicweb.web.views.formrenderers
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    29
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    30
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    31
Now what ? Example of bare fields form
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    32
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    33
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    34
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
    35
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
    36
: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
    37
:mod:`cubicweb.web.views.massmailing`.
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    38
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    39
Here is the source code:
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    40
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    41
.. sourcecode:: python
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    42
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    43
    def sender_value(form):
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    44
	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
    45
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    46
    def recipient_choices(form, field):
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    47
	return [(e.get_email(), e.eid) for e in form.cw_rset.entities()
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    48
		 if e.get_email()]
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    49
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    50
    def recipient_value(form):
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    51
	return [e.eid for e in form.cw_rset.entities() if e.get_email()]
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    52
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    53
    class MassMailingForm(forms.FieldsForm):
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    54
	__regid__ = 'massmailing'
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    55
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    56
	needs_js = ('cubicweb.widgets.js',)
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    57
	domid = 'sendmail'
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    58
	action = 'sendmail'
4443
83ff2bb898a5 start documenting forms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2172
diff changeset
    59
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    60
	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
    61
				label=_('From:'),
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    62
				value=sender_value)
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    63
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    64
	recipient = ff.StringField(widget=CheckBox(),
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    65
	                           label=_('Recipients:'),
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    66
				   choices=recipient_choices,
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    67
				   value=recipients_value)
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    68
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    69
	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
    70
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    71
	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
    72
						    inputid='mailbody'))
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    73
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    74
	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
    75
				  _('send email'), 'SEND_EMAIL_ICON'),
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    76
			ImgButton('cancelbutton', "javascript: history.back()",
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    77
				  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
    78
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    79
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
    80
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    81
* 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
    82
  email
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    83
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    84
* 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
    85
  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
    86
  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
    87
  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
    88
  vocabulary function.
4465
18fb359f5c7a fix wrong autoclass inclusion
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4443
diff changeset
    89
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    90
* 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
    91
  :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
    92
  :class:`~cubicweb.web.formfields.StringField`)
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    93
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    94
* 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
    95
  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
    96
  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
    97
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
    98
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
    99
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
   100
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
   101
attribute), another to cancel the form which will go back to the previous page
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   102
using another javascript call. Also we specify image to used as button icon a
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   103
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
   104
:class:`cubicweb.web.formwidgets.ImgButton`.
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   105
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   106
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
   107
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   108
.. sourcecode:: python
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   109
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   110
    class MassMailingFormView(form.FormViewMixIn, EntityView):
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   111
	__regid__ = 'massmailing'
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   112
	__select__ = implements(IEmailable) & authenticated_user()
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   113
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   114
	def call(self):
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   115
	    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
   116
	                                         rset=self.cw_rset)
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   117
	    self.w(form.render())
4443
83ff2bb898a5 start documenting forms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2172
diff changeset
   118
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   119
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
   120
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
   121
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
   122
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
   123
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   124
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
   125
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
   126
the mail to specified recipients.
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   127
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   128
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
   129
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   130
.. sourcecode:: python
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   131
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   132
    class SendMailController(Controller):
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   133
        __regid__ = 'sendmail'
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   134
        __select__ = authenticated_user() & match_form_params('recipient', 'mailbody', 'subject')
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   135
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   136
        def publish(self, rset=None):
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   137
            body = self._cw.form['mailbody']
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   138
            subject = self._cw.form['subject']
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   139
            eids = self._cw.form['recipient']
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   140
            # eids may be a string if only one recipient was specified
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   141
            if isinstance(eids, basestring):
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   142
                rset = self._cw.execute('Any X WHERE X eid %(x)s', {'x': eids})
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   143
            else:
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   144
                rset = self._cw.execute('Any X WHERE X eid in (%s)' % (','.join(eids)))
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   145
            recipients = list(rset.entities())
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   146
            msg = format_mail({'email' : self._cw.user.get_email(),
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   147
                               'name' : self._cw.user.dc_title()},
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   148
                              recipients, body, subject)
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   149
            if not self._cw.vreg.config.sendmails([(msg, recipients]):
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   150
                msg = self._cw._('could not connect to the SMTP server')
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   151
            else:
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   152
                msg = self._cw._('emails successfully sent')
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   153
            raise Redirect(self._cw.build_url(__message=msg))
4443
83ff2bb898a5 start documenting forms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2172
diff changeset
   154
83ff2bb898a5 start documenting forms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2172
diff changeset
   155
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   156
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
   157
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
   158
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
   159
: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
   160
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
   161
to inform the user.
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
   162
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   163
Also notice that our controller has a selector that deny access to it to
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   164
anonymous users (we don't want our instance to be used as a spam relay), but also
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   165
check expected parameters are specified in forms. That avoid later defensive
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   166
programming (though it's not enough to handle all possible error cases).
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   167
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   168
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
   169
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
   170
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
   171
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   172
.. sourcecode:: python
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   173
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   174
    class MassMailingFormRenderer(formrenderers.FormRenderer):
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   175
        __regid__ = 'massmailing'
4743
026a89520184 [book] a few autoclasses for renderers, misc tweaks
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4465
diff changeset
   176
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   177
        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
   178
            w(u'<table class="headersform">')
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   179
            for field in fields:
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   180
                if field.name == 'mailbody':
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   181
                    w(u'</table>')
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   182
                    w(u'<div id="toolbar">')
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   183
                    w(u'<ul>')
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   184
                    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
   185
                        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
   186
                    w(u'</ul>')
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   187
                    w(u'</div>')
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   188
                    w(u'<div>')
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   189
                    w(field.render(form, self))
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   190
                    w(u'</div>')
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   191
                else:
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   192
                    w(u'<tr>')
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   193
                    w(u'<td class="hlabel">%s</td>' % self.render_label(form, field))
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   194
                    w(u'<td class="hvalue">')
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   195
                    w(field.render(form, self))
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   196
                    w(u'</td></tr>')
4743
026a89520184 [book] a few autoclasses for renderers, misc tweaks
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4465
diff changeset
   197
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   198
        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
   199
            pass
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
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
   202
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
   203
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
   204
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
   205
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   206
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
   207
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   208
.. sourcecode:: python
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
    form_renderer_id = 'massmailing'
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5350
diff changeset
   211
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
.. Example of entity fields form