cubicweb/web/form.py
author Denis Laxalde <denis.laxalde@logilab.fr>
Fri, 22 Mar 2019 17:42:36 +0100
changeset 12542 85194bd49119
parent 12503 b01dd0ef43aa
child 12567 26744ad37953
permissions -rw-r--r--
Drop more deprecated code This follows up on changeset a8c1ea390400, in which code deprecated using logilab.common.deprecation got dropped. Now we also drop code deprecated using stdlib's warn(<msg>, DeprecationWarning). Notice that, as a consequence of dropping old/new etypes aliases in cubicweb/schema.py, we drop the import ETYPE_NAME_MAP (no longer needed); but since other modules imported that name from cubicweb.schema, we need to update the import statement to use "cubicweb" directly.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
7432
cab99ccdb774 [ui messages, xss] Start migration towards use of _msgid instead of __message (prone to XSS injection) closes #1698245
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 6109
diff changeset
     1
# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5369
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: 5369
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: 5369
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: 5369
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: 5369
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: 5369
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: 5369
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: 5369
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: 5369
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: 5369
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: 5369
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: 5369
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: 5369
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: 5369
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: 5369
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
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: 5547
diff changeset
    18
"""abstract form classes for CubicWeb web client"""
11767
432f87a63057 flake8 and all
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
    19
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    20
10688
fa29f3628a1b [py3k] use six.add_metaclass
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10662
diff changeset
    21
from six import add_metaclass
fa29f3628a1b [py3k] use six.add_metaclass
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10662
diff changeset
    22
3512
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
    23
from logilab.common.decorators import iclassmethod
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
    24
2656
a93ae0f6c0ad R [base classes] only AppObject remaning, no more AppRsetObject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2005
diff changeset
    25
from cubicweb.appobject import AppObject
1133
8a409ea0c9ec more linting
sylvain.thenault@logilab.fr
parents: 1132
diff changeset
    26
from cubicweb.view import NOINDEX, NOFOLLOW
5369
68c33344581c fix NameError
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5368
diff changeset
    27
from cubicweb.web import httpcache, formfields, controller, formwidgets as fwdgs
1097
611bacbbe001 pylint fixes, media definitions on form as well
sylvain.thenault@logilab.fr
parents: 1082
diff changeset
    28
1318
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
    29
class FormViewMixIn(object):
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
    30
    """abstract form view mix-in"""
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    31
    category = 'form'
