web/views/formrenderers.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Thu, 28 Apr 2011 15:29:21 +0200
branchstable
changeset 7270 5a1e9b90b5c4
parent 6609 d73733479a3a
child 7408 9ad9ce340c5f
permissions -rw-r--r--
merge stable
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5405
diff changeset
     1
# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5405
diff changeset
     2
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5405
diff changeset
     3
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5405
diff changeset
     4
# This file is part of CubicWeb.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5405
diff changeset
     5
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5405
diff changeset
     6
# CubicWeb is free software: you can redistribute it and/or modify it under the
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5405
diff changeset
     7
# terms of the GNU Lesser General Public License as published by the Free
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5405
diff changeset
     8
# Software Foundation, either version 2.1 of the License, or (at your option)
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5405
diff changeset
     9
# any later version.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5405
diff changeset
    10
#
5424
8ecbcbff9777 replace logilab-common by CubicWeb in disclaimer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5421
diff changeset
    11
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5405
diff changeset
    12
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5405
diff changeset
    13
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5405
diff changeset
    14
# details.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5405
diff changeset
    15
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5405
diff changeset
    16
# You should have received a copy of the GNU Lesser General Public License along
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5405
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5038
diff changeset
    18
"""
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5038
diff changeset
    19
Renderers
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5038
diff changeset
    20
---------
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
    21
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5038
diff changeset
    22
.. Note::
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5038
diff changeset
    23
   Form renderers are responsible to layout a form to HTML.
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5038
diff changeset
    24
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5038
diff changeset
    25
Here are the base renderers available:
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5038
diff changeset
    26
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5038
diff changeset
    27
.. autoclass:: cubicweb.web.views.formrenderers.FormRenderer
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5038
diff changeset
    28
.. autoclass:: cubicweb.web.views.formrenderers.HTableFormRenderer
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5038
diff changeset
    29
.. autoclass:: cubicweb.web.views.formrenderers.EntityCompositeFormRenderer
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5038
diff changeset
    30
.. autoclass:: cubicweb.web.views.formrenderers.EntityFormRenderer
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5038
diff changeset
    31
.. autoclass:: cubicweb.web.views.formrenderers.EntityInlinedFormRenderer
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5038
diff changeset
    32
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
    33
"""
6582
8eb7883b4223 [pylint] fix a bug of pylint detected errors and i18n pb (calling builtins._ instead of req._)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6575
diff changeset
    34
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
    35
__docformat__ = "restructuredtext en"
6582
8eb7883b4223 [pylint] fix a bug of pylint detected errors and i18n pb (calling builtins._ instead of req._)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6575
diff changeset
    36
_ = unicode
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
    37
3478
f043f71017a3 handle display_fields in the form, not in the renderer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3477
diff changeset
    38
from warnings import warn
f043f71017a3 handle display_fields in the form, not in the renderer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3477
diff changeset
    39
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
    40
from logilab.common import dictattr
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2247
diff changeset
    41
from logilab.mtconverter import xml_escape
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
    42
4023
eae23c40627a drop common subpackage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3629
diff changeset
    43
from cubicweb import tags
2656
a93ae0f6c0ad R [base classes] only AppObject remaning, no more AppRsetObject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2586
diff changeset
    44
from cubicweb.appobject import AppObject
5877
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
    45
from cubicweb.selectors import is_instance, yes
6082
57933567146f [forms] callable field kwargs now always take form _and_ field parameters
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 5940
diff changeset
    46
from cubicweb.utils import json_dumps, support_args
5940
0e3ae19b181a [uilib] refactor json_dumps code organization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
    47
from cubicweb.web import eid_param, formwidgets as fwdgs
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
    48
3478
f043f71017a3 handle display_fields in the form, not in the renderer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3477
diff changeset
    49
2819
b864288fd316 remove more 3.2 deprecated code, reintroduce checkbox used by formrenderers
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2656
diff changeset
    50
def checkbox(name, value, attrs='', checked=None):
b864288fd316 remove more 3.2 deprecated code, reintroduce checkbox used by formrenderers
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2656
diff changeset
    51
    if checked is None:
b864288fd316 remove more 3.2 deprecated code, reintroduce checkbox used by formrenderers
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2656
diff changeset
    52
        checked = value
b864288fd316 remove more 3.2 deprecated code, reintroduce checkbox used by formrenderers
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2656
diff changeset
    53
    checked = checked and 'checked="checked"' or ''
b864288fd316 remove more 3.2 deprecated code, reintroduce checkbox used by formrenderers
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2656
diff changeset
    54
    return u'<input type="checkbox" name="%s" value="%s" %s %s />' % (
b864288fd316 remove more 3.2 deprecated code, reintroduce checkbox used by formrenderers
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2656
diff changeset
    55
        name, value, checked, attrs)
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
    56
4313
5d8196a105a7 move base form renderer label handling into a function to reuse it in CompositeFormRenderer and avoid seeing a tuple in column headers...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4212
diff changeset
    57
def field_label(form, field):
6082
57933567146f [forms] callable field kwargs now always take form _and_ field parameters
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 5940
diff changeset
    58
    if callable(field.label):
57933567146f [forms] callable field kwargs now always take form _and_ field parameters
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 5940
diff changeset
    59
        return field.label(form, field)
4313
5d8196a105a7 move base form renderer label handling into a function to reuse it in CompositeFormRenderer and avoid seeing a tuple in column headers...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4212
diff changeset
    60
    # XXX with 3.6 we can now properly rely on 'if field.role is not None' and
5d8196a105a7 move base form renderer label handling into a function to reuse it in CompositeFormRenderer and avoid seeing a tuple in column headers...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4212
diff changeset
    61
    # stop having a tuple for label
5d8196a105a7 move base form renderer label handling into a function to reuse it in CompositeFormRenderer and avoid seeing a tuple in column headers...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4212
diff changeset
    62
    if isinstance(field.label, tuple): # i.e. needs contextual translation
4314
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4293 4313
diff changeset
    63
        return form._cw.pgettext(*field.label)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4293 4313
diff changeset
    64
    return form._cw._(field.label)
4313
5d8196a105a7 move base form renderer label handling into a function to reuse it in CompositeFormRenderer and avoid seeing a tuple in column headers...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4212
diff changeset
    65
5d8196a105a7 move base form renderer label handling into a function to reuse it in CompositeFormRenderer and avoid seeing a tuple in column headers...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4212
diff changeset
    66
