cubicweb/web/form.py
author Denis Laxalde <denis.laxalde@logilab.fr>
Thu, 14 Mar 2019 14:43:18 +0100
changeset 12503 b01dd0ef43aa
parent 11767 432f87a63057
child 12542 85194bd49119
permissions -rw-r--r--
Drop most deprecated code in cubicweb.web This includes both Python and JavaScript code. Most code has been deprecated since a very long time (versions 3.1x mostly, more than 5 years ago, and a few things until 3.24). There are still a few deprecated things, most of which are actually used within cubicweb (or in cubes we depend on for tests). I don't know what to do with these... Removed a couple of unused imports along the way. Changelog entry will come in a later changeset.
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
4224
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
    21
from warnings import warn
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
    22
10688
fa29f3628a1b [py3k] use six.add_metaclass
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10662
diff changeset
    23
from six import add_metaclass
fa29f3628a1b [py3k] use six.add_metaclass
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10662
diff changeset
    24
3512
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
    25
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
    26
2656
a93ae0f6c0ad R [base classes] only AppObject remaning, no more AppRsetObject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2005
diff changeset
    27
from cubicweb.appobject import AppObject
1133
8a409ea0c9ec more linting
sylvain.thenault@logilab.fr
parents: 1132
diff changeset
    28
from cubicweb.view import NOINDEX, NOFOLLOW
5369
68c33344581c fix NameError
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5368
diff changeset
    29
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
    30
1318
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
    31
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
    32
    """abstract form view mix-in"""
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    33
    category = 'form'
1995
ec95eaa2b711 turn renderers into appobjects
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    34
    http_cache_manager = httpcache.NoHTTPCacheManager
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    35
    add_to_breadcrumbs = False
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
    36
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    37
    def html_headers(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    38
        """return a list of html headers (eg something to be inserted between
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    39
        <head> and </head> of the returned page
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
        by default forms are neither indexed nor followed
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    42
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    43
        return [NOINDEX, NOFOLLOW]
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
    44
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    45
    def linkable(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    46
        """override since forms are usually linked by an action,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    47
        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
    48
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    49
        return False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    50
1318
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
    51
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    52
###############################################################################
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    53
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    54
class metafieldsform(type):
1406
133476216f4a define self.fields before it is used ...
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1400
diff changeset
    55
    """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
    56
    and put them into a single ordered list: '_fields_'.
1393
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
    57
    """
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    58
    def __new__(mcs, name, bases, classdict):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    59
        allfields = []
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    60
        for base in bases:
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    61
            if hasattr(base, '_fields_'):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    62
                allfields += base._fields_
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    63
        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
    64
                     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
    65
        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
    66
            if not field.name:
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
    67
                field.set_name(fieldname)
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    68
            allfields.append(field)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    69
        classdict['_fields_'] = allfields
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    70
        return super(metafieldsform, mcs).__new__(mcs, name, bases, classdict)
1270
53f35db66f88 raise specific exception
sylvain.thenault@logilab.fr
parents: 1265
diff changeset
    71
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
    72
1270
53f35db66f88 raise specific exception
sylvain.thenault@logilab.fr
parents: 1265
diff changeset
    73
class FieldNotFound(Exception):
53f35db66f88 raise specific exception
sylvain.thenault@logilab.fr
parents: 1265
diff changeset
    74
    """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
    75
    found
53f35db66f88 raise specific exception
sylvain.thenault@logilab.fr
parents: 1265
diff changeset
    76
    """
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
    77
10688
fa29f3628a1b [py3k] use six.add_metaclass
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10662
diff changeset
    78
@add_metaclass(metafieldsform)
3475
9c07e6c48e35 [forms] drop FormMixIn deprecated in 3.2
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3451
diff changeset
    79
class Form(AppObject):
1047
21d4d5e6aa45 make forms selectable (appobject)
sylvain.thenault@logilab.fr
parents: 1032
diff changeset
    80
    __registry__ = 'forms'
3512
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
    81
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
    82
    parent_form = None
3998
94cc7cad3d2d backport stable into default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3524 3925
diff changeset
    83
    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
    84
    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
    85
    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
    86
    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
    87
                           '__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
    88
                           ) )
3512
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
    89
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
    90
    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
    91
                 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
    92
        # 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
    93
        # 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
    94
        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
    95
        # 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
    96
        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
    97
        # 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
    98
        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
    99
        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
   100
            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
   101
        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
   102
            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
   103
            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
   104
            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
   105
        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
   106
            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
   107
            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
   108
            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
   109
        # 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
   110
        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
   111
            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
   112
                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
   113
                    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
   114
                    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
   115
                        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
   116
        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
   117
            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
   118
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
   119
    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
   120
        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
   121
        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
   122
        # 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
   123
        # attributes; remaining stuff goes in extrakwargs