1995
ec95eaa2b711 turn renderers into appobjects
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    32
    http_cache_manager = httpcache.NoHTTPCacheManager
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    33
    add_to_breadcrumbs = False
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
    34
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    35
    def html_headers(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    36
        """return a list of html headers (eg something to be inserted between
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    37
        <head> and </head> of the returned page
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    38
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    39
        by default forms are neither indexed nor followed
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    40
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    41
        return [NOINDEX, NOFOLLOW]
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
    42
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    43
    def linkable(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    44
        """override since forms are usually linked by an action,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    45
        so we don't want them to be listed by appli.possible_views
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    46
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    47
        return False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    48
1318
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
    49
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    50
###############################################################################
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    51
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    52
class metafieldsform(type):
1406
133476216f4a define self.fields before it is used ...
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1400
diff changeset
    53
    """metaclass for FieldsForm to retrieve fields defined as class attributes
133476216f4a define self.fields before it is used ...
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1400
diff changeset
    54
    and put them into a single ordered list: '_fields_'.
1393
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
    55
    """
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    56
    def __new__(mcs, name, bases, classdict):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    57
        allfields = []
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    58
        for base in bases:
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    59
            if hasattr(base, '_fields_'):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    60
                allfields += base._fields_
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    61
        clsfields = (item for item in classdict.items()
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
    62
                     if isinstance(item[1], formfields.Field))
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
    63
        for fieldname, field in sorted(clsfields, key=lambda x: x[1].creation_rank):
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    64
            if not field.name:
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
    65
                field.set_name(fieldname)
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    66
            allfields.append(field)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    67
        classdict['_fields_'] = allfields
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    68
        return super(metafieldsform, mcs).__new__(mcs, name, bases, classdict)
1270
53f35db66f88 raise specific exception
sylvain.thenault@logilab.fr
parents: 1265
diff changeset
    69
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
    70
1270
53f35db66f88 raise specific exception
sylvain.thenault@logilab.fr
parents: 1265
diff changeset
    71
class FieldNotFound(Exception):
53f35db66f88 raise specific exception
sylvain.thenault@logilab.fr
parents: 1265
diff changeset
    72
    """raised by field_by_name when a field with the given name has not been
53f35db66f88 raise specific exception
sylvain.thenault@logilab.fr
parents: 1265
diff changeset
    73
    found
53f35db66f88 raise specific exception
sylvain.thenault@logilab.fr
parents: 1265
diff changeset
    74
    """
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
    75
10688
fa29f3628a1b [py3k] use six.add_metaclass
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10662
diff changeset
    76
@add_metaclass(metafieldsform)
3475
9c07e6c48e35 [forms] drop FormMixIn deprecated in 3.2
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3451
diff changeset
    77
class Form(AppObject):
1047
21d4d5e6aa45 make forms selectable (appobject)
sylvain.thenault@logilab.fr
parents: 1032
diff changeset
    78
    __registry__ = 'forms'
3512
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
    79
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
    80
    parent_form = None
3998
94cc7cad3d2d backport stable into default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3524 3925
diff changeset
    81
    force_session_key = None
4668
9f82f81bf13d [form] fix #719285, due to multiple calls to restore_previous_post, by proper refactorings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    82
    domid = 'form'
9f82f81bf13d [form] fix #719285, due to multiple calls to restore_previous_post, by proper refactorings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    83
    copy_nav_params = False
7584
e1881933f366 [form, controller] closes #1787233: form should provide a method to process posted content
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7432
diff changeset
    84
    control_fields = set( ('__form_id', '__errorurl', '__domid',
10080
bc7c3b0f439b [web] stop accepting the magic __message form parameter
Julien Cristau <julien.cristau@logilab.fr>
parents: 8511
diff changeset
    85
                           '__redirectpath', '_cwmsgid',
7584
e1881933f366 [form, controller] closes #1787233: form should provide a method to process posted content
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7432
diff changeset
    86
                           ) )
3512
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
    87
4668
9f82f81bf13d [form] fix #719285, due to multiple calls to restore_previous_post, by proper refactorings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    88
    def __init__(self, req, rset=None, row=None, col=None,
9f82f81bf13d [form] fix #719285, due to multiple calls to restore_previous_post, by proper refactorings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    89
                 submitmsg=None, mainform=True, **kwargs):
8511
f15e90b914cd [web form] refactor Form.__init__ so that extra kwargs are set earlier in the process. Closes #2443040
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8337
diff changeset
    90
        # process kwargs first so we can properly pass them to Form and match
f15e90b914cd [web form] refactor Form.__init__ so that extra kwargs are set earlier in the process. Closes #2443040
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8337
diff changeset
    91
        # order expectation (ie cw_extra_kwargs populated almost first)
f15e90b914cd [web form] refactor Form.__init__ so that extra kwargs are set earlier in the process. Closes #2443040
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8337
diff changeset
    92
        hiddens, extrakw = self._process_kwargs(kwargs)
f15e90b914cd [web form] refactor Form.__init__ so that extra kwargs are set earlier in the process. Closes #2443040
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8337
diff changeset
    93
        # now call ancestor init
f15e90b914cd [web form] refactor Form.__init__ so that extra kwargs are set earlier in the process. Closes #2443040
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8337
diff changeset
    94
        super(Form, self).__init__(req, rset=rset, row=row, col=col, **extrakw)
f15e90b914cd [web form] refactor Form.__init__ so that extra kwargs are set earlier in the process. Closes #2443040
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8337
diff changeset
    95
        # then continue with further specific initialization
4668
9f82f81bf13d [form] fix #719285, due to multiple calls to restore_previous_post, by proper refactorings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    96
        self.fields = list(self.__class__._fields_)
8511
f15e90b914cd [web form] refactor Form.__init__ so that extra kwargs are set earlier in the process. Closes #2443040
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8337
diff changeset
    97
        for key, val in hiddens:
f15e90b914cd [web form] refactor Form.__init__ so that extra kwargs are set earlier in the process. Closes #2443040
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8337
diff changeset
    98
            self.add_hidden(key, val)
4683
c375d50eaad3 [form] only set __form_id for the main form, not for sub-forms. Should fix regression introduced by 4668:9f82f81bf13d
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4668
diff changeset
    99
        if mainform:
8337
b5275e739a44 [form] add a new property telling if the form is being generated or posted. Closes #2262340
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   100
            formid = kwargs.pop('formvid', self.__regid__)
b5275e739a44 [form] add a new property telling if the form is being generated or posted. Closes #2262340
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   101
            self.add_hidden(u'__form_id', formid)
b5275e739a44 [form] add a new property telling if the form is being generated or posted. Closes #2262340
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   102
            self._posting = self._cw.form.get('__form_id') == formid
4668
9f82f81bf13d [form] fix #719285, due to multiple calls to restore_previous_post, by proper refactorings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   103
        if mainform:
9f82f81bf13d [form] fix #719285, due to multiple calls to restore_previous_post, by proper refactorings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   104
            self.add_hidden(u'__errorurl', self.session_key())
9f82f81bf13d [form] fix #719285, due to multiple calls to restore_previous_post, by proper refactorings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   105
            self.add_hidden(u'__domid', self.domid)
9f82f81bf13d [form] fix #719285, due to multiple calls to restore_previous_post, by proper refactorings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   106
            self.restore_previous_post(self.session_key())
9f82f81bf13d [form] fix #719285, due to multiple calls to restore_previous_post, by proper refactorings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   107
        # XXX why do we need two different variables (mainform and copy_nav_params ?)
9f82f81bf13d [form] fix #719285, due to multiple calls to restore_previous_post, by proper refactorings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   108
        if self.copy_nav_params:
9f82f81bf13d [form] fix #719285, due to multiple calls to restore_previous_post, by proper refactorings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   109
            for param in controller.NAV_FORM_PARAMETERS:
9f82f81bf13d [form] fix #719285, due to multiple calls to restore_previous_post, by proper refactorings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   110
                if not param in kwargs:
9f82f81bf13d [form] fix #719285, due to multiple calls to restore_previous_post, by proper refactorings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   111
                    value = req.form.get(param)
9f82f81bf13d [form] fix #719285, due to multiple calls to restore_previous_post, by proper refactorings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   112
                    if value:
9f82f81bf13d [form] fix #719285, due to multiple calls to restore_previous_post, by proper refactorings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   113
                        self.add_hidden(param, value)
9f82f81bf13d [form] fix #719285, due to multiple calls to restore_previous_post, by proper refactorings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   114
        if submitmsg is not None:
7432
cab99ccdb774 [ui messages, xss] Start migration towards use of _msgid instead of __message (prone to XSS injection) closes #1698245
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 6109
diff changeset
   115
            self.set_message(submitmsg)
cab99ccdb774 [ui messages, xss] Start migration towards use of _msgid instead of __message (prone to XSS injection) closes #1698245
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 6109
diff changeset
   116
8511
f15e90b914cd [web form] refactor Form.__init__ so that extra kwargs are set earlier in the process. Closes #2443040
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8337
diff changeset
   117
    def _process_kwargs(self, kwargs):
f15e90b914cd [web form] refactor Form.__init__ so that extra kwargs are set earlier in the process. Closes #2443040
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8337
diff changeset
   118
        hiddens = []
f15e90b914cd [web form] refactor Form.__init__ so that extra kwargs are set earlier in the process. Closes #2443040
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8337
diff changeset
   119
        extrakw = {}
f15e90b914cd [web form] refactor Form.__init__ so that extra kwargs are set earlier in the process. Closes #2443040
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8337
diff changeset
   120
        # search for navigation parameters and customization of existing
f15e90b914cd [web form] refactor Form.__init__ so that extra kwargs are set earlier in the process. Closes #2443040
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8337
diff changeset
   121
        # attributes; remaining stuff goes in extrakwargs
10662
10942ed172de [py3k] dict.iteritems → dict.items
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10080
diff changeset
   122
        for key, val in kwargs.items():
8511
f15e90b914cd [web form] refactor Form.__init__ so that extra kwargs are set earlier in the process. Closes #2443040
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8337
diff changeset
   123
            if key in controller.NAV_FORM_PARAMETERS:
f15e90b914cd [web form] refactor Form.__init__ so that extra kwargs are set earlier in the process. Closes #2443040
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8337
diff changeset
   124
                hiddens.append( (key, val) )
f15e90b914cd [web form] refactor Form.__init__ so that extra kwargs are set earlier in the process. Closes #2443040
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8337
diff changeset
   125
            elif key == 'redirect_path':
f15e90b914cd [web form] refactor Form.__init__ so that extra kwargs are set earlier in the process. Closes #2443040
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8337
diff changeset
   126
                hiddens.append( (u'__redirectpath', val) )
f15e90b914cd [web form] refactor Form.__init__ so that extra kwargs are set earlier in the process. Closes #2443040
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8337
diff changeset
   127
            elif hasattr(self.__class__, key) and not key[0] == '_':
f15e90b914cd [web form] refactor Form.__init__ so that extra kwargs are set earlier in the process. Closes #2443040
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8337
diff changeset
   128
                setattr(self, key, val)
f15e90b914cd [web form] refactor Form.__init__ so that extra kwargs are set earlier in the process. Closes #2443040
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8337
diff changeset
   129
            else:
f15e90b914cd [web form] refactor Form.__init__ so that extra kwargs are set earlier in the process. Closes #2443040
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8337
diff changeset
   130
                extrakw[key] = val
f15e90b914cd [web form] refactor Form.__init__ so that extra kwargs are set earlier in the process. Closes #2443040
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8337
diff changeset
   131
        return hiddens, extrakw
f15e90b914cd [web form] refactor Form.__init__ so that extra kwargs are set earlier in the process. Closes #2443040
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8337
diff changeset
   132
7432
cab99ccdb774 [ui messages, xss] Start migration towards use of _msgid instead of __message (prone to XSS injection) closes #1698245
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 6109
diff changeset
   133
    def set_message(self, submitmsg):
cab99ccdb774 [ui messages, xss] Start migration towards use of _msgid instead of __message (prone to XSS injection) closes #1698245
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 6109
diff changeset
   134
        """sets a submitmsg if exists, using _cwmsgid mechanism """
cab99ccdb774 [ui messages, xss] Start migration towards use of _msgid instead of __message (prone to XSS injection) closes #1698245
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 6109
diff changeset
   135
        cwmsgid = self._cw.set_redirect_message(submitmsg)
cab99ccdb774 [ui messages, xss] Start migration towards use of _msgid instead of __message (prone to XSS injection) closes #1698245
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 6109
diff changeset
   136
        self.add_hidden(u'_cwmsgid', cwmsgid)
3512
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   137
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   138
    @property
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   139
    def root_form(self):
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   140
        """return the root form"""
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   141
        if self.parent_form is None:
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   142
            return self
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   143
        return self.parent_form.root_form
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   144
3998
94cc7cad3d2d backport stable into default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3524 3925
diff changeset
   145
    @property
4224
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   146
    def form_valerror(self):
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   147
        """the validation error exception if any"""
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   148
        if self.parent_form is None:
5358
d4d294610ee7 [forms] no crash if restore_previous_post has not be called, has in report bug form in management.py for instance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5223
diff changeset
   149
            # unset if restore_previous_post has not be called
d4d294610ee7 [forms] no crash if restore_previous_post has not be called, has in report bug form in management.py for instance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5223
diff changeset
   150
            return getattr(self, '_form_valerror', None)
4224
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   151
        return self.parent_form.form_valerror
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   152
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   153
    @property
3998
94cc7cad3d2d backport stable into default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3524 3925
diff changeset
   154
    def form_previous_values(self):
4224
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   155
        """previously posted values (on validation error)"""
3998
94cc7cad3d2d backport stable into default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3524 3925
diff changeset
   156
        if self.parent_form is None:
5358
d4d294610ee7 [forms] no crash if restore_previous_post has not be called, has in report bug form in management.py for instance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5223
diff changeset
   157
            # unset if restore_previous_post has not be called
d4d294610ee7 [forms] no crash if restore_previous_post has not be called, has in report bug form in management.py for instance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5223
diff changeset
   158
            return getattr(self, '_form_previous_values', {})
3998
94cc7cad3d2d backport stable into default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3524 3925
diff changeset
   159
        return self.parent_form.form_previous_values
94cc7cad3d2d backport stable into default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3524 3925
diff changeset
   160
8337
b5275e739a44 [form] add a new property telling if the form is being generated or posted. Closes #2262340
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   161
    @property
b5275e739a44 [form] add a new property telling if the form is being generated or posted. Closes #2262340
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   162
    def posting(self):
b5275e739a44 [form] add a new property telling if the form is being generated or posted. Closes #2262340
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   163
        """return True if the form is being posted, False if it is being
b5275e739a44 [form] add a new property telling if the form is being generated or posted. Closes #2262340
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   164
        generated.
b5275e739a44 [form] add a new property telling if the form is being generated or posted. Closes #2262340
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   165
        """
b5275e739a44 [form] add a new property telling if the form is being generated or posted. Closes #2262340
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   166
        # XXX check behaviour on regeneration after error
b5275e739a44 [form] add a new property telling if the form is being generated or posted. Closes #2262340
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   167
        if self.parent_form is None:
b5275e739a44 [form] add a new property telling if the form is being generated or posted. Closes #2262340
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   168
            return self._posting
b5275e739a44 [form] add a new property telling if the form is being generated or posted. Closes #2262340
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   169
        return self.parent_form.posting
b5275e739a44 [form] add a new property telling if the form is being generated or posted. Closes #2262340
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   170
3512
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   171
    @iclassmethod
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   172
    def _fieldsattr(cls_or_self):
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   173
        if isinstance(cls_or_self, type):
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   174
            fields = cls_or_self._fields_
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   175
        else:
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   176
            fields = cls_or_self.fields
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   177
        return fields
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   178
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   179
    @iclassmethod
4165
eb9acad29407 proper field's role handling: may be 'subject' / 'object' *in case
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4082
diff changeset
   180
    def field_by_name(cls_or_self, name, role=None):
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   181
        """Return field with the given name and role.
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   182
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   183
        Raise :exc:`FieldNotFound` if the field can't be found.
3512
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   184
        """
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   185
        for field in cls_or_self._fieldsattr():
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   186
            if field.name == name and field.role == role:
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   187
                return field
4235
49eb7e87d36d specify name *and* role when raising FieldNotFound helps debugging
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4224
diff changeset
   188
        raise FieldNotFound(name, role)
3512
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   189
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   190
    @iclassmethod
4165
eb9acad29407 proper field's role handling: may be 'subject' / 'object' *in case
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4082
diff changeset
   191
    def fields_by_name(cls_or_self, name, role=None):
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   192
        """Return a list of fields with the given name and role."""
3512
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   193
        return [field for field in cls_or_self._fieldsattr()
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   194
                if field.name == name and field.role == role]
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   195
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   196
    @iclassmethod
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   197
    def remove_field(cls_or_self, field):
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   198
        """Remove the given field."""
3512
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   199
        cls_or_self._fieldsattr().remove(field)
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   200
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   201
    @iclassmethod
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   202
    def append_field(cls_or_self, field):
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   203
        """Append the given field."""
3512
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   204
        cls_or_self._fieldsattr().append(field)
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   205
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   206
    @iclassmethod
5367
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4779
diff changeset
   207
    def insert_field_before(cls_or_self, field, name, role=None):
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4779
diff changeset
   208
        """Insert the given field before the field of given name and role."""
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4779
diff changeset
   209
        bfield = cls_or_self.field_by_name(name, role)
3512
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   210
        fields = cls_or_self._fieldsattr()
5367
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4779
diff changeset
   211
        fields.insert(fields.index(bfield), field)
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4779
diff changeset
   212
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4779
diff changeset
   213
    @iclassmethod
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4779
diff changeset
   214
    def insert_field_after(cls_or_self, field, name, role=None):
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4779
diff changeset
   215
        """Insert the given field after the field of given name and role."""
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4779
diff changeset
   216
        afield = cls_or_self.field_by_name(name, role)
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4779
diff changeset
   217
        fields = cls_or_self._fieldsattr()
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4779
diff changeset
   218
        fields.insert(fields.index(afield)+1, field)
3512
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   219
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   220
    @iclassmethod
5367
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4779
diff changeset
   221
    def add_hidden(cls_or_self, name, value=None, **kwargs):
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4779
diff changeset
   222
        """Append an hidden field to the form. `name`, `value` and extra keyword
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4779
diff changeset
   223
        arguments will be given to the field constructor. The inserted field is
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4779
diff changeset
   224
        returned.
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4779
diff changeset
   225
        """
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4779
diff changeset
   226
        kwargs.setdefault('ignore_req_params', True)
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4779
diff changeset
   227
        kwargs.setdefault('widget', fwdgs.HiddenInput)
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4779
diff changeset
   228
        field = formfields.StringField(name=name, value=value, **kwargs)
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4779
diff changeset
   229
        if 'id' in kwargs:
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4779
diff changeset
   230
            # by default, hidden input don't set id attribute. If one is
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4779
diff changeset
   231
            # explicitly specified, ensure it will be set
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4779
diff changeset
   232
            field.widget.setdomid = True
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4779
diff changeset
   233
        cls_or_self.append_field(field)
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4779
diff changeset
   234
        return field
3524
a3431f4e2f40 backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3475 3512
diff changeset
   235
1525
cc2e2cbd7019 include dom id of the form in __errorurl in case there are multiple forms in a page
sylvain.thenault@logilab.fr
parents: 1519
diff changeset
   236
    def session_key(self):
cc2e2cbd7019 include dom id of the form in __errorurl in case there are multiple forms in a page
sylvain.thenault@logilab.fr
parents: 1519
diff changeset
   237
        """return the key that may be used to store / retreive data about a
cc2e2cbd7019 include dom id of the form in __errorurl in case there are multiple forms in a page
sylvain.thenault@logilab.fr
parents: 1519
diff changeset
   238
        previous post which failed because of a validation error
cc2e2cbd7019 include dom id of the form in __errorurl in case there are multiple forms in a page
sylvain.thenault@logilab.fr
parents: 1519
diff changeset
   239
        """
3998
94cc7cad3d2d backport stable into default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3524 3925
diff changeset
   240
        if self.force_session_key is None:
4082
c7117119e215 3.6 api update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4023
diff changeset
   241
            return '%s#%s' % (self._cw.url(), self.domid)
3998
94cc7cad3d2d backport stable into default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3524 3925
diff changeset
   242
        return self.force_session_key
1525
cc2e2cbd7019 include dom id of the form in __errorurl in case there are multiple forms in a page
sylvain.thenault@logilab.fr
parents: 1519
diff changeset
   243
cc2e2cbd7019 include dom id of the form in __errorurl in case there are multiple forms in a page
sylvain.thenault@logilab.fr
parents: 1519
diff changeset
   244
    def restore_previous_post(self, sessionkey):
1318
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
   245
        # get validation session data which may have been previously set.
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
   246
        # deleting validation errors here breaks form reloading (errors are
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
   247
        # no more available), they have to be deleted by application's publish
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
   248
        # method on successful commit
5223
6abd6e3599f4 #773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4779
diff changeset
   249
        forminfo = self._cw.session.data.pop(sessionkey, None)
1318
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
   250
        if forminfo:
4224
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   251
            self._form_previous_values = forminfo['values']
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   252
            self._form_valerror = forminfo['error']
6109
47d9c0e0f7b7 integrate Celso's work on translation file: proper/complete spanish translation, fixed some typos in french translation, occured -> occurred fix in various places
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5588
diff changeset
   253
            # if some validation error occurred on entity creation, we have to
1318
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
   254
            # get the original variable name from its attributed eid
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: 1701
diff changeset
   255
            foreid = self.form_valerror.entity
1318
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
   256
            for var, eid in forminfo['eidmap'].items():
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
   257
                if foreid == eid:
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: 1701
diff changeset
   258
                    self.form_valerror.eid = var
1318
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
   259
                    break
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
   260
            else:
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: 1701
diff changeset
   261
                self.form_valerror.eid = foreid
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: 1701
diff changeset
   262
        else:
3998
94cc7cad3d2d backport stable into default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3524 3925
diff changeset
   263
            self._form_previous_values = {}
94cc7cad3d2d backport stable into default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3524 3925
diff changeset
   264
            self._form_valerror = None
4224
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   265
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   266
    def field_error(self, field):
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   267
        """return field's error if specified in current validation exception"""
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   268
        if self.form_valerror:
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   269
            if field.eidparam and self.edited_entity.eid != self.form_valerror.eid:
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   270
                return None
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   271
            try:
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   272
                return self.form_valerror.errors.pop(field.role_name())
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   273
            except KeyError:
12542
85194bd49119 Drop more deprecated code
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12503
diff changeset
   274
                pass
4224
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   275
        return None
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   276
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   277
    def remaining_errors(self):
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   278
        return sorted(self.form_valerror.errors.items())