1319
sylvain.thenault@logilab.fr
parents: 1305
diff changeset
    67
2656
a93ae0f6c0ad R [base classes] only AppObject remaning, no more AppRsetObject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2586
diff changeset
    68
class FormRenderer(AppObject):
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5038
diff changeset
    69
    """This is the 'default' renderer, displaying fields in a two columns table:
1401
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
    70
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
    71
    +--------------+--------------+
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
    72
    | field1 label | field1 input |
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
    73
    +--------------+--------------+
5405
c03a9792e53a [web/views] fix docstring
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 5389
diff changeset
    74
    | field2 label | field2 input |
1401
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
    75
    +--------------+--------------+
4743
026a89520184 [book] a few autoclasses for renderers, misc tweaks
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4668
diff changeset
    76
1401
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
    77
    +---------+
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
    78
    | buttons |
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
    79
    +---------+
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
    80
    """
1995
ec95eaa2b711 turn renderers into appobjects
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    81
    __registry__ = 'formrenderers'
3377
dd9d292b6a6d use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3369
diff changeset
    82
    __regid__ = 'default'
1995
ec95eaa2b711 turn renderers into appobjects
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    83
3478
f043f71017a3 handle display_fields in the form, not in the renderer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3477
diff changeset
    84
    _options = ('display_label', 'display_help',
1995
ec95eaa2b711 turn renderers into appobjects
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    85
                'display_progress_div', 'table_class', 'button_bar_class',
ec95eaa2b711 turn renderers into appobjects
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    86
                # add entity since it may be given to select the renderer
ec95eaa2b711 turn renderers into appobjects
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    87
                'entity')
1362
decb7507fa91 nicer renderer options handling: can be passed to __init__ or to render
sylvain.thenault@logilab.fr
parents: 1340
diff changeset
    88
    display_label = True
decb7507fa91 nicer renderer options handling: can be passed to __init__ or to render
sylvain.thenault@logilab.fr
parents: 1340
diff changeset
    89
    display_help = True
decb7507fa91 nicer renderer options handling: can be passed to __init__ or to render
sylvain.thenault@logilab.fr
parents: 1340
diff changeset
    90
    display_progress_div = True
1710
8c717cc0b353 refactor error handling: get validation error information from a form attribute instead of req.data to avoid pb when multiple forms are displayed
sylvain.thenault@logilab.fr
parents: 1691
diff changeset
    91
    table_class = u'attributeForm'
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
    92
    button_bar_class = u'formButtonBar'
1436
97774eb6443b delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1434
diff changeset
    93
1995
ec95eaa2b711 turn renderers into appobjects
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    94
    def __init__(self, req=None, rset=None, row=None, col=None, **kwargs):
2890
fdcb8a2bb6eb fix __init__ parameters
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2819
diff changeset
    95
        super(FormRenderer, self).__init__(req, rset=rset, row=row, col=col)
1362
decb7507fa91 nicer renderer options handling: can be passed to __init__ or to render
sylvain.thenault@logilab.fr
parents: 1340
diff changeset
    96
        if self._set_options(kwargs):
decb7507fa91 nicer renderer options handling: can be passed to __init__ or to render
sylvain.thenault@logilab.fr
parents: 1340
diff changeset
    97
            raise ValueError('unconsumed arguments %s' % kwargs)
decb7507fa91 nicer renderer options handling: can be passed to __init__ or to render
sylvain.thenault@logilab.fr
parents: 1340
diff changeset
    98
decb7507fa91 nicer renderer options handling: can be passed to __init__ or to render
sylvain.thenault@logilab.fr
parents: 1340
diff changeset
    99
    def _set_options(self, kwargs):
1434
42e57dbbc585 new display_relations_form option on EntityFormRender
sylvain.thenault@logilab.fr
parents: 1412
diff changeset
   100
        for key in self._options:
1362
decb7507fa91 nicer renderer options handling: can be passed to __init__ or to render
sylvain.thenault@logilab.fr
parents: 1340
diff changeset
   101
            try:
decb7507fa91 nicer renderer options handling: can be passed to __init__ or to render
sylvain.thenault@logilab.fr
parents: 1340
diff changeset
   102
                setattr(self, key, kwargs.pop(key))
decb7507fa91 nicer renderer options handling: can be passed to __init__ or to render
sylvain.thenault@logilab.fr
parents: 1340
diff changeset
   103
            except KeyError:
decb7507fa91 nicer renderer options handling: can be passed to __init__ or to render
sylvain.thenault@logilab.fr
parents: 1340
diff changeset
   104
                continue
decb7507fa91 nicer renderer options handling: can be passed to __init__ or to render
sylvain.thenault@logilab.fr
parents: 1340
diff changeset
   105
        return kwargs
1436
97774eb6443b delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1434
diff changeset
   106
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   107
    # renderer interface ######################################################
1436
97774eb6443b delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1434
diff changeset
   108
6453
7fdd780d87e4 [form] unify form.render prototype to take a 'w' argument as other view/components render method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   109
    def render(self, w, form, values):
1362
decb7507fa91 nicer renderer options handling: can be passed to __init__ or to render
sylvain.thenault@logilab.fr
parents: 1340
diff changeset
   110
        self._set_options(values)
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   111
        form.add_media()
6582
8eb7883b4223 [pylint] fix a bug of pylint detected errors and i18n pb (calling builtins._ instead of req._)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6575
diff changeset
   112
        data = []
8eb7883b4223 [pylint] fix a bug of pylint detected errors and i18n pb (calling builtins._ instead of req._)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6575
diff changeset
   113
        _w = data.append
8eb7883b4223 [pylint] fix a bug of pylint detected errors and i18n pb (calling builtins._ instead of req._)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6575
diff changeset
   114
        _w(self.open_form(form, values))
1362
decb7507fa91 nicer renderer options handling: can be passed to __init__ or to render
sylvain.thenault@logilab.fr
parents: 1340
diff changeset
   115
        if self.display_progress_div:
6582
8eb7883b4223 [pylint] fix a bug of pylint detected errors and i18n pb (calling builtins._ instead of req._)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6575
diff changeset
   116
            _w(u'<div id="progress">%s</div>' % self._cw._('validating...'))
6597
ba9fb496ad87 [test/renderer] fix html form/field generation & adapt a bit one test
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6582
diff changeset
   117
        _w(u'\n<fieldset>\n')
6582
8eb7883b4223 [pylint] fix a bug of pylint detected errors and i18n pb (calling builtins._ instead of req._)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6575
diff changeset
   118
        self.render_fields(_w, form, values)