10662
10942ed172de [py3k] dict.iteritems → dict.items
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10080
diff changeset
   124
        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
   125
            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
   126
                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
   127
            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
   128
                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
   129
            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
   130
                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
   131
            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
   132
                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
   133
        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
   134
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
   135
    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
   136
        """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
   137
        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
   138
        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
   139
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   140
    @property
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   141
    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
   142
        """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
   143
        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
   144
            return self
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   145
        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
   146
3998
94cc7cad3d2d backport stable into default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3524 3925
diff changeset
   147
    @property
4224
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   148
    def form_valerror(self):
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   149
        """the validation error exception if any"""
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   150
        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
   151
            # 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
   152
            return getattr(self, '_form_valerror', None)
4224
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   153
        return self.parent_form.form_valerror
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   154
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   155
    @property
3998
94cc7cad3d2d backport stable into default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3524 3925
diff changeset
   156
    def form_previous_values(self):
4224
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   157
        """previously posted values (on validation error)"""
3998
94cc7cad3d2d backport stable into default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3524 3925
diff changeset
   158
        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
   159
            # 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
   160
            return getattr(self, '_form_previous_values', {})
3998
94cc7cad3d2d backport stable into default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3524 3925
diff changeset
   161
        return self.parent_form.form_previous_values
94cc7cad3d2d backport stable into default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3524 3925
diff changeset
   162
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
   163
    @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
   164
    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
   165
        """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
   166
        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
   167
        """
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
        # 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
   169
        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
   170
            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
   171
        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
   172
3512
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   173
    @iclassmethod
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   174
    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
   175
        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
   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
        else:
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   178
            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
   179
        return fields
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   180
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   181
    @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
   182
    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
   183
        """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
   184
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   185
        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
   186
        """
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   187
        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
   188
            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
   189
                return field
4235
49eb7e87d36d specify name *and* role when raising FieldNotFound helps debugging
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4224
diff changeset
   190
        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
   191
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   192
    @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
   193
    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
   194
        """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
   195
        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
   196
                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
   197
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   198
    @iclassmethod
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   199
    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
   200
        """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
   201
        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
   202
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   203
    @iclassmethod
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   204
    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
   205
        """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
   206
        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
   207
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   208
    @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
   209
    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
   210
        """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
   211
        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
   212
        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
   213
        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
   214
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4779
diff changeset
   215
    @iclassmethod
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4779
diff changeset
   216
    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
   217
        """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
   218
        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
   219
        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
   220
        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
   221
2ceaa4e40348 move low-level form handling to base form class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   222
    @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
   223
    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
   224
        """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
   225
        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
   226
        returned.
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4779
diff changeset
   227
        """
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4779
diff changeset
   228
        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
   229
        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
   230
        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
   231
        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
   232
            # 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
   233
            # 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
   234
            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
   235
        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
   236
        return field
3524
a3431f4e2f40 backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3475 3512
diff changeset
   237
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
   238
    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
   239
        """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
   240
        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
   241
        """
3998
94cc7cad3d2d backport stable into default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3524 3925
diff changeset
   242
        if self.force_session_key is None:
4082
c7117119e215 3.6 api update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4023
diff changeset
   243
            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
   244
        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
   245
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
   246
    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
   247
        # 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
   248
        # 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
   249
        # 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
   250
        # 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
   251
        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
   252
        if forminfo:
4224
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   253
            self._form_previous_values = forminfo['values']
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   254
            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
   255
            # 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
   256
            # 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
   257
            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
   258
            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
   259
                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
   260
                    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
   261
                    break
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
   262
            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
   263
                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
   264
        else:
3998
94cc7cad3d2d backport stable into default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3524 3925
diff changeset
   265
            self._form_previous_values = {}
94cc7cad3d2d backport stable into default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3524 3925
diff changeset
   266
            self._form_valerror = None
4224
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   267
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   268
    def field_error(self, field):
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   269
        """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
   270
        if self.form_valerror:
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   271
            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
   272
                return None
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   273
            try:
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   274
                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
   275
            except KeyError:
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   276
                if field.role and field.name in self.form_valerror:
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   277
                    warn('%s: errors key of attribute/relation should be suffixed by "-<role>"'
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   278
                         % self.form_valerror.__class__, DeprecationWarning)
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   279
                    return self.form_valerror.errors.pop(field.name)
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   280
        return None
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   281
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   282
    def remaining_errors(self):
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4165
diff changeset
   283
        return sorted(self.form_valerror.errors.items())