author | Sylvain Thénault <sylvain.thenault@logilab.fr> |
Fri, 25 Sep 2009 11:30:59 +0200 | |
changeset 3475 | 9c07e6c48e35 |
parent 3451 | 6b46d73823f5 |
child 3524 | a3431f4e2f40 |
permissions | -rw-r--r-- |
0 | 1 |
"""abstract form classes for CubicWeb web client |
2 |
||
3 |
:organization: Logilab |
|
1977
606923dff11b
big bunch of copyright / docstring update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
1962
diff
changeset
|
4 |
:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2. |
0 | 5 |
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr |
1977
606923dff11b
big bunch of copyright / docstring update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
1962
diff
changeset
|
6 |
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses |
0 | 7 |
""" |
8 |
__docformat__ = "restructuredtext en" |
|
9 |
||
2656
a93ae0f6c0ad
R [base classes] only AppObject remaning, no more AppRsetObject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2005
diff
changeset
|
10 |
from cubicweb.appobject import AppObject |
1133 | 11 |
from cubicweb.view import NOINDEX, NOFOLLOW |
1097
611bacbbe001
pylint fixes, media definitions on form as well
sylvain.thenault@logilab.fr
parents:
1082
diff
changeset
|
12 |
from cubicweb.common import tags |
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
|
13 |
from cubicweb.web import stdmsgs, httpcache, formfields |
1995
ec95eaa2b711
turn renderers into appobjects
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
14 |
|
1097
611bacbbe001
pylint fixes, media definitions on form as well
sylvain.thenault@logilab.fr
parents:
1082
diff
changeset
|
15 |
|
1318
50e1a778c5ee
new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents:
1315
diff
changeset
|
16 |
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
|
17 |
"""abstract form view mix-in""" |
0 | 18 |
category = 'form' |
1995
ec95eaa2b711
turn renderers into appobjects
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
19 |
http_cache_manager = httpcache.NoHTTPCacheManager |
0 | 20 |
add_to_breadcrumbs = False |
1437 | 21 |
|
0 | 22 |
def html_headers(self): |
23 |
"""return a list of html headers (eg something to be inserted between |
|
24 |
<head> and </head> of the returned page |
|
25 |
||
26 |
by default forms are neither indexed nor followed |
|
27 |
""" |
|
28 |
return [NOINDEX, NOFOLLOW] |
|
1437 | 29 |
|
0 | 30 |
def linkable(self): |
31 |
"""override since forms are usually linked by an action, |
|
32 |
so we don't want them to be listed by appli.possible_views |
|
33 |
""" |
|
34 |
return False |
|
35 |
||
1318
50e1a778c5ee
new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents:
1315
diff
changeset
|
36 |
|
3475
9c07e6c48e35
[forms] drop FormMixIn deprecated in 3.2
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3451
diff
changeset
|
37 |
class metafieldsform(type): |
9c07e6c48e35
[forms] drop FormMixIn deprecated in 3.2
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3451
diff
changeset
|
38 |
"""metaclass for FieldsForm to retrieve fields defined as class attributes |
9c07e6c48e35
[forms] drop FormMixIn deprecated in 3.2
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3451
diff
changeset
|
39 |
and put them into a single ordered list: '_fields_'. |
1318
50e1a778c5ee
new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents:
1315
diff
changeset
|
40 |
""" |
3475
9c07e6c48e35
[forms] drop FormMixIn deprecated in 3.2
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3451
diff
changeset
|
41 |
def __new__(mcs, name, bases, classdict): |
9c07e6c48e35
[forms] drop FormMixIn deprecated in 3.2
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3451
diff
changeset
|
42 |
allfields = [] |
9c07e6c48e35
[forms] drop FormMixIn deprecated in 3.2
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3451
diff
changeset
|
43 |
for base in bases: |
9c07e6c48e35
[forms] drop FormMixIn deprecated in 3.2
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3451
diff
changeset
|
44 |
if hasattr(base, '_fields_'): |
9c07e6c48e35
[forms] drop FormMixIn deprecated in 3.2
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3451
diff
changeset
|
45 |
allfields += base._fields_ |
9c07e6c48e35
[forms] drop FormMixIn deprecated in 3.2
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3451
diff
changeset
|
46 |
clsfields = (item for item in classdict.items() |
9c07e6c48e35
[forms] drop FormMixIn deprecated in 3.2
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3451
diff
changeset
|
47 |
if isinstance(item[1], formfields.Field)) |
9c07e6c48e35
[forms] drop FormMixIn deprecated in 3.2
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3451
diff
changeset
|
48 |
for fieldname, field in sorted(clsfields, key=lambda x: x[1].creation_rank): |
9c07e6c48e35
[forms] drop FormMixIn deprecated in 3.2
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3451
diff
changeset
|
49 |
if not field.name: |
9c07e6c48e35
[forms] drop FormMixIn deprecated in 3.2
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3451
diff
changeset
|
50 |
field.set_name(fieldname) |
9c07e6c48e35
[forms] drop FormMixIn deprecated in 3.2
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3451
diff
changeset
|
51 |
allfields.append(field) |
9c07e6c48e35
[forms] drop FormMixIn deprecated in 3.2
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3451
diff
changeset
|
52 |
classdict['_fields_'] = allfields |
9c07e6c48e35
[forms] drop FormMixIn deprecated in 3.2
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3451
diff
changeset
|
53 |
return super(metafieldsform, mcs).__new__(mcs, name, bases, classdict) |
9c07e6c48e35
[forms] drop FormMixIn deprecated in 3.2
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3451
diff
changeset
|
54 |
|
9c07e6c48e35
[forms] drop FormMixIn deprecated in 3.2
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3451
diff
changeset
|
55 |
|
9c07e6c48e35
[forms] drop FormMixIn deprecated in 3.2
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3451
diff
changeset
|
56 |
class FieldNotFound(Exception): |
9c07e6c48e35
[forms] drop FormMixIn deprecated in 3.2
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3451
diff
changeset
|
57 |
"""raised by field_by_name when a field with the given name has not been |
9c07e6c48e35
[forms] drop FormMixIn deprecated in 3.2
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3451
diff
changeset
|
58 |
found |
9c07e6c48e35
[forms] drop FormMixIn deprecated in 3.2
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3451
diff
changeset
|
59 |
""" |
9c07e6c48e35
[forms] drop FormMixIn deprecated in 3.2
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3451
diff
changeset
|
60 |
|
9c07e6c48e35
[forms] drop FormMixIn deprecated in 3.2
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3451
diff
changeset
|
61 |
class Form(AppObject): |
9c07e6c48e35
[forms] drop FormMixIn deprecated in 3.2
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3451
diff
changeset
|
62 |
__metaclass__ = metafieldsform |
9c07e6c48e35
[forms] drop FormMixIn deprecated in 3.2
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3451
diff
changeset
|
63 |
__registry__ = 'forms' |
9c07e6c48e35
[forms] drop FormMixIn deprecated in 3.2
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3451
diff
changeset
|
64 |
|
9c07e6c48e35
[forms] drop FormMixIn deprecated in 3.2
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3451
diff
changeset
|
65 |
def __init__(self, req, rset, **kwargs): |
9c07e6c48e35
[forms] drop FormMixIn deprecated in 3.2
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3451
diff
changeset
|
66 |
super(Form, self).__init__(req, rset=rset, **kwargs) |
9c07e6c48e35
[forms] drop FormMixIn deprecated in 3.2
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3451
diff
changeset
|
67 |
self.restore_previous_post(self.session_key()) |
1318
50e1a778c5ee
new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents:
1315
diff
changeset
|
68 |
|
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
|
69 |
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
|
70 |
"""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
|
71 |
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
|
72 |
""" |
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3023
diff
changeset
|
73 |
return '%s#%s' % (self._cw.url(), self.domid) |
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
|
74 |
|
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
|
75 |
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
|
76 |
# 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
|
77 |
# 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
|
78 |
# 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
|
79 |
# method on successful commit |
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3023
diff
changeset
|
80 |
forminfo = self._cw.get_session_data(sessionkey, pop=True) |
1318
50e1a778c5ee
new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents:
1315
diff
changeset
|
81 |
if forminfo: |
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
|
82 |
# XXX remove req.data assigment once cw.web.widget is killed |
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3023
diff
changeset
|
83 |
self._cw.data['formvalues'] = self.form_previous_values = forminfo['values'] |
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3023
diff
changeset
|
84 |
self._cw.data['formerrors'] = self.form_valerror = forminfo['errors'] |
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3023
diff
changeset
|
85 |
self._cw.data['displayederrors'] = self.form_displayed_errors = set() |
1318
50e1a778c5ee
new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents:
1315
diff
changeset
|
86 |
# if some validation error occured on entity creation, we have to |
50e1a778c5ee
new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents:
1315
diff
changeset
|
87 |
# 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
|
88 |
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
|
89 |
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
|
90 |
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
|
91 |
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
|
92 |
break |
50e1a778c5ee
new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents:
1315
diff
changeset
|
93 |
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
|
94 |
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
|
95 |
else: |
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
|
96 |
self.form_previous_values = {} |
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
|
97 |
self.form_valerror = None |