8eb7883b4223 [pylint] fix a bug of pylint detected errors and i18n pb (calling builtins._ instead of req._)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6575
diff changeset
   119
        self.render_buttons(_w, form)
6597
ba9fb496ad87 [test/renderer] fix html form/field generation & adapt a bit one test
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6582
diff changeset
   120
        _w(u'\n</fieldset>\n')
6582
8eb7883b4223 [pylint] fix a bug of pylint detected errors and i18n pb (calling builtins._ instead of req._)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6575
diff changeset
   121
        _w(self.close_form(form, values))
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   122
        errormsg = self.error_message(form)
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   123
        if errormsg:
1436
97774eb6443b delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1434
diff changeset
   124
            data.insert(0, errormsg)
6582
8eb7883b4223 [pylint] fix a bug of pylint detected errors and i18n pb (calling builtins._ instead of req._)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6575
diff changeset
   125
        w(''.join(data))
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   126
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   127
    def render_label(self, form, field):
2521
782360fa6cc0 take care to None labels
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2520
diff changeset
   128
        if field.label is None:
782360fa6cc0 take care to None labels
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2520
diff changeset
   129
            return u''
4313
5d8196a105a7 move base form renderer label handling into a function to reuse it in CompositeFormRenderer and avoid seeing a tuple in column headers...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4212
diff changeset
   130
        label = field_label(form, field)
4156
1bbb0ee42c8e drop form_field_name/form_field_id methods from form object, in favor of field.input_name(form) / field.dom_id(form)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4083
diff changeset
   131
        attrs = {'for': field.dom_id(form)}
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   132
        if field.required:
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   133
            attrs['class'] = 'required'
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   134
        return tags.label(label, **attrs)
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   135
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   136
    def render_help(self, form, field):
1946
d60ddfc4bb09 don't use tab
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1863
diff changeset
   137
        help = []
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   138
        descr = field.help
2093
e3aaf61f8c66 field's help may now be a callable taking the form as argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2006
diff changeset
   139
        if callable(descr):
6082
57933567146f [forms] callable field kwargs now always take form _and_ field parameters
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 5940
diff changeset
   140
            if support_args(descr, 'form', 'field'):
57933567146f [forms] callable field kwargs now always take form _and_ field parameters
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 5940
diff changeset
   141
                descr = descr(form, field)
57933567146f [forms] callable field kwargs now always take form _and_ field parameters
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 5940
diff changeset
   142
            else:
6575
18588fff9c97 [3.10] include field's info in deprecation warning
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6543
diff changeset
   143
                warn("[3.10] field's help callback must now take form and field as argument (%s)"
18588fff9c97 [3.10] include field's info in deprecation warning
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6543
diff changeset
   144
                     % field, DeprecationWarning)
6082
57933567146f [forms] callable field kwargs now always take form _and_ field parameters
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 5940
diff changeset
   145
                descr = descr(form)
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   146
        if descr:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3398
diff changeset
   147
            help.append('<div class="helper">%s</div>' % self._cw._(descr))
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3398
diff changeset
   148
        example = field.example_format(self._cw)
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   149
        if example:
1863
9a02979a2c00 do not use <br> in widgets
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 1757
diff changeset
   150
            help.append('<div class="helper">(%s: %s)</div>'
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3398
diff changeset
   151
                        % (self._cw._('sample format'), example))
2996
866a2c135c33 B #345282 xhtml requires to use &#160; instead of &nbsp;
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2656
diff changeset
   152
        return u'&#160;'.join(help)
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   153
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   154
    # specific methods (mostly to ease overriding) #############################
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   155
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   156
    def error_message(self, form):
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   157
        """return formatted error message
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   158
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   159
        This method should be called once inlined field errors has been consumed
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   160
        """
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3398
diff changeset
   161
        req = self._cw
1710
8c717cc0b353 refactor error handling: get validation error information from a form attribute instead of req.data to avoid pb when multiple forms are displayed
sylvain.thenault@logilab.fr
parents: 1691
diff changeset
   162
        errex = form.form_valerror
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   163
        # get extra errors
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   164
        if errex is not None:
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   165
            errormsg = req._('please correct the following errors:')
4224
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4181
diff changeset
   166
            errors = form.remaining_errors()
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   167
            if errors:
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   168
                if len(errors) > 1:
4783
6dc34d4cf892 [F] views: fix 2 unicode errors
Julien Jehannet <Julien Jehannet <julien.jehannet@logilab.fr>>
parents: 4743
diff changeset
   169
                    templstr = u'<li>%s</li>\n'
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   170
                else:
4783
6dc34d4cf892 [F] views: fix 2 unicode errors
Julien Jehannet <Julien Jehannet <julien.jehannet@logilab.fr>>
parents: 4743
diff changeset
   171
                    templstr = u'&#160;%s\n'
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   172
                for field, err in errors:
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   173
                    if field is None:
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   174
                        errormsg += templstr % err
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   175
                    else:
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   176
                        errormsg += templstr % '%s: %s' % (req._(field), err)
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   177
                if len(errors) > 1:
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   178
                    errormsg = '<ul>%s</ul>' % errormsg
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   179
            return u'<div class="errorMessage">%s</div>' % errormsg
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   180
        return u''
1436
97774eb6443b delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1434
diff changeset
   181
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   182
    def open_form(self, form, values):
4164
119a374c5eb4 form_add_hidden -> add_hidden
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4156
diff changeset
   183
        if form.needs_multipart:
6453
7fdd780d87e4 [form] unify form.render prototype to take a 'w' argument as other view/components render method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   184
            enctype = u'multipart/form-data'
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   185
        else:
6453
7fdd780d87e4 [form] unify form.render prototype to take a 'w' argument as other view/components render method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   186
            enctype = u'application/x-www-form-urlencoded'
