web/views/forms.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Tue, 23 Feb 2010 12:43:15 +0100
branchstable
changeset 4658 25de2eb0432b
parent 4583 356f08325072
child 4659 f8326ff98f37
permissions -rw-r--r--
[form] add a new ignore_req_params attribute on field controlling value's retreival for such field, such as eid/__type in entity forms, we don't want to consider values from req.form since we may get undesired value (as reported by #714766). This new attribute allow do specify that we don't want to consider req.form in such case. Also, it seems that retreival of form values after a validation error suffer from the same problem, so don't use form_previous_values for field with ignore_req_params set to True (XXX though I suppose that may not be correct in some cases).
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     1
"""some base form classes for CubicWeb web client
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     2
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     3
:organization: Logilab
4212
ab6573088b4a update copyright: welcome 2010
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4210
diff changeset
     4
:copyright: 2001-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     5
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     6
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     7
"""
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     8
__docformat__ = "restructuredtext en"
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     9
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    10
from warnings import warn
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    11
4236
9260403bfe0b move autoform's field_by_name implementation on base EntityFieldsForm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4224
diff changeset
    12
from logilab.common.decorators import iclassmethod
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    13
from logilab.common.compat import any
3953
19aefd78f61b [forms] deprecate form_render(**kwargs) in favor of render(formvalues=None, rendervalues=None, renderer=None)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3923
diff changeset
    14
from logilab.common.deprecation import deprecated
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    15
4159
6b2b20c73d59 refactor form field value handling, to get a nicer api and an easier algorithm to get field's value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4156
diff changeset
    16
from cubicweb import typed_eid
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    17
from cubicweb.selectors import non_final_entity, match_kwargs, one_line_rset
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    18
from cubicweb.web import INTERNAL_FIELD_VALUE, eid_param
4236
9260403bfe0b move autoform's field_by_name implementation on base EntityFieldsForm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4224
diff changeset
    19
from cubicweb.web import uicfg, form, formwidgets as fwdgs
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    20
from cubicweb.web.controller import NAV_FORM_PARAMETERS
4236
9260403bfe0b move autoform's field_by_name implementation on base EntityFieldsForm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4224
diff changeset
    21
from cubicweb.web.formfields import StringField, relvoc_unrelated, guess_field
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    22
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    23
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    24
class FieldsForm(form.Form):
2573
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    25
    """base class for fields based forms.
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    26
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    27
    The following attributes may be either set on subclasses or given on
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    28
    form selection to customize the generated form:
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    29
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    30
    * `needs_js`: sequence of javascript files that should be added to handle
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    31
      this form (through `req.add_js`)
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    32
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    33
    * `needs_css`: sequence of css files that should be added to handle this
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    34
      form (through `req.add_css`)
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    35
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    36
    * `domid`: value for the "id" attribute of the <form> tag
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    37
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    38
    * `action`: value for the "action" attribute of the <form> tag
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    39
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    40
    * `onsubmit`: value for the "onsubmit" attribute of the <form> tag
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    41
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    42
    * `cssclass`: value for the "class" attribute of the <form> tag
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    43
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    44
    * `cssstyle`: value for the "style" attribute of the <form> tag
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    45
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    46
    * `cwtarget`: value for the "cubicweb:target" attribute of the <form> tag
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    47
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    48
    * `redirect_path`: relative to redirect to after submitting the form
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    49
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    50
    * `copy_nav_params`: flag telling if navigation paramenters should be copied
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    51
      back in hidden input
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    52
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    53
    * `form_buttons`:  form buttons sequence (button widgets instances)
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    54
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    55
    * `form_renderer_id`: id of the form renderer to use to render the form
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    56
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    57
    * `fieldsets_in_order`: fieldset name sequence, to control order
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    58
    """
3377
dd9d292b6a6d use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3369
diff changeset
    59
    __regid__ = 'base'
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    60
2573
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    61
    internal_fields = ('__errorurl',) + NAV_FORM_PARAMETERS
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    62
2573
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    63
    # attributes overrideable by subclasses or through __init__
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    64
    needs_js = ('cubicweb.ajax.js', 'cubicweb.edition.js',)
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    65
    needs_css = ('cubicweb.form.css',)
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    66
    domid = 'form'
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    67
    action = None
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    68
    onsubmit = "return freezeFormButtons('%(domid)s');"
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    69
    cssclass = None
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    70
    cssstyle = None
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    71
    cwtarget = None
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    72
    redirect_path = None
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    73
    copy_nav_params = False
2573
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    74
    form_buttons = None
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    75
    form_renderer_id = 'default'
2573
9c414dbc76da add default values for fielsets_in_order, document base form attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    76
    fieldsets_in_order = None
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    77
2048
5e4d1433b90b replace set_error_url/set_dom_id by a single mainform argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2046
diff changeset
    78
    def __init__(self, req, rset=None, row=None, col=None,
5e4d1433b90b replace set_error_url/set_dom_id by a single mainform argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2046
diff changeset
    79
                 submitmsg=None, mainform=True,
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    80
                 **kwargs):
2890
fdcb8a2bb6eb fix __init__ parameters
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2657
diff changeset
    81
        super(FieldsForm, self).__init__(req, rset=rset, row=row, col=col)
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    82
        self.fields = list(self.__class__._fields_)
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    83
        for key, val in kwargs.items():
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    84
            if key in NAV_FORM_PARAMETERS:
4164
119a374c5eb4 form_add_hidden -> add_hidden
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4162
diff changeset
    85
                self.add_hidden(key, val)
3340
7dfccf5612ed [form] simply skip unknown argument given to form constructor, don't fail
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3245
diff changeset
    86
            elif hasattr(self.__class__, key) and not key[0] == '_':
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    87
                setattr(self, key, val)
3516
5f18e71e3d42 [form] put unknown constructor args into extra_kwargs and consider them when looking for field display values
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3513
diff changeset
    88
            else:
4082
c7117119e215 3.6 api update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4047
diff changeset
    89
                self.cw_extra_kwargs[key] = val
3340
7dfccf5612ed [form] simply skip unknown argument given to form constructor, don't fail
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3245
diff changeset
    90
            # skip other parameters, usually given for selection
7dfccf5612ed [form] simply skip unknown argument given to form constructor, don't fail
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3245
diff changeset
    91
            # (else write a custom class to handle them)
2048
5e4d1433b90b replace set_error_url/set_dom_id by a single mainform argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2046
diff changeset
    92
        if mainform:
4164
119a374c5eb4 form_add_hidden -> add_hidden
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4162
diff changeset
    93
            self.add_hidden('__errorurl', self.session_key())
119a374c5eb4 form_add_hidden -> add_hidden
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4162
diff changeset
    94
            self.add_hidden('__domid', self.domid)
3923
be05eeeb2db1 fix previous post values handling (eg on validation error) for sub-forms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3922
diff changeset
    95
            self.restore_previous_post(self.session_key())
be05eeeb2db1 fix previous post values handling (eg on validation error) for sub-forms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3922
diff changeset
    96
3880
88fc53eb5b5f [forms] muledit mainform should copy nav params, its subforms shouldn't
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3689
diff changeset
    97
        # XXX why do we need two different variables (mainform and copy_nav_params ?)
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    98
        if self.copy_nav_params:
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    99
            for param in NAV_FORM_PARAMETERS:
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   100
                if not param in kwargs:
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   101
                    value = req.form.get(param)
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   102
                    if value:
4164
119a374c5eb4 form_add_hidden -> add_hidden
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4162
diff changeset
   103
                        self.add_hidden(param, value)
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   104
        if submitmsg is not None:
4164
119a374c5eb4 form_add_hidden -> add_hidden
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4162
diff changeset
   105
            self.add_hidden('__message', submitmsg)
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   106
        if 'domid' in kwargs:# session key changed
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   107
            self.restore_previous_post(self.session_key())
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   108
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   109
    @property
4164
119a374c5eb4 form_add_hidden -> add_hidden
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4162
diff changeset
   110
    def needs_multipart(self):
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   111
        """true if the form needs enctype=multipart/form-data"""
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   112
        return any(field.needs_multipart for field in self.fields)
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   113
4164
119a374c5eb4 form_add_hidden -> add_hidden
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4162
diff changeset
   114
    def add_hidden(self, name, value=None, **kwargs):
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   115
        """add an hidden field to the form"""
2270
70c0da0f2181 should use a hidden text area for error description, not an hidden input (else the browser may remove line breaks)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2089
diff changeset
   116
        kwargs.setdefault('widget', fwdgs.HiddenInput)
4159
6b2b20c73d59 refactor form field value handling, to get a nicer api and an easier algorithm to get field's value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4156
diff changeset
   117
        field = StringField(name=name, value=value, **kwargs)
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   118
        if 'id' in kwargs:
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   119
            # by default, hidden input don't set id attribute. If one is
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   120
            # explicitly specified, ensure it will be set
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   121
            field.widget.setdomid = True
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   122
        self.append_field(field)
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   123
        return field
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   124
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   125
    def add_media(self):
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   126
        """adds media (CSS & JS) required by this widget"""
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   127
        if self.needs_js:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   128
            self._cw.add_js(self.needs_js)
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   129
        if self.needs_css:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   130
            self._cw.add_css(self.needs_css)
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   131
4167
73e649a7797d fix render (formerly form_render) prototype
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4164
diff changeset
   132
    def render(self, formvalues=None, rendervalues=None, renderer=None, **kwargs):
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   133
        """render this form, using the renderer given in args or the default
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   134
        FormRenderer()
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   135
        """
4167
73e649a7797d fix render (formerly form_render) prototype
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4164
diff changeset
   136
        if rendervalues is not None:
73e649a7797d fix render (formerly form_render) prototype
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4164
diff changeset
   137
            warn('[3.6] rendervalues argument is deprecated, all named arguments will be given instead',
4284
8e5dcb54fd8e fix warning stack level
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4260
diff changeset
   138
                 DeprecationWarning, stacklevel=2)
4167
73e649a7797d fix render (formerly form_render) prototype
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4164
diff changeset
   139
            kwargs = rendervalues
73e649a7797d fix render (formerly form_render) prototype
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4164
diff changeset
   140
        self.build_context(formvalues)
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   141
        if renderer is None:
4164
119a374c5eb4 form_add_hidden -> add_hidden
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4162
diff changeset
   142
            renderer = self.default_renderer()
119a374c5eb4 form_add_hidden -> add_hidden
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4162
diff changeset
   143
        return renderer.render(self, kwargs)
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   144
4164
119a374c5eb4 form_add_hidden -> add_hidden
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4162
diff changeset
   145
    def default_renderer(self):
119a374c5eb4 form_add_hidden -> add_hidden
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4162
diff changeset
   146
        return self._cw.vreg['formrenderers'].select(
119a374c5eb4 form_add_hidden -> add_hidden
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4162
diff changeset
   147
            self.form_renderer_id, self._cw,
119a374c5eb4 form_add_hidden -> add_hidden
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4162
diff changeset
   148
            rset=self.cw_rset, row=self.cw_row, col=self.cw_col)
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   149
4159
6b2b20c73d59 refactor form field value handling, to get a nicer api and an easier algorithm to get field's value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4156
diff changeset
   150
    formvalues = None
6b2b20c73d59 refactor form field value handling, to get a nicer api and an easier algorithm to get field's value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4156
diff changeset
   151
    def build_context(self, formvalues=None):
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   152
        """build form context values (the .context attribute which is a
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   153
        dictionary with field instance as key associated to a dictionary
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   154
        containing field 'name' (qualified), 'id', 'value' (for display, always
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   155
        a string).
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   156
        """
4159
6b2b20c73d59 refactor form field value handling, to get a nicer api and an easier algorithm to get field's value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4156
diff changeset
   157
        if self.formvalues is not None:
3510
bf746bf4a394 rename form_build_context to build_context, and call it from form, not renderer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3354
diff changeset
   158
            return # already built
4159
6b2b20c73d59 refactor form field value handling, to get a nicer api and an easier algorithm to get field's value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4156
diff changeset
   159
        self.formvalues = formvalues or {}
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   160
        # use a copy in case fields are modified while context is build (eg
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   161
        # __linkto handling for instance)
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   162
        for field in self.fields[:]:
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   163
            for field in field.actual_fields(self):
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   164
                field.form_init(self)
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   165
4164
119a374c5eb4 form_add_hidden -> add_hidden
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4162
diff changeset
   166
    @deprecated('[3.6] use .add_hidden(name, value, **kwargs)')
119a374c5eb4 form_add_hidden -> add_hidden
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4162
diff changeset
   167
    def form_add_hidden(self, name, value=None, **kwargs):
119a374c5eb4 form_add_hidden -> add_hidden
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4162
diff changeset
   168
        return self.add_hidden(name, value, **kwargs)
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   169
4164
119a374c5eb4 form_add_hidden -> add_hidden
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4162
diff changeset
   170
    @deprecated('[3.6] use .render(formvalues, **rendervalues)')
3953
19aefd78f61b [forms] deprecate form_render(**kwargs) in favor of render(formvalues=None, rendervalues=None, renderer=None)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3923
diff changeset
   171
    def form_render(self, **values):
19aefd78f61b [forms] deprecate form_render(**kwargs) in favor of render(formvalues=None, rendervalues=None, renderer=None)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3923
diff changeset
   172
        """render this form, using the renderer given in args or the default
19aefd78f61b [forms] deprecate form_render(**kwargs) in favor of render(formvalues=None, rendervalues=None, renderer=None)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3923
diff changeset
   173
        FormRenderer()
19aefd78f61b [forms] deprecate form_render(**kwargs) in favor of render(formvalues=None, rendervalues=None, renderer=None)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3923
diff changeset
   174
        """
19aefd78f61b [forms] deprecate form_render(**kwargs) in favor of render(formvalues=None, rendervalues=None, renderer=None)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3923
diff changeset
   175
        self.build_context(values)
19aefd78f61b [forms] deprecate form_render(**kwargs) in favor of render(formvalues=None, rendervalues=None, renderer=None)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3923
diff changeset
   176
        renderer = values.pop('renderer', None)
19aefd78f61b [forms] deprecate form_render(**kwargs) in favor of render(formvalues=None, rendervalues=None, renderer=None)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3923
diff changeset
   177
        if renderer is None:
4260
832b578839cb [forms] fix implementation of backward compat method form_render
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4257
diff changeset
   178
            renderer = self.default_renderer()
3953
19aefd78f61b [forms] deprecate form_render(**kwargs) in favor of render(formvalues=None, rendervalues=None, renderer=None)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3923
diff changeset
   179
        return renderer.render(self, values)
19aefd78f61b [forms] deprecate form_render(**kwargs) in favor of render(formvalues=None, rendervalues=None, renderer=None)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3923
diff changeset
   180
4236
9260403bfe0b move autoform's field_by_name implementation on base EntityFieldsForm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4224
diff changeset
   181
_AFF = uicfg.autoform_field
9260403bfe0b move autoform's field_by_name implementation on base EntityFieldsForm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4224
diff changeset
   182
_AFF_KWARGS = uicfg.autoform_field_kwargs
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   183
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   184
class EntityFieldsForm(FieldsForm):
3377
dd9d292b6a6d use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3369
diff changeset
   185
    __regid__ = 'base'
2657
de974465d381 [appobject] kill VObject class, move base selector classes to appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   186
    __select__ = (match_kwargs('entity')
de974465d381 [appobject] kill VObject class, move base selector classes to appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   187
                  | (one_line_rset() & non_final_entity()))
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   188
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   189
    internal_fields = FieldsForm.internal_fields + ('__type', 'eid', '__maineid')
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   190
    domid = 'entityForm'
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   191
4257
0a9b38a492e1 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   192
    @iclassmethod
0a9b38a492e1 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   193
    def field_by_name(cls_or_self, name, role=None, eschema=None):
0a9b38a492e1 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   194
        """return field with the given name and role. If field is not explicitly
0a9b38a492e1 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   195
        defined for the form but `eclass` is specified, guess_field will be
0a9b38a492e1 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   196
        called.
0a9b38a492e1 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   197
        """
0a9b38a492e1 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   198
        try:
0a9b38a492e1 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   199
            return super(EntityFieldsForm, cls_or_self).field_by_name(name, role)
0a9b38a492e1 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   200
        except form.FieldNotFound:
0a9b38a492e1 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   201
            if eschema is None or role is None or not name in eschema.schema:
0a9b38a492e1 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   202
                raise
0a9b38a492e1 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   203
            rschema = eschema.schema.rschema(name)
0a9b38a492e1 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   204
            # XXX use a sample target type. Document this.
0a9b38a492e1 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   205
            tschemas = rschema.targets(eschema, role)
0a9b38a492e1 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   206
            fieldcls = _AFF.etype_get(eschema, rschema, role, tschemas[0])
0a9b38a492e1 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   207
            kwargs = _AFF_KWARGS.etype_get(eschema, rschema, role, tschemas[0])
0a9b38a492e1 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   208
            if kwargs is None:
0a9b38a492e1 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   209
                kwargs = {}
0a9b38a492e1 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   210
            if fieldcls:
0a9b38a492e1 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   211
                if not isinstance(fieldcls, type):
0a9b38a492e1 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   212
                    return fieldcls # already and instance
0a9b38a492e1 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   213
                return fieldcls(name=name, role=role, eidparam=True, **kwargs)
0a9b38a492e1 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   214
            field = guess_field(eschema, rschema, role, eidparam=True, **kwargs)
0a9b38a492e1 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   215
            if field is None:
0a9b38a492e1 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   216
                raise
0a9b38a492e1 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   217
            return field
0a9b38a492e1 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   218
0a9b38a492e1 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   219
    def __init__(self, _cw, rset=None, row=None, col=None, **kwargs):
0a9b38a492e1 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   220
        try:
4206
cebdf8ee5ad7 [forms] edited_entity must be set before calling session_key()
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4134
diff changeset
   221
            self.edited_entity = kwargs.pop('entity')
4257
0a9b38a492e1 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   222
        except KeyError:
4252
6c4f109c2b03 backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4248 4212
diff changeset
   223
            self.edited_entity = rset.complete_entity(row or 0, col or 0)
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   224
        msg = kwargs.pop('submitmsg', None)
4257
0a9b38a492e1 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   225
        super(EntityFieldsForm, self).__init__(_cw, rset, row, col, **kwargs)
4658
25de2eb0432b [form] add a new ignore_req_params attribute on field controlling value's retreival
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4583
diff changeset
   226
        self.add_hidden('__type', self.edited_entity.__regid__, eidparam=True,
25de2eb0432b [form] add a new ignore_req_params attribute on field controlling value's retreival
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4583
diff changeset
   227
                        ignore_req_params=True)
25de2eb0432b [form] add a new ignore_req_params attribute on field controlling value's retreival
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4583
diff changeset
   228
        self.add_hidden('eid', self.edited_entity.eid, ignore_req_params=True)
2080
3ea388b5b9d8 oops, mainform default to True
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2050
diff changeset
   229
        if kwargs.get('mainform', True): # mainform default to true in parent
4164
119a374c5eb4 form_add_hidden -> add_hidden
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4162
diff changeset
   230
            self.add_hidden(u'__maineid', self.edited_entity.eid)
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   231
            # If we need to directly attach the new object to another one
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   232
            if self._cw.list_form_param('__linkto'):
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   233
                for linkto in self._cw.list_form_param('__linkto'):
4164
119a374c5eb4 form_add_hidden -> add_hidden
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4162
diff changeset
   234
                    self.add_hidden('__linkto', linkto)
2050
ce184fdb1e56 fix submit message handling in entity form
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2049
diff changeset
   235
                if msg:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   236
                    msg = '%s %s' % (msg, self._cw._('and linked'))
2050
ce184fdb1e56 fix submit message handling in entity form
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2049
diff changeset
   237
                else:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   238
                    msg = self._cw._('entity linked')
2050
ce184fdb1e56 fix submit message handling in entity form
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2049
diff changeset
   239
        if msg:
4164
119a374c5eb4 form_add_hidden -> add_hidden
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4162
diff changeset
   240
            self.add_hidden('__message', msg)
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   241
3922
69020a7c234a refactor session_key (__errorurl) to handle cases where the form is generated throuhg an ajax call: in case of an entity form, return the entity's absolute url. Also allow to force session key value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3880
diff changeset
   242
    def session_key(self):
69020a7c234a refactor session_key (__errorurl) to handle cases where the form is generated throuhg an ajax call: in case of an entity form, return the entity's absolute url. Also allow to force session key value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3880
diff changeset
   243
        """return the key that may be used to store / retreive data about a
69020a7c234a refactor session_key (__errorurl) to handle cases where the form is generated throuhg an ajax call: in case of an entity form, return the entity's absolute url. Also allow to force session key value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3880
diff changeset
   244
        previous post which failed because of a validation error
69020a7c234a refactor session_key (__errorurl) to handle cases where the form is generated throuhg an ajax call: in case of an entity form, return the entity's absolute url. Also allow to force session key value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3880
diff changeset
   245
        """
4133
24ffe983abfc force_session_key default to None in base form class...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3953
diff changeset
   246
        if self.force_session_key is not None:
3922
69020a7c234a refactor session_key (__errorurl) to handle cases where the form is generated throuhg an ajax call: in case of an entity form, return the entity's absolute url. Also allow to force session key value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3880
diff changeset
   247
            return self.force_session_key
4133
24ffe983abfc force_session_key default to None in base form class...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3953
diff changeset
   248
        # XXX if this is a json request, suppose we should redirect to the
24ffe983abfc force_session_key default to None in base form class...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3953
diff changeset
   249
        # entity primary view
4183
b5aa030bb2f9 use ._cw instead of .req (reintroduced by merge of stable)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4181
diff changeset
   250
        if self._cw.json_request and self.edited_entity.has_eid():
4133
24ffe983abfc force_session_key default to None in base form class...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3953
diff changeset
   251
            return '%s#%s' % (self.edited_entity.absolute_url(), self.domid)
4183
b5aa030bb2f9 use ._cw instead of .req (reintroduced by merge of stable)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4181
diff changeset
   252
        return '%s#%s' % (self._cw.url(), self.domid)
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   253
4159
6b2b20c73d59 refactor form field value handling, to get a nicer api and an easier algorithm to get field's value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4156
diff changeset
   254
    def build_context(self, formvalues=None):
4248
d375643eea43 don't add another _cw_edited_field hidden when build_context is called twice (may occurs with inlined relation forms)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4236
diff changeset
   255
        if self.formvalues is not None:
d375643eea43 don't add another _cw_edited_field hidden when build_context is called twice (may occurs with inlined relation forms)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4236
diff changeset
   256
            return # already built
4159
6b2b20c73d59 refactor form field value handling, to get a nicer api and an easier algorithm to get field's value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4156
diff changeset
   257
        super(EntityFieldsForm, self).build_context(formvalues)
6b2b20c73d59 refactor form field value handling, to get a nicer api and an easier algorithm to get field's value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4156
diff changeset
   258
        edited = set()
6b2b20c73d59 refactor form field value handling, to get a nicer api and an easier algorithm to get field's value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4156
diff changeset
   259
        for field in self.fields:
6b2b20c73d59 refactor form field value handling, to get a nicer api and an easier algorithm to get field's value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4156
diff changeset
   260
            if field.eidparam:
6b2b20c73d59 refactor form field value handling, to get a nicer api and an easier algorithm to get field's value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4156
diff changeset
   261
                edited.add(field.role_name())
6b2b20c73d59 refactor form field value handling, to get a nicer api and an easier algorithm to get field's value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4156
diff changeset
   262
        self.add_hidden('_cw_edited_fields', u','.join(edited),
6b2b20c73d59 refactor form field value handling, to get a nicer api and an easier algorithm to get field's value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4156
diff changeset
   263
                        eidparam=True)
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   264
4164
119a374c5eb4 form_add_hidden -> add_hidden
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4162
diff changeset
   265
    def default_renderer(self):
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   266
        return self._cw.vreg['formrenderers'].select(
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   267
            self.form_renderer_id, self._cw, rset=self.cw_rset, row=self.cw_row,
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   268
            col=self.cw_col, entity=self.edited_entity)
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   269
4583
356f08325072 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4284
diff changeset
   270
    def should_display_add_new_relation_link(self, rschema, existant, card):
356f08325072 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4284
diff changeset
   271
        return False
356f08325072 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4284
diff changeset
   272
4167
73e649a7797d fix render (formerly form_render) prototype
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4164
diff changeset
   273
    # controller side method (eg POST reception handling)
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   274
4159
6b2b20c73d59 refactor form field value handling, to get a nicer api and an easier algorithm to get field's value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4156
diff changeset
   275
    def actual_eid(self, eid):
6b2b20c73d59 refactor form field value handling, to get a nicer api and an easier algorithm to get field's value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4156
diff changeset
   276
        # should be either an int (existant entity) or a variable (to be
6b2b20c73d59 refactor form field value handling, to get a nicer api and an easier algorithm to get field's value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4156
diff changeset
   277
        # created entity)
6b2b20c73d59 refactor form field value handling, to get a nicer api and an easier algorithm to get field's value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4156
diff changeset
   278
        assert eid or eid == 0, repr(eid) # 0 is a valid eid
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   279
        try:
4159
6b2b20c73d59 refactor form field value handling, to get a nicer api and an easier algorithm to get field's value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4156
diff changeset
   280
            return typed_eid(eid)
6b2b20c73d59 refactor form field value handling, to get a nicer api and an easier algorithm to get field's value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4156
diff changeset
   281
        except ValueError:
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   282
            try:
4159
6b2b20c73d59 refactor form field value handling, to get a nicer api and an easier algorithm to get field's value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4156
diff changeset
   283
                return self._cw.data['eidmap'][eid]
6b2b20c73d59 refactor form field value handling, to get a nicer api and an easier algorithm to get field's value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4156
diff changeset
   284
            except KeyError:
6b2b20c73d59 refactor form field value handling, to get a nicer api and an easier algorithm to get field's value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4156
diff changeset
   285
                self._cw.data['eidmap'][eid] = None
6b2b20c73d59 refactor form field value handling, to get a nicer api and an easier algorithm to get field's value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4156
diff changeset
   286
                return None
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   287
3476
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3467
diff changeset
   288
    def editable_relations(self):
2089
b1070848726b backport default branch fix 4ec37d33657e (EntityFieldsForm methods implementation)
Florent <florent@secondweb.fr>
parents: 2080
diff changeset
   289
        return ()
b1070848726b backport default branch fix 4ec37d33657e (EntityFieldsForm methods implementation)
Florent <florent@secondweb.fr>
parents: 2080
diff changeset
   290
4161
4273f5094651 refactor vocabulary handling to avoid having to define methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4159
diff changeset
   291
    @deprecated('[3.6] use cw.web.formfields.relvoc_unrelated function')
4273f5094651 refactor vocabulary handling to avoid having to define methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4159
diff changeset
   292
    def subject_relation_vocabulary(self, rtype, limit=None):
4273f5094651 refactor vocabulary handling to avoid having to define methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4159
diff changeset
   293
        """defaut vocabulary method for the given relation, looking for
4273f5094651 refactor vocabulary handling to avoid having to define methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4159
diff changeset
   294
        relation's object entities (i.e. self is the subject)
4273f5094651 refactor vocabulary handling to avoid having to define methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4159
diff changeset
   295
        """
4273f5094651 refactor vocabulary handling to avoid having to define methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4159
diff changeset
   296
        return relvoc_unrelated(self.edited_entity, rtype, 'subject', limit=None)
4273f5094651 refactor vocabulary handling to avoid having to define methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4159
diff changeset
   297
4273f5094651 refactor vocabulary handling to avoid having to define methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4159
diff changeset
   298
    @deprecated('[3.6] use cw.web.formfields.relvoc_unrelated function')
4273f5094651 refactor vocabulary handling to avoid having to define methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4159
diff changeset
   299
    def object_relation_vocabulary(self, rtype, limit=None):
4273f5094651 refactor vocabulary handling to avoid having to define methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4159
diff changeset
   300
        return relvoc_unrelated(self.edited_entity, rtype, 'object', limit=None)
4273f5094651 refactor vocabulary handling to avoid having to define methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4159
diff changeset
   301
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   302
3510
bf746bf4a394 rename form_build_context to build_context, and call it from form, not renderer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3354
diff changeset
   303
class CompositeFormMixIn(object):
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2657
diff changeset
   304
    """form composed of sub-forms"""
3377
dd9d292b6a6d use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3369
diff changeset
   305
    __regid__ = 'composite'
3467
a6405235aac6 [tests] make unittest_views_editforms pass again
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3451
diff changeset
   306
    form_renderer_id = __regid__
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   307
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   308
    def __init__(self, *args, **kwargs):
3510
bf746bf4a394 rename form_build_context to build_context, and call it from form, not renderer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3354
diff changeset
   309
        super(CompositeFormMixIn, self).__init__(*args, **kwargs)
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   310
        self.forms = []
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   311
3513
c002f6488631 [form] replace is_subform by parent_form, carrying more information at the same cost
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3512
diff changeset
   312
    def add_subform(self, subform):
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   313
        """mark given form as a subform and append it"""
3513
c002f6488631 [form] replace is_subform by parent_form, carrying more information at the same cost
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3512
diff changeset
   314
        subform.parent_form = self
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   315
        self.forms.append(subform)
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2657
diff changeset
   316
4159
6b2b20c73d59 refactor form field value handling, to get a nicer api and an easier algorithm to get field's value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4156
diff changeset
   317
    def build_context(self, formvalues=None):
6b2b20c73d59 refactor form field value handling, to get a nicer api and an easier algorithm to get field's value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4156
diff changeset
   318
        super(CompositeFormMixIn, self).build_context(formvalues)
3510
bf746bf4a394 rename form_build_context to build_context, and call it from form, not renderer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3354
diff changeset
   319
        for form in self.forms:
4159
6b2b20c73d59 refactor form field value handling, to get a nicer api and an easier algorithm to get field's value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4156
diff changeset
   320
            form.build_context(formvalues)
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2657
diff changeset
   321
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2657
diff changeset
   322
3510
bf746bf4a394 rename form_build_context to build_context, and call it from form, not renderer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3354
diff changeset
   323
class CompositeForm(CompositeFormMixIn, FieldsForm):
bf746bf4a394 rename form_build_context to build_context, and call it from form, not renderer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3354
diff changeset
   324
    pass
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2657
diff changeset
   325
3510
bf746bf4a394 rename form_build_context to build_context, and call it from form, not renderer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3354
diff changeset
   326
class CompositeEntityForm(CompositeFormMixIn, EntityFieldsForm):
bf746bf4a394 rename form_build_context to build_context, and call it from form, not renderer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3354
diff changeset
   327
    pass # XXX why is this class necessary?