7fdd780d87e4 [form] unify form.render prototype to take a 'w' argument as other view/components render method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   187
        tag = (u'<form action="%s" method="post" enctype="%s"' % (
5588
377c9adfe81e [forms] refactor action handling to ease overriding while keeping action overrideable by instance (closes #969167)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   188
            xml_escape(form.form_action() or '#'), enctype))
1274
b730932a79b7 we don't want dom id systematically
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
   189
        if form.domid:
6453
7fdd780d87e4 [form] unify form.render prototype to take a 'w' argument as other view/components render method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   190
            tag += u' id="%s"' % form.domid
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   191
        if form.onsubmit:
6453
7fdd780d87e4 [form] unify form.render prototype to take a 'w' argument as other view/components render method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   192
            tag += u' onsubmit="%s"' % xml_escape(form.onsubmit % dictattr(form))
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   193
        if form.cssstyle:
6453
7fdd780d87e4 [form] unify form.render prototype to take a 'w' argument as other view/components render method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   194
            tag += u' style="%s"' % xml_escape(form.cssstyle)
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   195
        if form.cssclass:
6453
7fdd780d87e4 [form] unify form.render prototype to take a 'w' argument as other view/components render method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   196
            tag += u' class="%s"' % xml_escape(form.cssclass)
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   197
        if form.cwtarget:
6453
7fdd780d87e4 [form] unify form.render prototype to take a 'w' argument as other view/components render method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   198
            tag += u' cubicweb:target="%s"' % xml_escape(form.cwtarget)
7fdd780d87e4 [form] unify form.render prototype to take a 'w' argument as other view/components render method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   199
        return tag + u'>'
1436
97774eb6443b delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1434
diff changeset
   200
4573
fc6bb020e60e use a close_form method for consistency w/ open_form and allow overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4380
diff changeset
   201
    def close_form(self, form, values):
4743
026a89520184 [book] a few autoclasses for renderers, misc tweaks
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4668
diff changeset
   202
        """seems dumb but important for consistency w/ close form, and necessary
4573
fc6bb020e60e use a close_form method for consistency w/ open_form and allow overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4380
diff changeset
   203
        for form renderers overriding open_form to use something else or more than
fc6bb020e60e use a close_form method for consistency w/ open_form and allow overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4380
diff changeset
   204
        and <form>
fc6bb020e60e use a close_form method for consistency w/ open_form and allow overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4380
diff changeset
   205
        """
6453
7fdd780d87e4 [form] unify form.render prototype to take a 'w' argument as other view/components render method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   206
        return u'</form>'
4573
fc6bb020e60e use a close_form method for consistency w/ open_form and allow overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4380
diff changeset
   207
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   208
    def render_fields(self, w, form, values):
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   209
        fields = self._render_hidden_fields(w, form)
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   210
        if fields:
1403
425892e14e67 _render_fields don't need values argument
sylvain.thenault@logilab.fr
parents: 1401
diff changeset
   211
            self._render_fields(fields, w, form)
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   212
        self.render_child_forms(w, form, values)
1436
97774eb6443b delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1434
diff changeset
   213
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   214
    def render_child_forms(self, w, form, values):
1436
97774eb6443b delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1434
diff changeset
   215
        # render
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   216
        for childform in getattr(form, 'forms', []):
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   217
            self.render_fields(w, childform, values)
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   218
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   219
    def _render_hidden_fields(self, w, form):
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   220
        fields = form.fields[:]
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   221
        for field in form.fields:
3478
f043f71017a3 handle display_fields in the form, not in the renderer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3477
diff changeset
   222
            if not field.is_visible():
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   223
                w(field.render(form, self))
6609
d73733479a3a oops, use unicode
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6597
diff changeset
   224
                w(u'\n')
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   225
                fields.remove(field)
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   226
        return fields
1436
97774eb6443b delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1434
diff changeset
   227
1403
425892e14e67 _render_fields don't need values argument
sylvain.thenault@logilab.fr
parents: 1401
diff changeset
   228
    def _render_fields(self, fields, w, form):
2520
8c5cf48ae9ea new fieldset attribute on field, use to group fields by the default form renderer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2381
diff changeset
   229
        byfieldset = {}
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   230
        for field in fields:
2520
8c5cf48ae9ea new fieldset attribute on field, use to group fields by the default form renderer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2381
diff changeset
   231
            byfieldset.setdefault(field.fieldset, []).append(field)
2574
37154aa90947 [form renderer] consider form.fieldsets_in_order if specified. Warn about unexistant or unused fieldsets.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2561
diff changeset
   232
        if form.fieldsets_in_order:
37154aa90947 [form renderer] consider form.fieldsets_in_order if specified. Warn about unexistant or unused fieldsets.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2561
diff changeset
   233
            fieldsets = form.fieldsets_in_order
37154aa90947 [form renderer] consider form.fieldsets_in_order if specified. Warn about unexistant or unused fieldsets.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2561
diff changeset
   234
        else:
37154aa90947 [form renderer] consider form.fieldsets_in_order if specified. Warn about unexistant or unused fieldsets.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2561
diff changeset
   235
            fieldsets = byfieldset.keys()
37154aa90947 [form renderer] consider form.fieldsets_in_order if specified. Warn about unexistant or unused fieldsets.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2561
diff changeset
   236
        for fieldset in fieldsets:
37154aa90947 [form renderer] consider form.fieldsets_in_order if specified. Warn about unexistant or unused fieldsets.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2561
diff changeset
   237
            try:
37154aa90947 [form renderer] consider form.fieldsets_in_order if specified. Warn about unexistant or unused fieldsets.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2561
diff changeset
   238
                fields = byfieldset.pop(fieldset)
37154aa90947 [form renderer] consider form.fieldsets_in_order if specified. Warn about unexistant or unused fieldsets.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2561
diff changeset
   239
            except KeyError:
37154aa90947 [form renderer] consider form.fieldsets_in_order if specified. Warn about unexistant or unused fieldsets.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2561
diff changeset
   240
                self.warning('no such fieldset: %s (%s)', fieldset, form)
37154aa90947 [form renderer] consider form.fieldsets_in_order if specified. Warn about unexistant or unused fieldsets.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2561
diff changeset
   241
                continue
6597
ba9fb496ad87 [test/renderer] fix html form/field generation & adapt a bit one test
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6582
diff changeset
   242
            w(u'<fieldset class="%s">\n' % (fieldset or u'default'))
2520
8c5cf48ae9ea new fieldset attribute on field, use to group fields by the default form renderer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2381
diff changeset
   243
            if fieldset:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3398
diff changeset
   244
                w(u'<legend>%s</legend>' % self._cw._(fieldset))
6597
ba9fb496ad87 [test/renderer] fix html form/field generation & adapt a bit one test
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6582
diff changeset
   245
            w(u'<table class="%s">\n' % self.table_class)
2520
8c5cf48ae9ea new fieldset attribute on field, use to group fields by the default form renderer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2381
diff changeset
   246
            for field in fields:
6597
ba9fb496ad87 [test/renderer] fix html form/field generation & adapt a bit one test
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6582
diff changeset
   247
                w(u'<tr class="%s_%s_row">\n' % (field.name, field.role))
4277
35cd057339b2 turn all the stuff used to handle 'generic relations' in forms into proper
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   248
                if self.display_label and field.label is not None:
6597
ba9fb496ad87 [test/renderer] fix html form/field generation & adapt a bit one test
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6582
diff changeset
   249
                    w(u'<th class="labelCol">%s</th>\n' % self.render_label(form, field))
6453
7fdd780d87e4 [form] unify form.render prototype to take a 'w' argument as other view/components render method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   250
                w(u'<td')
4277
35cd057339b2 turn all the stuff used to handle 'generic relations' in forms into proper
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   251
                if field.label is None:
6453
7fdd780d87e4 [form] unify form.render prototype to take a 'w' argument as other view/components render method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   252
                    w(u' colspan="2"')
4224
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4181
diff changeset
   253
                error = form.field_error(field)
2520
8c5cf48ae9ea new fieldset attribute on field, use to group fields by the default form renderer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2381
diff changeset
   254
                if error:
4277
35cd057339b2 turn all the stuff used to handle 'generic relations' in forms into proper
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   255
                    w(u' class="error"')
6597
ba9fb496ad87 [test/renderer] fix html form/field generation & adapt a bit one test
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6582
diff changeset
   256
                w(u'>\n')
2520
8c5cf48ae9ea new fieldset attribute on field, use to group fields by the default form renderer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2381
diff changeset
   257
                w(field.render(form, self))
6609
d73733479a3a oops, use unicode
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6597
diff changeset
   258
                w(u'\n')
5038
90493551b1eb [form] fix validation error handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4936
diff changeset
   259
                if error:
90493551b1eb [form] fix validation error handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4936
diff changeset
   260
                    self.render_error(w, error)
2520
8c5cf48ae9ea new fieldset attribute on field, use to group fields by the default form renderer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2381
diff changeset
   261
                if self.display_help:
8c5cf48ae9ea new fieldset attribute on field, use to group fields by the default form renderer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2381
diff changeset
   262
                    w(self.render_help(form, field))
6597
ba9fb496ad87 [test/renderer] fix html form/field generation & adapt a bit one test
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6582
diff changeset
   263
                w(u'</td></tr>\n')
ba9fb496ad87 [test/renderer] fix html form/field generation & adapt a bit one test
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6582
diff changeset
   264
            w(u'</table></fieldset>\n')
2574
37154aa90947 [form renderer] consider form.fieldsets_in_order if specified. Warn about unexistant or unused fieldsets.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2561
diff changeset
   265
        if byfieldset:
37154aa90947 [form renderer] consider form.fieldsets_in_order if specified. Warn about unexistant or unused fieldsets.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2561
diff changeset
   266
            self.warning('unused fieldsets: %s', ', '.join(byfieldset))
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   267
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   268
    def render_buttons(self, w, form):
2148
2b2b9626a98f do not write -invalid- empty table row when form has no buttons
Florent <florent@secondweb.fr>
parents: 2093
diff changeset
   269
        if not form.form_buttons:
2b2b9626a98f do not write -invalid- empty table row when form has no buttons
Florent <florent@secondweb.fr>
parents: 2093
diff changeset
   270
            return
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   271
        w(u'<table class="%s">\n<tr>\n' % self.button_bar_class)
1304
8975c8e520a9 refactor button handling
sylvain.thenault@logilab.fr
parents: 1293
diff changeset
   272
        for button in form.form_buttons:
8975c8e520a9 refactor button handling
sylvain.thenault@logilab.fr
parents: 1293
diff changeset
   273
            w(u'<td>%s</td>\n' % button.render(form))
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   274
        w(u'</tr></table>')
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   275
4224
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4181
diff changeset
   276
    def render_error(self, w, err):
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4181
diff changeset
   277
        """return validation error for widget's field, if any"""
5038
90493551b1eb [form] fix validation error handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4936
diff changeset
   278
        w(u'<span class="errorMsg">%s</span>' % err)
4224
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4181
diff changeset
   279
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4181
diff changeset
   280
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   281
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1995
diff changeset
   282
class BaseFormRenderer(FormRenderer):
2198
ac45d4dbaf76 close #344264, pb with composite fields / renderer.display_fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2148
diff changeset
   283
    """use form_renderer_id = 'base' if you want base FormRenderer layout even
ac45d4dbaf76 close #344264, pb with composite fields / renderer.display_fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2148
diff changeset
   284
    when selected for an entity
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1995
diff changeset
   285
    """
3377
dd9d292b6a6d use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3369
diff changeset
   286
    __regid__ = 'base'
2198
ac45d4dbaf76 close #344264, pb with composite fields / renderer.display_fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2148
diff changeset
   287
ac45d4dbaf76 close #344264, pb with composite fields / renderer.display_fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2148
diff changeset
   288
ac45d4dbaf76 close #344264, pb with composite fields / renderer.display_fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2148
diff changeset
   289
1401
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
   290
class HTableFormRenderer(FormRenderer):
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5038
diff changeset
   291
    """The 'htable' form renderer display fields horizontally in a table:
1401
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
   292
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
   293
    +--------------+--------------+---------+
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
   294
    | field1 label | field2 label |         |
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
   295
    +--------------+--------------+---------+
4936
a4b772a0d801 Fixed some of the documentation warnings when building the book with sphinx.
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 4783
diff changeset
   296
    | field1 input | field2 input | buttons |
1436
97774eb6443b delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1434
diff changeset
   297
    +--------------+--------------+---------+
1401
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
   298
    """
3377
dd9d292b6a6d use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3369
diff changeset
   299
    __regid__ = 'htable'
1995
ec95eaa2b711 turn renderers into appobjects
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   300
1401
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
   301
    display_help = False
1403
425892e14e67 _render_fields don't need values argument
sylvain.thenault@logilab.fr
parents: 1401
diff changeset
   302
    def _render_fields(self, fields, w, form):
3572
606ce53dc557 [forms] some style for htable renderer layout
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3519
diff changeset
   303
        w(u'<table border="0" class="htableForm">')
1401
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
   304
        w(u'<tr>')
1436
97774eb6443b delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1434
diff changeset
   305
        for field in fields:
1401
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
   306
            if self.display_label:
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
   307
                w(u'<th class="labelCol">%s</th>' % self.render_label(form, field))
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
   308
            if self.display_help:
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
   309
                w(self.render_help(form, field))
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
   310
        # empty slot for buttons
2996
866a2c135c33 B #345282 xhtml requires to use &#160; instead of &nbsp;
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2656
diff changeset
   311
        w(u'<th class="labelCol">&#160;</th>')
1401
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
   312
        w(u'</tr>')
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
   313
        w(u'<tr>')
1436
97774eb6443b delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1434
diff changeset
   314
        for field in fields:
4224
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4181
diff changeset
   315
            error = form.field_error(field)
1401
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
   316
            if error:
1757
fbb9928bf4f1 remove fixed width
sylvain.thenault@logilab.fr
parents: 1710
diff changeset
   317
                w(u'<td class="error">')
4224
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4181
diff changeset
   318
                self.render_error(w, error)
1401
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
   319
            else:
1757
fbb9928bf4f1 remove fixed width
sylvain.thenault@logilab.fr
parents: 1710
diff changeset
   320
                w(u'<td>')
1401
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
   321
            w(field.render(form, self))
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
   322
            w(u'</td>')
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
   323
        w(u'<td>')
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
   324
        for button in form.form_buttons:
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
   325
            w(button.render(form))
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
   326
        w(u'</td>')
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
   327
        w(u'</tr>')
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
   328
        w(u'</table>')
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
   329
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
   330
    def render_buttons(self, w, form):
56764b1b4887 new renderer displaying field in an horizontable table
sylvain.thenault@logilab.fr
parents: 1362
diff changeset
   331
        pass
1436
97774eb6443b delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1434
diff changeset
   332
97774eb6443b delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1434
diff changeset
   333
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   334
class EntityCompositeFormRenderer(FormRenderer):
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5038
diff changeset
   335
    """This is a specific renderer for the multiple entities edition form
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5038
diff changeset
   336
    ('muledit').
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5038
diff changeset
   337
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5038
diff changeset
   338
    Each entity form will be displayed in row off a table, with a check box for
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5038
diff changeset
   339
    each entities to indicate which ones are edited. Those checkboxes should be
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5038
diff changeset
   340
    automatically updated when something is edited.
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5038
diff changeset
   341
    """
3377
dd9d292b6a6d use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3369
diff changeset
   342
    __regid__ = 'composite'
1436
97774eb6443b delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1434
diff changeset
   343
2575
e033939d5664 [form renderer] fix composite form renderer in case the main form has some visible fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2574
diff changeset
   344
    _main_display_fields = None
e033939d5664 [form renderer] fix composite form renderer in case the main form has some visible fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2574
diff changeset
   345
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   346
    def render_fields(self, w, form, values):
3513
c002f6488631 [form] replace is_subform by parent_form, carrying more information at the same cost
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3510
diff changeset
   347
        if form.parent_form is None:
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   348
            w(u'<table class="listing">')
6357
2d277c67f103 [muledit] form may contains subforms with nothing editable that will be s kipped, so ensure we choose one with something to display when rendering table headers
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5940
diff changeset
   349
            # get fields from the first subform with something to display (we
2d277c67f103 [muledit] form may contains subforms with nothing editable that will be s kipped, so ensure we choose one with something to display when rendering table headers
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5940
diff changeset
   350
            # may have subforms with nothing editable that will simply be
2d277c67f103 [muledit] form may contains subforms with nothing editable that will be s kipped, so ensure we choose one with something to display when rendering table headers
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5940
diff changeset
   351
            # skipped later)
2d277c67f103 [muledit] form may contains subforms with nothing editable that will be s kipped, so ensure we choose one with something to display when rendering table headers
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5940
diff changeset
   352
            for subform in form.forms:
2d277c67f103 [muledit] form may contains subforms with nothing editable that will be s kipped, so ensure we choose one with something to display when rendering table headers
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5940
diff changeset
   353
                subfields = [field for field in subform.fields
2d277c67f103 [muledit] form may contains subforms with nothing editable that will be s kipped, so ensure we choose one with something to display when rendering table headers
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5940
diff changeset
   354
                             if field.is_visible()]
2d277c67f103 [muledit] form may contains subforms with nothing editable that will be s kipped, so ensure we choose one with something to display when rendering table headers
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5940
diff changeset
   355
                if subfields:
2d277c67f103 [muledit] form may contains subforms with nothing editable that will be s kipped, so ensure we choose one with something to display when rendering table headers
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5940
diff changeset
   356
                    break
2586
879912fe94e1 [xhtml form renderer] fix html structure, move header where we are sure to display it when necesary (_render_fields not displayed if main form has no visible fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2577
diff changeset
   357
            if subfields:
879912fe94e1 [xhtml form renderer] fix html structure, move header where we are sure to display it when necesary (_render_fields not displayed if main form has no visible fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2577
diff changeset
   358
                # main form, display table headers
879912fe94e1 [xhtml form renderer] fix html structure, move header where we are sure to display it when necesary (_render_fields not displayed if main form has no visible fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2577
diff changeset
   359
                w(u'<tr class="header">')
879912fe94e1 [xhtml form renderer] fix html structure, move header where we are sure to display it when necesary (_render_fields not displayed if main form has no visible fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2577
diff changeset
   360
                w(u'<th align="left">%s</th>' %
879912fe94e1 [xhtml form renderer] fix html structure, move header where we are sure to display it when necesary (_render_fields not displayed if main form has no visible fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2577
diff changeset
   361
                  tags.input(type='checkbox',
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3398
diff changeset
   362
                             title=self._cw._('toggle check boxes'),
5658
7b9553a9db65 [ajax] refactor/cleanup low-level ajax functions
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 5588
diff changeset
   363
                             onclick="setCheckboxesState('eid', null, this.checked)"))
2586
879912fe94e1 [xhtml form renderer] fix html structure, move header where we are sure to display it when necesary (_render_fields not displayed if main form has no visible fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2577
diff changeset
   364
                for field in subfields:
4313
5d8196a105a7 move base form renderer label handling into a function to reuse it in CompositeFormRenderer and avoid seeing a tuple in column headers...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4212
diff changeset
   365
                    w(u'<th>%s</th>' % field_label(form, field))
2586
879912fe94e1 [xhtml form renderer] fix html structure, move header where we are sure to display it when necesary (_render_fields not displayed if main form has no visible fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2577
diff changeset
   366
                w(u'</tr>')
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   367
        super(EntityCompositeFormRenderer, self).render_fields(w, form, values)
3513
c002f6488631 [form] replace is_subform by parent_form, carrying more information at the same cost
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3510
diff changeset
   368
        if form.parent_form is None:
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   369
            w(u'</table>')
2575
e033939d5664 [form renderer] fix composite form renderer in case the main form has some visible fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2574
diff changeset
   370
            if self._main_display_fields:
e033939d5664 [form renderer] fix composite form renderer in case the main form has some visible fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2574
diff changeset
   371
                super(EntityCompositeFormRenderer, self)._render_fields(
e033939d5664 [form renderer] fix composite form renderer in case the main form has some visible fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2574
diff changeset
   372
                    self._main_display_fields, w, form)
1436
97774eb6443b delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1434
diff changeset
   373
1403
425892e14e67 _render_fields don't need values argument
sylvain.thenault@logilab.fr
parents: 1401
diff changeset
   374
    def _render_fields(self, fields, w, form):
3513
c002f6488631 [form] replace is_subform by parent_form, carrying more information at the same cost
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3510
diff changeset
   375
        if form.parent_form is not None:
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   376
            entity = form.edited_entity
1710
8c717cc0b353 refactor error handling: get validation error information from a form attribute instead of req.data to avoid pb when multiple forms are displayed
sylvain.thenault@logilab.fr
parents: 1691
diff changeset
   377
            values = form.form_previous_values
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   378
            qeid = eid_param('eid', entity.eid)
5658
7b9553a9db65 [ajax] refactor/cleanup low-level ajax functions
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 5588
diff changeset
   379
            cbsetstate = "setCheckboxesState('eid', %s, 'checked')" % \
5940
0e3ae19b181a [uilib] refactor json_dumps code organization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   380
                         xml_escape(json_dumps(entity.eid))
3467
a6405235aac6 [tests] make unittest_views_editforms pass again
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3451
diff changeset
   381
            w(u'<tr class="%s">' % (entity.cw_row % 2 and u'even' or u'odd'))
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   382
            # XXX turn this into a widget used on the eid field
2577
7c9888114085 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2575
diff changeset
   383
            w(u'<td>%s</td>' % checkbox('eid', entity.eid,
7c9888114085 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2575
diff changeset
   384
                                        checked=qeid in values))
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   385
            for field in fields:
4224
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4181
diff changeset
   386
                error = form.field_error(field)
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   387
                if error:
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   388
                    w(u'<td class="error">')
4224
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4181
diff changeset
   389
                    self.render_error(w, error)
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   390
                else:
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   391
                    w(u'<td>')
2577
7c9888114085 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2575
diff changeset
   392
                if isinstance(field.widget, (fwdgs.Select, fwdgs.CheckBox,
7c9888114085 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2575
diff changeset
   393
                                             fwdgs.Radio)):
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   394
                    field.widget.attrs['onchange'] = cbsetstate
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   395
                elif isinstance(field.widget, fwdgs.Input):
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   396
                    field.widget.attrs['onkeypress'] = cbsetstate
2577
7c9888114085 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2575
diff changeset
   397
                # XXX else
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   398
                w(u'<div>%s</div>' % field.render(form, self))
2586
879912fe94e1 [xhtml form renderer] fix html structure, move header where we are sure to display it when necesary (_render_fields not displayed if main form has no visible fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2577
diff changeset
   399
                w(u'</td>\n')
879912fe94e1 [xhtml form renderer] fix html structure, move header where we are sure to display it when necesary (_render_fields not displayed if main form has no visible fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2577
diff changeset
   400
            w(u'</tr>')
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   401
        else:
2575
e033939d5664 [form renderer] fix composite form renderer in case the main form has some visible fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2574
diff changeset
   402
            self._main_display_fields = fields
1436
97774eb6443b delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1434
diff changeset
   403
97774eb6443b delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1434
diff changeset
   404
3478
f043f71017a3 handle display_fields in the form, not in the renderer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3477
diff changeset
   405
class EntityFormRenderer(BaseFormRenderer):
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5038
diff changeset
   406
    """This is the 'default' renderer for entity's form.
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5038
diff changeset
   407
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5038
diff changeset
   408
    You can still use form_renderer_id = 'base' if you want base FormRenderer
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5038
diff changeset
   409
    layout even when selected for an entity.
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5038
diff changeset
   410
    """
3377
dd9d292b6a6d use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3369
diff changeset
   411
    __regid__ = 'default'
2198
ac45d4dbaf76 close #344264, pb with composite fields / renderer.display_fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2148
diff changeset
   412
    # needs some additional points in some case (XXX explain cases)
5877
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   413
    __select__ = is_instance('Any') & yes()
1995
ec95eaa2b711 turn renderers into appobjects
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   414
4293
0c4bdb3d93fd delete remaining stuff w/ handling of the generic relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4278
diff changeset
   415
    _options = FormRenderer._options + ('main_form_title',)
3592
4c08780e54ed [i18n] msgid tweaks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3572
diff changeset
   416
    main_form_title = _('main informations')
1436
97774eb6443b delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1434
diff changeset
   417
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   418
    def open_form(self, form, values):
3507
ff945c7013d9 [form] make EntityFormRenderer a little bit easier to override
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 3360
diff changeset
   419
        attrs_fs_label = ''
ff945c7013d9 [form] make EntityFormRenderer a little bit easier to override
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 3360
diff changeset
   420
        if self.main_form_title:
ff945c7013d9 [form] make EntityFormRenderer a little bit easier to override
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 3360
diff changeset
   421
            attrs_fs_label += ('<div class="iformTitle"><span>%s</span></div>'
4073
03681ba6da0b cw 3.6 api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4023
diff changeset
   422
                               % self._cw._(self.main_form_title))
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   423
        attrs_fs_label += '<div class="formBody">'
1181
620ec8e6ae19 cleanup, various fix to get something working
sylvain.thenault@logilab.fr
parents: 1147
diff changeset
   424
        return attrs_fs_label + super(EntityFormRenderer, self).open_form(form, values)
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   425
5830
23ea56123670 EntityFormRenderer redefine open_form and add a div section, so redefine close_form to add the closing div tag
Stéphanie Marcu <steph@logilab.fr>
parents: 5829
diff changeset
   426
    def close_form(self, form, values):
23ea56123670 EntityFormRenderer redefine open_form and add a div section, so redefine close_form to add the closing div tag
Stéphanie Marcu <steph@logilab.fr>
parents: 5829
diff changeset
   427
        """seems dumb but important for consistency w/ close form, and necessary
23ea56123670 EntityFormRenderer redefine open_form and add a div section, so redefine close_form to add the closing div tag
Stéphanie Marcu <steph@logilab.fr>
parents: 5829
diff changeset
   428
        for form renderers overriding open_form to use something else or more than
23ea56123670 EntityFormRenderer redefine open_form and add a div section, so redefine close_form to add the closing div tag
Stéphanie Marcu <steph@logilab.fr>
parents: 5829
diff changeset
   429
        and <form>
23ea56123670 EntityFormRenderer redefine open_form and add a div section, so redefine close_form to add the closing div tag
Stéphanie Marcu <steph@logilab.fr>
parents: 5829
diff changeset
   430
        """
23ea56123670 EntityFormRenderer redefine open_form and add a div section, so redefine close_form to add the closing div tag
Stéphanie Marcu <steph@logilab.fr>
parents: 5829
diff changeset
   431
        return super(EntityFormRenderer, self).close_form(form, values) + '</div>'
23ea56123670 EntityFormRenderer redefine open_form and add a div section, so redefine close_form to add the closing div tag
Stéphanie Marcu <steph@logilab.fr>
parents: 5829
diff changeset
   432
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   433
    def render_buttons(self, w, form):
1304
8975c8e520a9 refactor button handling
sylvain.thenault@logilab.fr
parents: 1293
diff changeset
   434
        if len(form.form_buttons) == 3:
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   435
            w("""<table width="100%%">
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   436
  <tbody>
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   437
   <tr><td align="center">
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   438
     %s
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   439
   </td><td style="align: right; width: 50%%;">
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   440
     %s
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   441
     %s
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   442
   </td></tr>
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   443
  </tbody>
1304
8975c8e520a9 refactor button handling
sylvain.thenault@logilab.fr
parents: 1293
diff changeset
   444
 </table>""" % tuple(button.render(form) for button in form.form_buttons))
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   445
        else:
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   446
            super(EntityFormRenderer, self).render_buttons(w, form)
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   447
1436
97774eb6443b delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1434
diff changeset
   448
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   449
class EntityInlinedFormRenderer(EntityFormRenderer):
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5038
diff changeset
   450
    """This is a specific renderer for entity's form inlined into another
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5038
diff changeset
   451
    entity's form.
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   452
    """
3377
dd9d292b6a6d use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3369
diff changeset
   453
    __regid__ = 'inline'
1995
ec95eaa2b711 turn renderers into appobjects
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   454
6453
7fdd780d87e4 [form] unify form.render prototype to take a 'w' argument as other view/components render method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   455
    def render(self, w, form, values):
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   456
        form.add_media()
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   457
        try:
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   458
            w(u'<div id="div-%(divid)s" onclick="%(divonclick)s">' % values)
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   459
        except KeyError:
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   460
            w(u'<div id="div-%(divid)s">' % values)
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   461
        else:
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   462
            w(u'<div id="notice-%s" class="notice">%s</div>' % (
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3398
diff changeset
   463
                values['divid'], self._cw._('click on the box to cancel the deletion')))
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   464
        w(u'<div class="iformBody">')
3327
44efba78afac fix/enhance i18n context usage for inlined forms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3275
diff changeset
   465
        eschema = form.edited_entity.e_schema
5769
b3b48e0b8e3b [autoform] do not show remove link for inline form if card == 1
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5588
diff changeset
   466
        if values['removejs']:
b3b48e0b8e3b [autoform] do not show remove link for inline form if card == 1
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5588
diff changeset
   467
            values['removemsg'] = self._cw._('remove-inlined-entity-form')
b3b48e0b8e3b [autoform] do not show remove link for inline form if card == 1
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5588
diff changeset
   468
            w(u'<div class="iformTitle"><span>%(title)s</span> '
b3b48e0b8e3b [autoform] do not show remove link for inline form if card == 1
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5588
diff changeset
   469
              '#<span class="icounter">%(counter)s</span> '
6543
66145280a7e6 [js] remove deprecation warnings by using $.noop instead of noop
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6453
diff changeset
   470
              '[<a href="javascript: %(removejs)s;$.noop();">%(removemsg)s</a>]</div>'
5769
b3b48e0b8e3b [autoform] do not show remove link for inline form if card == 1
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5588
diff changeset
   471
              % values)
b3b48e0b8e3b [autoform] do not show remove link for inline form if card == 1
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5588
diff changeset
   472
        else:
b3b48e0b8e3b [autoform] do not show remove link for inline form if card == 1
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5588
diff changeset
   473
            w(u'<div class="iformTitle"><span>%(title)s</span> '
b3b48e0b8e3b [autoform] do not show remove link for inline form if card == 1
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5588
diff changeset
   474
              '#<span class="icounter">%(counter)s</span></div>'
b3b48e0b8e3b [autoform] do not show remove link for inline form if card == 1
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5588
diff changeset
   475
              % values)
b3b48e0b8e3b [autoform] do not show remove link for inline form if card == 1
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5588
diff changeset
   476
        # XXX that stinks
1964
b60719223965 need to cleanup values if we don't want them to be interpreted by fields (title is a common field name for instance)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1946
diff changeset
   477
        # cleanup values
b60719223965 need to cleanup values if we don't want them to be interpreted by fields (title is a common field name for instance)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1946
diff changeset
   478
        for key in ('title', 'removejs', 'removemsg'):
5769
b3b48e0b8e3b [autoform] do not show remove link for inline form if card == 1
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5588
diff changeset
   479
            values.pop(key, None)
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   480
        self.render_fields(w, form, values)
1293
aae1516b6426 missing closing div
sylvain.thenault@logilab.fr
parents: 1292
diff changeset
   481
        w(u'</div></div>')
1436
97774eb6443b delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1434
diff changeset
   482
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   483
    def render_fields(self, w, form, values):
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   484
        w(u'<fieldset id="fs-%(divid)s">' % values)
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   485
        fields = self._render_hidden_fields(w, form)
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   486
        w(u'</fieldset>')
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   487
        w(u'<fieldset class="subentity">')
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   488
        if fields:
1403
425892e14e67 _render_fields don't need values argument
sylvain.thenault@logilab.fr
parents: 1401
diff changeset
   489
            self._render_fields(fields, w, form)
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   490
        self.render_child_forms(w, form, values)
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents:
diff changeset
   491
        w(u'</fieldset>')
1436
97774eb6443b delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1434
diff changeset
   492