web/form.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Thu, 28 May 2009 20:06:45 +0200
changeset 1995 ec95eaa2b711
parent 1977 606923dff11b
child 2005 e8032965f37a
permissions -rw-r--r--
turn renderers into appobjects
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     1
"""abstract form classes for CubicWeb web client
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     2
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     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
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     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
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     7
"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     8
__docformat__ = "restructuredtext en"
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     9
848
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
    10
from warnings import warn
1016
26387b836099 use datetime instead of mx.DateTime
sylvain.thenault@logilab.fr
parents: 1013
diff changeset
    11
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    12
from logilab.common.compat import any
1058
c27be37daef8 field_by_name method (on class or instance)
sylvain.thenault@logilab.fr
parents: 1056
diff changeset
    13
from logilab.common.decorators import iclassmethod
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    14
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
    15
from cubicweb.appobject import AppRsetObject
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
    16
from cubicweb.selectors import yes, non_final_entity, match_kwargs, one_line_rset
1133
8a409ea0c9ec more linting
sylvain.thenault@logilab.fr
parents: 1132
diff changeset
    17
from cubicweb.view import NOINDEX, NOFOLLOW
1097
611bacbbe001 pylint fixes, media definitions on form as well
sylvain.thenault@logilab.fr
parents: 1082
diff changeset
    18
from cubicweb.common import tags
611bacbbe001 pylint fixes, media definitions on form as well
sylvain.thenault@logilab.fr
parents: 1082
diff changeset
    19
from cubicweb.web import INTERNAL_FIELD_VALUE, eid_param, stdmsgs
1995
ec95eaa2b711 turn renderers into appobjects
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    20
from cubicweb.web import formwidgets as fwdgs, httpcache
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
    21
from cubicweb.web.controller import NAV_FORM_PARAMETERS
1097
611bacbbe001 pylint fixes, media definitions on form as well
sylvain.thenault@logilab.fr
parents: 1082
diff changeset
    22
from cubicweb.web.formfields import (Field, StringField, RelationField,
611bacbbe001 pylint fixes, media definitions on form as well
sylvain.thenault@logilab.fr
parents: 1082
diff changeset
    23
                                     HiddenInitialValueField)
1995
ec95eaa2b711 turn renderers into appobjects
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    24
1097
611bacbbe001 pylint fixes, media definitions on form as well
sylvain.thenault@logilab.fr
parents: 1082
diff changeset
    25
1318
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
    26
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
    27
    """abstract form view mix-in"""
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    28
    category = 'form'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    29
    controller = 'edit'
1995
ec95eaa2b711 turn renderers into appobjects
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    30
    http_cache_manager = httpcache.NoHTTPCacheManager
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    31
    add_to_breadcrumbs = False
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
    32
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    33
    def html_headers(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    34
        """return a list of html headers (eg something to be inserted between
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    35
        <head> and </head> of the returned page
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    36
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    37
        by default forms are neither indexed nor followed
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
        return [NOINDEX, NOFOLLOW]
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
    40
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    41
    def linkable(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    42
        """override since forms are usually linked by an action,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    43
        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
    44
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    45
        return False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    46
1318
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
    47
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
    48
# XXX should disappear
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
class FormMixIn(object):
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
    50
    """abstract form mix-in
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
    51
    XXX: you should inherit from this FIRST (obscure pb with super call)
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
    52
    """
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
    53
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
    54
    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
    55
        """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
    56
        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
    57
        """
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
    58
        return '%s#%s' % (self.req.url(), self.domid)
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
    59
1318
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
    60
    def __init__(self, req, rset, **kwargs):
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
    61
        super(FormMixIn, self).__init__(req, rset, **kwargs)
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
    62
        self.restore_previous_post(self.session_key())
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
    63
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
    64
    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
    65
        # 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
    66
        # 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
    67
        # 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
    68
        # method on successful commit
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
        forminfo = self.req.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
    70
        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
    71
            # XXX remove req.data assigment once cw.web.widget is killed
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
    72
            self.req.data['formvalues'] = self.form_previous_values = forminfo['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
    73
            self.req.data['formerrors'] = self.form_valerror = forminfo['errors']
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
    74
            self.req.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
    75
            # 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
    76
            # 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
    77
            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
    78
            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
    79
                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
    80
                    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
    81
                    break
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
    82
            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
    83
                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
    84
        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
    85
            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
    86
            self.form_valerror = None
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
    87
1519
5cfc5cc1dd20 fix retreival of previously submitted error for entity forms
sylvain.thenault@logilab.fr
parents: 1451
diff changeset
    88
    # XXX deprecated with new form system. Should disappear
5cfc5cc1dd20 fix retreival of previously submitted error for entity forms
sylvain.thenault@logilab.fr
parents: 1451
diff changeset
    89
5cfc5cc1dd20 fix retreival of previously submitted error for entity forms
sylvain.thenault@logilab.fr
parents: 1451
diff changeset
    90
    domid = 'entityForm'
5cfc5cc1dd20 fix retreival of previously submitted error for entity forms
sylvain.thenault@logilab.fr
parents: 1451
diff changeset
    91
    category = 'form'
5cfc5cc1dd20 fix retreival of previously submitted error for entity forms
sylvain.thenault@logilab.fr
parents: 1451
diff changeset
    92
    controller = 'edit'
1995
ec95eaa2b711 turn renderers into appobjects
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    93
    http_cache_manager = httpcache.NoHTTPCacheManager
1519
5cfc5cc1dd20 fix retreival of previously submitted error for entity forms
sylvain.thenault@logilab.fr
parents: 1451
diff changeset
    94
    add_to_breadcrumbs = False
5cfc5cc1dd20 fix retreival of previously submitted error for entity forms
sylvain.thenault@logilab.fr
parents: 1451
diff changeset
    95
1318
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
    96
    def html_headers(self):
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
    97
        """return a list of html headers (eg something to be inserted between
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
    98
        <head> and </head> of the returned page
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
    99
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
   100
        by default forms are neither indexed nor followed
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
   101
        """
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
   102
        return [NOINDEX, NOFOLLOW]
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
   103
1318
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
   104
    def linkable(self):
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
   105
        """override since forms are usually linked by an action,
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
   106
        so we don't want them to be listed by appli.possible_views
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
   107
        """
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
   108
        return False
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
   109
50e1a778c5ee new FormViewMixIn class, cleanup FormMixIn (to remove once cubes doesn't use it anymore)
sylvain.thenault@logilab.fr
parents: 1315
diff changeset
   110
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   111
    def button(self, label, klass='validateButton', tabindex=None, **kwargs):
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   112
        if tabindex is None:
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   113
            tabindex = self.req.next_tabindex()
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   114
        return tags.input(value=label, klass=klass, **kwargs)
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   115
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   116
    def action_button(self, label, onclick=None, __action=None, **kwargs):
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   117
        if onclick is None:
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   118
            onclick = "postForm('__action_%s', \'%s\', \'%s\')" % (
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   119
                __action, label, self.domid)
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   120
        return self.button(label, onclick=onclick, **kwargs)
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   121
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   122
    def button_ok(self, label=None, type='submit', name='defaultsubmit',
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   123
                  **kwargs):
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   124
        label = self.req._(label or stdmsgs.BUTTON_OK).capitalize()
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   125
        return self.button(label, name=name, type=type, **kwargs)
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
   126
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   127
    def button_apply(self, label=None, type='button', **kwargs):
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   128
        label = self.req._(label or stdmsgs.BUTTON_APPLY).capitalize()
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   129
        return self.action_button(label, __action='apply', type=type, **kwargs)
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   130
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   131
    def button_delete(self, label=None, type='button', **kwargs):
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   132
        label = self.req._(label or stdmsgs.BUTTON_DELETE).capitalize()
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   133
        return self.action_button(label, __action='delete', type=type, **kwargs)
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
   134
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   135
    def button_cancel(self, label=None, type='button', **kwargs):
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   136
        label = self.req._(label or stdmsgs.BUTTON_CANCEL).capitalize()
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   137
        return self.action_button(label, __action='cancel', type=type, **kwargs)
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
   138
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   139
    def button_reset(self, label=None, type='reset', name='__action_cancel',
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   140
                     **kwargs):
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   141
        label = self.req._(label or stdmsgs.BUTTON_CANCEL).capitalize()
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   142
        return self.button(label, type=type, **kwargs)
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   143
1305
395ef7f2b95b cleanup, remove some unnecessary (sometime buggy) stuff
sylvain.thenault@logilab.fr
parents: 1304
diff changeset
   144
    def need_multipart(self, entity, categories=('primary', 'secondary')):
395ef7f2b95b cleanup, remove some unnecessary (sometime buggy) stuff
sylvain.thenault@logilab.fr
parents: 1304
diff changeset
   145
        """return a boolean indicating if form's enctype should be multipart
395ef7f2b95b cleanup, remove some unnecessary (sometime buggy) stuff
sylvain.thenault@logilab.fr
parents: 1304
diff changeset
   146
        """
395ef7f2b95b cleanup, remove some unnecessary (sometime buggy) stuff
sylvain.thenault@logilab.fr
parents: 1304
diff changeset
   147
        for rschema, _, x in entity.relations_by_category(categories):
395ef7f2b95b cleanup, remove some unnecessary (sometime buggy) stuff
sylvain.thenault@logilab.fr
parents: 1304
diff changeset
   148
            if entity.get_widget(rschema, x).need_multipart:
395ef7f2b95b cleanup, remove some unnecessary (sometime buggy) stuff
sylvain.thenault@logilab.fr
parents: 1304
diff changeset
   149
                return True
395ef7f2b95b cleanup, remove some unnecessary (sometime buggy) stuff
sylvain.thenault@logilab.fr
parents: 1304
diff changeset
   150
        # let's find if any of our inlined entities needs multipart
395ef7f2b95b cleanup, remove some unnecessary (sometime buggy) stuff
sylvain.thenault@logilab.fr
parents: 1304
diff changeset
   151
        for rschema, targettypes, x in entity.relations_by_category('inlineview'):
395ef7f2b95b cleanup, remove some unnecessary (sometime buggy) stuff
sylvain.thenault@logilab.fr
parents: 1304
diff changeset
   152
            assert len(targettypes) == 1, \
395ef7f2b95b cleanup, remove some unnecessary (sometime buggy) stuff
sylvain.thenault@logilab.fr
parents: 1304
diff changeset
   153
                   "I'm not able to deal with several targets and inlineview"
395ef7f2b95b cleanup, remove some unnecessary (sometime buggy) stuff
sylvain.thenault@logilab.fr
parents: 1304
diff changeset
   154
            ttype = targettypes[0]
395ef7f2b95b cleanup, remove some unnecessary (sometime buggy) stuff
sylvain.thenault@logilab.fr
parents: 1304
diff changeset
   155
            inlined_entity = self.vreg.etype_class(ttype)(self.req, None, None)
395ef7f2b95b cleanup, remove some unnecessary (sometime buggy) stuff
sylvain.thenault@logilab.fr
parents: 1304
diff changeset
   156
            for irschema, _, x in inlined_entity.relations_by_category(categories):
395ef7f2b95b cleanup, remove some unnecessary (sometime buggy) stuff
sylvain.thenault@logilab.fr
parents: 1304
diff changeset
   157
                if inlined_entity.get_widget(irschema, x).need_multipart:
395ef7f2b95b cleanup, remove some unnecessary (sometime buggy) stuff
sylvain.thenault@logilab.fr
parents: 1304
diff changeset
   158
                    return True
395ef7f2b95b cleanup, remove some unnecessary (sometime buggy) stuff
sylvain.thenault@logilab.fr
parents: 1304
diff changeset
   159
        return False
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
   160
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   161
    def error_message(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   162
        """return formatted error message
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   163
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   164
        This method should be called once inlined field errors has been consumed
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   165
        """
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
   166
        errex = self.req.data.get('formerrors') or self.form_valerror
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   167
        # get extra errors
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   168
        if errex is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   169
            errormsg = self.req._('please correct the following errors:')
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
   170
            displayed = self.req.data.get('displayederrors') or self.form_displayed_errors
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   171
            errors = sorted((field, err) for field, err in errex.errors.items()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   172
                            if not field in displayed)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   173
            if errors:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   174
                if len(errors) > 1:
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
   175
                    templstr = '<li>%s</li>\n'
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   176
                else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   177
                    templstr = '&nbsp;%s\n'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   178
                for field, err in errors:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   179
                    if field is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   180
                        errormsg += templstr % err
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   181
                    else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   182
                        errormsg += templstr % '%s: %s' % (self.req._(field), err)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   183
                if len(errors) > 1:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   184
                    errormsg = '<ul>%s</ul>' % errormsg
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   185
            return u'<div class="errorMessage">%s</div>' % errormsg
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   186
        return u''
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   187
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   188
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   189
###############################################################################
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   190
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   191
class metafieldsform(type):
1406
133476216f4a define self.fields before it is used ...
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1400
diff changeset
   192
    """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
   193
    and put them into a single ordered list: '_fields_'.
1393
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   194
    """
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   195
    def __new__(mcs, name, bases, classdict):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   196
        allfields = []
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   197
        for base in bases:
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   198
            if hasattr(base, '_fields_'):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   199
                allfields += base._fields_
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   200
        clsfields = (item for item in classdict.items()
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   201
                     if isinstance(item[1], Field))
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   202
        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
   203
            if not field.name:
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   204
                field.set_name(fieldname)
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   205
            allfields.append(field)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   206
        classdict['_fields_'] = allfields
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   207
        return super(metafieldsform, mcs).__new__(mcs, name, bases, classdict)
1270
53f35db66f88 raise specific exception
sylvain.thenault@logilab.fr
parents: 1265
diff changeset
   208
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
   209
1270
53f35db66f88 raise specific exception
sylvain.thenault@logilab.fr
parents: 1265
diff changeset
   210
class FieldNotFound(Exception):
53f35db66f88 raise specific exception
sylvain.thenault@logilab.fr
parents: 1265
diff changeset
   211
    """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
   212
    found
53f35db66f88 raise specific exception
sylvain.thenault@logilab.fr
parents: 1265
diff changeset
   213
    """
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
   214
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   215
class FieldsForm(FormMixIn, AppRsetObject):
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   216
    __metaclass__ = metafieldsform
1047
21d4d5e6aa45 make forms selectable (appobject)
sylvain.thenault@logilab.fr
parents: 1032
diff changeset
   217
    __registry__ = 'forms'
21d4d5e6aa45 make forms selectable (appobject)
sylvain.thenault@logilab.fr
parents: 1032
diff changeset
   218
    __select__ = yes()
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
   219
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   220
    is_subform = False
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
   221
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   222
    # attributes overrideable through __init__
1082
07c21784787b more rendering control
sylvain.thenault@logilab.fr
parents: 1081
diff changeset
   223
    internal_fields = ('__errorurl',) + NAV_FORM_PARAMETERS
1311
4cc6e2723dc7 move ajax.js to base form class
sylvain.thenault@logilab.fr
parents: 1308
diff changeset
   224
    needs_js = ('cubicweb.ajax.js', 'cubicweb.edition.js',)
1097
611bacbbe001 pylint fixes, media definitions on form as well
sylvain.thenault@logilab.fr
parents: 1082
diff changeset
   225
    needs_css = ('cubicweb.form.css',)
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   226
    domid = 'form'
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   227
    title = None
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   228
    action = None
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   229
    onsubmit = "return freezeFormButtons('%(domid)s');"
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   230
    cssclass = None
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   231
    cssstyle = None
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   232
    cwtarget = None
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   233
    redirect_path = None
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   234
    set_error_url = True
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   235
    copy_nav_params = False
1304
8975c8e520a9 refactor button handling
sylvain.thenault@logilab.fr
parents: 1289
diff changeset
   236
    form_buttons = None # form buttons (button widgets instances)
1995
ec95eaa2b711 turn renderers into appobjects
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   237
    form_renderer_id = 'default'
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
   238
1271
0a5257f5d723 handle __message in FieldsForm, not only in EntityFieldsForm
sylvain.thenault@logilab.fr
parents: 1270
diff changeset
   239
    def __init__(self, req, rset=None, row=None, col=None, submitmsg=None,
0a5257f5d723 handle __message in FieldsForm, not only in EntityFieldsForm
sylvain.thenault@logilab.fr
parents: 1270
diff changeset
   240
                 **kwargs):
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   241
        super(FieldsForm, self).__init__(req, rset, row=row, col=col)
1406
133476216f4a define self.fields before it is used ...
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1400
diff changeset
   242
        self.fields = list(self.__class__._fields_)
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   243
        for key, val in kwargs.items():
1400
5926626fb27b fix navigation parameters handling: those given in kwargs should always be there
sylvain.thenault@logilab.fr
parents: 1393
diff changeset
   244
            if key in NAV_FORM_PARAMETERS:
5926626fb27b fix navigation parameters handling: those given in kwargs should always be there
sylvain.thenault@logilab.fr
parents: 1393
diff changeset
   245
                self.form_add_hidden(key, val)
5926626fb27b fix navigation parameters handling: those given in kwargs should always be there
sylvain.thenault@logilab.fr
parents: 1393
diff changeset
   246
            else:
5926626fb27b fix navigation parameters handling: those given in kwargs should always be there
sylvain.thenault@logilab.fr
parents: 1393
diff changeset
   247
                assert hasattr(self.__class__, key) and not key[0] == '_', key
5926626fb27b fix navigation parameters handling: those given in kwargs should always be there
sylvain.thenault@logilab.fr
parents: 1393
diff changeset
   248
                setattr(self, key, val)
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   249
        if self.set_error_url:
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
   250
            self.form_add_hidden('__errorurl', self.session_key())
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   251
        if self.copy_nav_params:
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   252
            for param in NAV_FORM_PARAMETERS:
1400
5926626fb27b fix navigation parameters handling: those given in kwargs should always be there
sylvain.thenault@logilab.fr
parents: 1393
diff changeset
   253
                if not param in kwargs:
5926626fb27b fix navigation parameters handling: those given in kwargs should always be there
sylvain.thenault@logilab.fr
parents: 1393
diff changeset
   254
                    value = req.form.get(param)
5926626fb27b fix navigation parameters handling: those given in kwargs should always be there
sylvain.thenault@logilab.fr
parents: 1393
diff changeset
   255
                    if value:
5926626fb27b fix navigation parameters handling: those given in kwargs should always be there
sylvain.thenault@logilab.fr
parents: 1393
diff changeset
   256
                        self.form_add_hidden(param, value)
1271
0a5257f5d723 handle __message in FieldsForm, not only in EntityFieldsForm
sylvain.thenault@logilab.fr
parents: 1270
diff changeset
   257
        if submitmsg is not None:
0a5257f5d723 handle __message in FieldsForm, not only in EntityFieldsForm
sylvain.thenault@logilab.fr
parents: 1270
diff changeset
   258
            self.form_add_hidden('__message', submitmsg)
1053
e4d965b5ca37 cleanup
sylvain.thenault@logilab.fr
parents: 1050
diff changeset
   259
        self.context = None
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
   260
        if 'domid' in kwargs:# session key changed
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
   261
            self.restore_previous_post(self.session_key())
1058
c27be37daef8 field_by_name method (on class or instance)
sylvain.thenault@logilab.fr
parents: 1056
diff changeset
   262
c27be37daef8 field_by_name method (on class or instance)
sylvain.thenault@logilab.fr
parents: 1056
diff changeset
   263
    @iclassmethod
1935
a54a3b665361 add helpers to insert new fields in forms
Florent <florent@secondweb.fr>
parents: 1861
diff changeset
   264
    def _fieldsattr(cls_or_self):
1058
c27be37daef8 field_by_name method (on class or instance)
sylvain.thenault@logilab.fr
parents: 1056
diff changeset
   265
        if isinstance(cls_or_self, type):
c27be37daef8 field_by_name method (on class or instance)
sylvain.thenault@logilab.fr
parents: 1056
diff changeset
   266
            fields = cls_or_self._fields_
c27be37daef8 field_by_name method (on class or instance)
sylvain.thenault@logilab.fr
parents: 1056
diff changeset
   267
        else:
c27be37daef8 field_by_name method (on class or instance)
sylvain.thenault@logilab.fr
parents: 1056
diff changeset
   268
            fields = cls_or_self.fields
1935
a54a3b665361 add helpers to insert new fields in forms
Florent <florent@secondweb.fr>
parents: 1861
diff changeset
   269
        return fields
a54a3b665361 add helpers to insert new fields in forms
Florent <florent@secondweb.fr>
parents: 1861
diff changeset
   270
a54a3b665361 add helpers to insert new fields in forms
Florent <florent@secondweb.fr>
parents: 1861
diff changeset
   271
    @iclassmethod
1183
62afd820d3ae field_by_name now takes a "role" argument, override it in AutomaticForm to call guess field if necessary
sylvain.thenault@logilab.fr
parents: 1175
diff changeset
   272
    def field_by_name(cls_or_self, name, role='subject'):
1947
8696403e5324 test and fix __linkto handling (#343421)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1861
diff changeset
   273
        """return field with the given name and role.
8696403e5324 test and fix __linkto handling (#343421)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1861
diff changeset
   274
        Raise FieldNotFound if the field can't be found.
8696403e5324 test and fix __linkto handling (#343421)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1861
diff changeset
   275
        """
1935
a54a3b665361 add helpers to insert new fields in forms
Florent <florent@secondweb.fr>
parents: 1861
diff changeset
   276
        for field in cls_or_self._fieldsattr():
1183
62afd820d3ae field_by_name now takes a "role" argument, override it in AutomaticForm to call guess field if necessary
sylvain.thenault@logilab.fr
parents: 1175
diff changeset
   277
            if field.name == name and field.role == role:
1058
c27be37daef8 field_by_name method (on class or instance)
sylvain.thenault@logilab.fr
parents: 1056
diff changeset
   278
                return field
1270
53f35db66f88 raise specific exception
sylvain.thenault@logilab.fr
parents: 1265
diff changeset
   279
        raise FieldNotFound(name)
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
   280
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   281
    @iclassmethod
1947
8696403e5324 test and fix __linkto handling (#343421)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1861
diff changeset
   282
    def fields_by_name(cls_or_self, name, role='subject'):
8696403e5324 test and fix __linkto handling (#343421)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1861
diff changeset
   283
        """return a list of fields with the given name and role"""
1962
45af1e015683 backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1935 1947
diff changeset
   284
        return [field for field in cls_or_self._fieldsattr()
1947
8696403e5324 test and fix __linkto handling (#343421)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1861
diff changeset
   285
                if field.name == name and field.role == role]
8696403e5324 test and fix __linkto handling (#343421)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1861
diff changeset
   286
8696403e5324 test and fix __linkto handling (#343421)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1861
diff changeset
   287
    @iclassmethod
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   288
    def remove_field(cls_or_self, field):
1391
2a80b14fc548 more docstring
sylvain.thenault@logilab.fr
parents: 1386
diff changeset
   289
        """remove a field from form class or instance"""
1935
a54a3b665361 add helpers to insert new fields in forms
Florent <florent@secondweb.fr>
parents: 1861
diff changeset
   290
        cls_or_self._fieldsattr().remove(field)
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
   291
1272
e710fc46c6a0 new append_field method
sylvain.thenault@logilab.fr
parents: 1271
diff changeset
   292
    @iclassmethod
e710fc46c6a0 new append_field method
sylvain.thenault@logilab.fr
parents: 1271
diff changeset
   293
    def append_field(cls_or_self, field):
1391
2a80b14fc548 more docstring
sylvain.thenault@logilab.fr
parents: 1386
diff changeset
   294
        """append a field to form class or instance"""
1935
a54a3b665361 add helpers to insert new fields in forms
Florent <florent@secondweb.fr>
parents: 1861
diff changeset
   295
        cls_or_self._fieldsattr().append(field)
a54a3b665361 add helpers to insert new fields in forms
Florent <florent@secondweb.fr>
parents: 1861
diff changeset
   296
a54a3b665361 add helpers to insert new fields in forms
Florent <florent@secondweb.fr>
parents: 1861
diff changeset
   297
    @iclassmethod
a54a3b665361 add helpers to insert new fields in forms
Florent <florent@secondweb.fr>
parents: 1861
diff changeset
   298
    def insert_field_before(cls_or_self, new_field, name, role='subject'):
a54a3b665361 add helpers to insert new fields in forms
Florent <florent@secondweb.fr>
parents: 1861
diff changeset
   299
        field = cls_or_self.field_by_name(name, role)
a54a3b665361 add helpers to insert new fields in forms
Florent <florent@secondweb.fr>
parents: 1861
diff changeset
   300
        fields = cls_or_self._fieldsattr()
a54a3b665361 add helpers to insert new fields in forms
Florent <florent@secondweb.fr>
parents: 1861
diff changeset
   301
        fields.insert(fields.index(field), new_field)
a54a3b665361 add helpers to insert new fields in forms
Florent <florent@secondweb.fr>
parents: 1861
diff changeset
   302
a54a3b665361 add helpers to insert new fields in forms
Florent <florent@secondweb.fr>
parents: 1861
diff changeset
   303
    @iclassmethod
a54a3b665361 add helpers to insert new fields in forms
Florent <florent@secondweb.fr>
parents: 1861
diff changeset
   304
    def insert_field_after(cls_or_self, new_field, name, role='subject'):
a54a3b665361 add helpers to insert new fields in forms
Florent <florent@secondweb.fr>
parents: 1861
diff changeset
   305
        field = cls_or_self.field_by_name(name, role)
a54a3b665361 add helpers to insert new fields in forms
Florent <florent@secondweb.fr>
parents: 1861
diff changeset
   306
        fields = cls_or_self._fieldsattr()
a54a3b665361 add helpers to insert new fields in forms
Florent <florent@secondweb.fr>
parents: 1861
diff changeset
   307
        fields.insert(fields.index(field)+1, new_field)
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
   308
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   309
    @property
847
27c4ebe90d03 prefixed form methods to avoid potential conflicts with field names, button related method, a bit more serious renderer
sylvain.thenault@logilab.fr
parents: 844
diff changeset
   310
    def form_needs_multipart(self):
1391
2a80b14fc548 more docstring
sylvain.thenault@logilab.fr
parents: 1386
diff changeset
   311
        """true if the form needs enctype=multipart/form-data"""
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
   312
        return any(field.needs_multipart for field in self.fields)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   313
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   314
    def form_add_hidden(self, name, value=None, **kwargs):
1391
2a80b14fc548 more docstring
sylvain.thenault@logilab.fr
parents: 1386
diff changeset
   315
        """add an hidden field to the form"""
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   316
        field = StringField(name=name, widget=fwdgs.HiddenInput, initial=value,
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   317
                            **kwargs)
1338
9e038f84dbb3 setdomid should be true when id specified in kwargs
sylvain.thenault@logilab.fr
parents: 1326
diff changeset
   318
        if 'id' in kwargs:
9e038f84dbb3 setdomid should be true when id specified in kwargs
sylvain.thenault@logilab.fr
parents: 1326
diff changeset
   319
            # by default, hidden input don't set id attribute. If one is
9e038f84dbb3 setdomid should be true when id specified in kwargs
sylvain.thenault@logilab.fr
parents: 1326
diff changeset
   320
            # explicitly specified, ensure it will be set
9e038f84dbb3 setdomid should be true when id specified in kwargs
sylvain.thenault@logilab.fr
parents: 1326
diff changeset
   321
            field.widget.setdomid = True
1406
133476216f4a define self.fields before it is used ...
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1400
diff changeset
   322
        self.append_field(field)
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   323
        return field
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
   324
1097
611bacbbe001 pylint fixes, media definitions on form as well
sylvain.thenault@logilab.fr
parents: 1082
diff changeset
   325
    def add_media(self):
611bacbbe001 pylint fixes, media definitions on form as well
sylvain.thenault@logilab.fr
parents: 1082
diff changeset
   326
        """adds media (CSS & JS) required by this widget"""
611bacbbe001 pylint fixes, media definitions on form as well
sylvain.thenault@logilab.fr
parents: 1082
diff changeset
   327
        if self.needs_js:
611bacbbe001 pylint fixes, media definitions on form as well
sylvain.thenault@logilab.fr
parents: 1082
diff changeset
   328
            self.req.add_js(self.needs_js)
611bacbbe001 pylint fixes, media definitions on form as well
sylvain.thenault@logilab.fr
parents: 1082
diff changeset
   329
        if self.needs_css:
611bacbbe001 pylint fixes, media definitions on form as well
sylvain.thenault@logilab.fr
parents: 1082
diff changeset
   330
            self.req.add_css(self.needs_css)
611bacbbe001 pylint fixes, media definitions on form as well
sylvain.thenault@logilab.fr
parents: 1082
diff changeset
   331
847
27c4ebe90d03 prefixed form methods to avoid potential conflicts with field names, button related method, a bit more serious renderer
sylvain.thenault@logilab.fr
parents: 844
diff changeset
   332
    def form_render(self, **values):
1391
2a80b14fc548 more docstring
sylvain.thenault@logilab.fr
parents: 1386
diff changeset
   333
        """render this form, using the renderer given in args or the default
2a80b14fc548 more docstring
sylvain.thenault@logilab.fr
parents: 1386
diff changeset
   334
        FormRenderer()
2a80b14fc548 more docstring
sylvain.thenault@logilab.fr
parents: 1386
diff changeset
   335
        """
1995
ec95eaa2b711 turn renderers into appobjects
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   336
        renderer = values.pop('renderer', None)
ec95eaa2b711 turn renderers into appobjects
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   337
        if renderer is None:
ec95eaa2b711 turn renderers into appobjects
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   338
            renderer = self.form_default_renderer()
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   339
        return renderer.render(self, values)
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   340
1995
ec95eaa2b711 turn renderers into appobjects
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   341
    def form_default_renderer(self):
ec95eaa2b711 turn renderers into appobjects
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   342
        return self.vreg.select_object('formrenderers', self.form_renderer_id,
ec95eaa2b711 turn renderers into appobjects
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   343
                                       self.req, self.rset,
ec95eaa2b711 turn renderers into appobjects
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   344
                                       row=self.row, col=self.col)
ec95eaa2b711 turn renderers into appobjects
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   345
1391
2a80b14fc548 more docstring
sylvain.thenault@logilab.fr
parents: 1386
diff changeset
   346
    def form_build_context(self, rendervalues=None):
2a80b14fc548 more docstring
sylvain.thenault@logilab.fr
parents: 1386
diff changeset
   347
        """build form context values (the .context attribute which is a
2a80b14fc548 more docstring
sylvain.thenault@logilab.fr
parents: 1386
diff changeset
   348
        dictionary with field instance as key associated to a dictionary
2a80b14fc548 more docstring
sylvain.thenault@logilab.fr
parents: 1386
diff changeset
   349
        containing field 'name' (qualified), 'id', 'value' (for display, always
2a80b14fc548 more docstring
sylvain.thenault@logilab.fr
parents: 1386
diff changeset
   350
        a string).
2a80b14fc548 more docstring
sylvain.thenault@logilab.fr
parents: 1386
diff changeset
   351
2a80b14fc548 more docstring
sylvain.thenault@logilab.fr
parents: 1386
diff changeset
   352
        rendervalues is an optional dictionary containing extra kwargs given to
2a80b14fc548 more docstring
sylvain.thenault@logilab.fr
parents: 1386
diff changeset
   353
        form_render()
2a80b14fc548 more docstring
sylvain.thenault@logilab.fr
parents: 1386
diff changeset
   354
        """
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   355
        self.context = context = {}
1392
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   356
        # ensure rendervalues is a dict
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   357
        if rendervalues is None:
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   358
            rendervalues = {}
1947
8696403e5324 test and fix __linkto handling (#343421)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1861
diff changeset
   359
        # use a copy in case fields are modified while context is build (eg
8696403e5324 test and fix __linkto handling (#343421)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1861
diff changeset
   360
        # __linkto handling for instance)
8696403e5324 test and fix __linkto handling (#343421)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1861
diff changeset
   361
        for field in self.fields[:]:
894
e1f848785e3d test and fixes
sylvain.thenault@logilab.fr
parents: 892
diff changeset
   362
            for field in field.actual_fields(self):
1304
8975c8e520a9 refactor button handling
sylvain.thenault@logilab.fr
parents: 1289
diff changeset
   363
                field.form_init(self)
1392
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   364
                value = self.form_field_display_value(field, rendervalues)
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   365
                context[field] = {'value': value,
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   366
                                  'name': self.form_field_name(field),
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   367
                                  'id': self.form_field_id(field),
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   368
                                  }
847
27c4ebe90d03 prefixed form methods to avoid potential conflicts with field names, button related method, a bit more serious renderer
sylvain.thenault@logilab.fr
parents: 844
diff changeset
   369
1392
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   370
    def form_field_display_value(self, field, rendervalues, load_bytes=False):
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   371
        """return field's *string* value to use for display
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
   372
1392
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   373
        looks in
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   374
        1. previously submitted form values if any (eg on validation error)
848
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   375
        2. req.form
1392
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   376
        3. extra kw args given to render_form
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   377
        4. field's typed value
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   378
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   379
        values found in 1. and 2. are expected te be already some 'display'
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   380
        value while those found in 3. and 4. are expected to be correctly typed.
848
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   381
        """
1755
1bd225376013 consider __linkto in form_field_display_value
sylvain.thenault@logilab.fr
parents: 1710
diff changeset
   382
        value = self._req_display_value(field)
1bd225376013 consider __linkto in form_field_display_value
sylvain.thenault@logilab.fr
parents: 1710
diff changeset
   383
        if value is None:
1392
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   384
            if field.name in rendervalues:
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   385
                value = rendervalues[field.name]
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   386
            else:
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   387
                value = self.form_field_value(field, load_bytes)
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   388
                if callable(value):
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   389
                    value = value(self)
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
   390
            if value != INTERNAL_FIELD_VALUE:
1392
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   391
                value = field.format_value(self.req, value)
897
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
   392
        return value
1392
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   393
1755
1bd225376013 consider __linkto in form_field_display_value
sylvain.thenault@logilab.fr
parents: 1710
diff changeset
   394
    def _req_display_value(self, field):
1bd225376013 consider __linkto in form_field_display_value
sylvain.thenault@logilab.fr
parents: 1710
diff changeset
   395
        qname = self.form_field_name(field)
1bd225376013 consider __linkto in form_field_display_value
sylvain.thenault@logilab.fr
parents: 1710
diff changeset
   396
        if qname in self.form_previous_values:
1bd225376013 consider __linkto in form_field_display_value
sylvain.thenault@logilab.fr
parents: 1710
diff changeset
   397
            return self.form_previous_values[qname]
1bd225376013 consider __linkto in form_field_display_value
sylvain.thenault@logilab.fr
parents: 1710
diff changeset
   398
        if qname in self.req.form:
1bd225376013 consider __linkto in form_field_display_value
sylvain.thenault@logilab.fr
parents: 1710
diff changeset
   399
            return self.req.form[qname]
1843
646c2dd1f03e #343290: inputs don't use value specified in URL
sylvain.thenault@logilab.fr
parents: 1756
diff changeset
   400
        if field.name in self.req.form:
646c2dd1f03e #343290: inputs don't use value specified in URL
sylvain.thenault@logilab.fr
parents: 1756
diff changeset
   401
            return self.req.form[field.name]
1755
1bd225376013 consider __linkto in form_field_display_value
sylvain.thenault@logilab.fr
parents: 1710
diff changeset
   402
        return None
1bd225376013 consider __linkto in form_field_display_value
sylvain.thenault@logilab.fr
parents: 1710
diff changeset
   403
1392
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   404
    def form_field_value(self, field, load_bytes=False):
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   405
        """return field's *typed* value"""
1855
4e2eeb88780f restore possibility to have default value methods on forms, this may still be useful according to how the form is defined
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1843
diff changeset
   406
        myattr = '%s_%s_default' % (field.role, field.name)
4e2eeb88780f restore possibility to have default value methods on forms, this may still be useful according to how the form is defined
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1843
diff changeset
   407
        if hasattr(self, myattr):
4e2eeb88780f restore possibility to have default value methods on forms, this may still be useful according to how the form is defined
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1843
diff changeset
   408
            return getattr(self, myattr)()
1861
21fae1546ac4 stupido
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1860
diff changeset
   409
        value = field.initial
1860
ce67132ced1c this is actually needed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1855
diff changeset
   410
        if callable(value):
ce67132ced1c this is actually needed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1855
diff changeset
   411
            value = value(self)
1861
21fae1546ac4 stupido
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1860
diff changeset
   412
        return value
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
   413
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   414
    def form_field_error(self, field):
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   415
        """return validation error for widget's field, if any"""
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
   416
        if self._field_has_error(field):
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
   417
            self.form_displayed_errors.add(field.name)
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
   418
            return u'<span class="error">%s</span>' % self.form_valerror.errors[field.name]
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   419
        return u''
897
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
   420
1060
d795477ad16b rename method to form_field_format
sylvain.thenault@logilab.fr
parents: 1059
diff changeset
   421
    def form_field_format(self, field):
1393
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   422
        """return MIME type used for the given (text or bytes) field"""
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   423
        return self.req.property_value('ui.default-text-format')
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
   424
1061
7d2e6b5fae3c * new load_bytes argument to form_field_value
sylvain.thenault@logilab.fr
parents: 1060
diff changeset
   425
    def form_field_encoding(self, field):
1393
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   426
        """return encoding used for the given (text) field"""
1061
7d2e6b5fae3c * new load_bytes argument to form_field_value
sylvain.thenault@logilab.fr
parents: 1060
diff changeset
   427
        return self.req.encoding
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
   428
849
8591d896db7e update some prototype, ChangeStateForm
sylvain.thenault@logilab.fr
parents: 848
diff changeset
   429
    def form_field_name(self, field):
1393
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   430
        """return qualified name for the given field"""
847
27c4ebe90d03 prefixed form methods to avoid potential conflicts with field names, button related method, a bit more serious renderer
sylvain.thenault@logilab.fr
parents: 844
diff changeset
   431
        return field.name
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   432
849
8591d896db7e update some prototype, ChangeStateForm
sylvain.thenault@logilab.fr
parents: 848
diff changeset
   433
    def form_field_id(self, field):
1393
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   434
        """return dom id for the given field"""
847
27c4ebe90d03 prefixed form methods to avoid potential conflicts with field names, button related method, a bit more serious renderer
sylvain.thenault@logilab.fr
parents: 844
diff changeset
   435
        return field.id
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
   436
1183
62afd820d3ae field_by_name now takes a "role" argument, override it in AutomaticForm to call guess field if necessary
sylvain.thenault@logilab.fr
parents: 1175
diff changeset
   437
    def form_field_vocabulary(self, field, limit=None):
1393
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   438
        """return vocabulary for the given field. Should be overriden in
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   439
        specific forms using fields which requires some vocabulary
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   440
        """
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   441
        raise NotImplementedError
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   442
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
   443
    def _field_has_error(self, field):
1393
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   444
        """return true if the field has some error in given validation exception
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   445
        """
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
   446
        return self.form_valerror and field.name in self.form_valerror.errors
1393
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   447
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
   448
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   449
class EntityFieldsForm(FieldsForm):
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   450
    __select__ = (match_kwargs('entity') | (one_line_rset & non_final_entity()))
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
   451
1561
85752d14c15d [form] __maineid missing from the special fields list
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1530
diff changeset
   452
    internal_fields = FieldsForm.internal_fields + ('__type', 'eid', '__maineid')
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   453
    domid = 'entityForm'
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
   454
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   455
    def __init__(self, *args, **kwargs):
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   456
        self.edited_entity = kwargs.pop('entity', None)
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   457
        msg = kwargs.pop('submitmsg', None)
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   458
        super(EntityFieldsForm, self).__init__(*args, **kwargs)
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   459
        if self.edited_entity is None:
1651
675873ed82e3 protect against None values
sylvain.thenault@logilab.fr
parents: 1564
diff changeset
   460
            self.edited_entity = self.complete_entity(self.row or 0, self.col or 0)
887
51e371245bc5 various fixes to have change state and deletion forms working
sylvain.thenault@logilab.fr
parents: 874
diff changeset
   461
        self.form_add_hidden('__type', eidparam=True)
51e371245bc5 various fixes to have change state and deletion forms working
sylvain.thenault@logilab.fr
parents: 874
diff changeset
   462
        self.form_add_hidden('eid')
1947
8696403e5324 test and fix __linkto handling (#343421)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1861
diff changeset
   463
        if msg:
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   464
            # If we need to directly attach the new object to another one
1947
8696403e5324 test and fix __linkto handling (#343421)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1861
diff changeset
   465
            self.form_add_hidden('__message', msg)
8696403e5324 test and fix __linkto handling (#343421)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1861
diff changeset
   466
        if not self.is_subform:
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   467
            for linkto in self.req.list_form_param('__linkto'):
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   468
                self.form_add_hidden('__linkto', linkto)
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   469
                msg = '%s %s' % (msg, self.req._('and linked'))
1519
5cfc5cc1dd20 fix retreival of previously submitted error for entity forms
sylvain.thenault@logilab.fr
parents: 1451
diff changeset
   470
        # in case of direct instanciation
5cfc5cc1dd20 fix retreival of previously submitted error for entity forms
sylvain.thenault@logilab.fr
parents: 1451
diff changeset
   471
        self.schema = self.edited_entity.schema
5cfc5cc1dd20 fix retreival of previously submitted error for entity forms
sylvain.thenault@logilab.fr
parents: 1451
diff changeset
   472
        self.vreg = self.edited_entity.vreg
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
   473
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
   474
    def _field_has_error(self, field):
1393
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   475
        """return true if the field has some error in given validation exception
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   476
        """
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
   477
        return super(EntityFieldsForm, self)._field_has_error(field) \
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
   478
               and self.form_valerror.eid == self.edited_entity.eid
1393
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   479
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   480
    def _relation_vocabulary(self, rtype, targettype, role,
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   481
                            limit=None, done=None):
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   482
        """return unrelated entities for a given relation and target entity type
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   483
        for use in vocabulary
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   484
        """
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   485
        if done is None:
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   486
            done = set()
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   487
        rset = self.edited_entity.unrelated(rtype, targettype, role, limit)
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   488
        res = []
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   489
        for entity in rset.entities():
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   490
            if entity.eid in done:
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   491
                continue
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   492
            done.add(entity.eid)
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   493
            res.append((entity.view('combobox'), entity.eid))
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   494
        return res
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   495
1755
1bd225376013 consider __linkto in form_field_display_value
sylvain.thenault@logilab.fr
parents: 1710
diff changeset
   496
    def _req_display_value(self, field):
1bd225376013 consider __linkto in form_field_display_value
sylvain.thenault@logilab.fr
parents: 1710
diff changeset
   497
        value = super(EntityFieldsForm, self)._req_display_value(field)
1bd225376013 consider __linkto in form_field_display_value
sylvain.thenault@logilab.fr
parents: 1710
diff changeset
   498
        if value is None:
1947
8696403e5324 test and fix __linkto handling (#343421)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1861
diff changeset
   499
            value = self.edited_entity.linked_to(field.name, field.role)
8696403e5324 test and fix __linkto handling (#343421)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1861
diff changeset
   500
            if value:
8696403e5324 test and fix __linkto handling (#343421)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1861
diff changeset
   501
                searchedvalues = ['%s:%s:%s' % (field.name, eid, field.role)
8696403e5324 test and fix __linkto handling (#343421)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1861
diff changeset
   502
                                  for eid in value]
8696403e5324 test and fix __linkto handling (#343421)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1861
diff changeset
   503
                # remove associated __linkto hidden fields
8696403e5324 test and fix __linkto handling (#343421)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1861
diff changeset
   504
                for field in self.fields_by_name('__linkto'):
8696403e5324 test and fix __linkto handling (#343421)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1861
diff changeset
   505
                    if field.initial in searchedvalues:
8696403e5324 test and fix __linkto handling (#343421)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1861
diff changeset
   506
                        self.remove_field(field)
8696403e5324 test and fix __linkto handling (#343421)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1861
diff changeset
   507
            else:
8696403e5324 test and fix __linkto handling (#343421)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1861
diff changeset
   508
                value = None
1755
1bd225376013 consider __linkto in form_field_display_value
sylvain.thenault@logilab.fr
parents: 1710
diff changeset
   509
        return value
1bd225376013 consider __linkto in form_field_display_value
sylvain.thenault@logilab.fr
parents: 1710
diff changeset
   510
1393
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   511
    def _form_field_default_value(self, field, load_bytes):
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   512
        defaultattr = 'default_%s' % field.name
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   513
        if hasattr(self.edited_entity, defaultattr):
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   514
            # XXX bw compat, default_<field name> on the entity
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   515
            warn('found %s on %s, should be set on a specific form'
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   516
                 % (defaultattr, self.edited_entity.id), DeprecationWarning)
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   517
            value = getattr(self.edited_entity, defaultattr)
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   518
            if callable(value):
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   519
                value = value()
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   520
        else:
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   521
            value = super(EntityFieldsForm, self).form_field_value(field,
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   522
                                                                   load_bytes)
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   523
        return value
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
   524
1995
ec95eaa2b711 turn renderers into appobjects
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   525
    def form_default_renderer(self):
ec95eaa2b711 turn renderers into appobjects
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   526
        return self.vreg.select_object('formrenderers', self.form_renderer_id,
ec95eaa2b711 turn renderers into appobjects
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   527
                                       self.req, self.rset,
ec95eaa2b711 turn renderers into appobjects
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   528
                                       row=self.row, col=self.col,
ec95eaa2b711 turn renderers into appobjects
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   529
                                       entity=self.edited_entity)
ec95eaa2b711 turn renderers into appobjects
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   530
1315
86bddd181e03 should set None as default here as well
sylvain.thenault@logilab.fr
parents: 1312
diff changeset
   531
    def form_build_context(self, values=None):
1393
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   532
        """overriden to add edit[s|o] hidden fields and to ensure schema fields
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   533
        have eidparam set to True
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   534
1528
864ae7c15ef5 other fixlets
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1451
diff changeset
   535
        edit[s|o] hidden fields are used to indicate the value for the
1393
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   536
        associated field before the (potential) modification made when
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   537
        submitting the form.
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   538
        """
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   539
        eschema = self.edited_entity.e_schema
863
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   540
        for field in self.fields[:]:
894
e1f848785e3d test and fixes
sylvain.thenault@logilab.fr
parents: 892
diff changeset
   541
            for field in field.actual_fields(self):
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   542
                fieldname = field.name
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   543
                if fieldname != 'eid' and (
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   544
                    (eschema.has_subject_relation(fieldname) or
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   545
                     eschema.has_object_relation(fieldname))):
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   546
                    field.eidparam = True
1393
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   547
                    self.fields.append(HiddenInitialValueField(field))
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   548
        return super(EntityFieldsForm, self).form_build_context(values)
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
   549
1392
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   550
    def form_field_value(self, field, load_bytes=False):
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   551
        """return field's *typed* value
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   552
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   553
        overriden to deal with
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   554
        * special eid / __type / edits- / edito- fields
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   555
        * lookup for values on edited entities
848
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   556
        """
1392
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   557
        attr = field.name
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   558
        entity = self.edited_entity
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   559
        if attr == 'eid':
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   560
            return entity.eid
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   561
        if not field.eidparam:
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   562
            return super(EntityFieldsForm, self).form_field_value(field, load_bytes)
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   563
        if attr.startswith('edits-') or attr.startswith('edito-'):
888
603327e9aef4 fix field value for hidden edit[s|à] fields
sylvain.thenault@logilab.fr
parents: 887
diff changeset
   564
            # edit[s|o]- fieds must have the actual value stored on the entity
1392
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   565
            assert hasattr(field, 'visible_field')
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   566
            vfield = field.visible_field
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   567
            assert vfield.eidparam
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   568
            if entity.has_eid():
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   569
                return self.form_field_value(vfield)
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   570
            return INTERNAL_FIELD_VALUE
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   571
        if attr == '__type':
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   572
            return entity.id
1701
9fb5b4741a08 use values cached on the entity if any
sylvain.thenault@logilab.fr
parents: 1686
diff changeset
   573
        if self.schema.rschema(attr).is_final():
1392
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   574
            attrtype = entity.e_schema.destination(attr)
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   575
            if attrtype == 'Password':
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   576
                return entity.has_eid() and INTERNAL_FIELD_VALUE or ''
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   577
            if attrtype == 'Bytes':
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   578
                if entity.has_eid():
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   579
                    if load_bytes:
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   580
                        return getattr(entity, attr)
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   581
                    # XXX value should reflect if some file is already attached
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   582
                    return True
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   583
                return False
1701
9fb5b4741a08 use values cached on the entity if any
sylvain.thenault@logilab.fr
parents: 1686
diff changeset
   584
            if entity.has_eid() or attr in entity:
1392
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   585
                value = getattr(entity, attr)
888
603327e9aef4 fix field value for hidden edit[s|à] fields
sylvain.thenault@logilab.fr
parents: 887
diff changeset
   586
            else:
1392
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   587
                value = self._form_field_default_value(field, load_bytes)
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   588
            return value
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   589
        # non final relation field
1701
9fb5b4741a08 use values cached on the entity if any
sylvain.thenault@logilab.fr
parents: 1686
diff changeset
   590
        if entity.has_eid() or entity.relation_cached(attr, field.role):
9fb5b4741a08 use values cached on the entity if any
sylvain.thenault@logilab.fr
parents: 1686
diff changeset
   591
            value = [r[0] for r in entity.related(attr, field.role)]
848
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   592
        else:
1392
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   593
            value = self._form_field_default_value(field, load_bytes)
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1391
diff changeset
   594
        return value
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
   595
1060
d795477ad16b rename method to form_field_format
sylvain.thenault@logilab.fr
parents: 1059
diff changeset
   596
    def form_field_format(self, field):
1393
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   597
        """return MIME type used for the given (text or bytes) field"""
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   598
        entity = self.edited_entity
1107
961a478593a5 has_metadata is a schema method
sylvain.thenault@logilab.fr
parents: 1101
diff changeset
   599
        if field.eidparam and entity.e_schema.has_metadata(field.name, 'format') and (
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   600
            entity.has_eid() or '%s_format' % field.name in entity):
1360
13ae1121835e rename attribute_metadata method to attr_metadata to save a few chars
sylvain.thenault@logilab.fr
parents: 1338
diff changeset
   601
            return self.edited_entity.attr_metadata(field.name, 'format')
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   602
        return self.req.property_value('ui.default-text-format')
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   603
1061
7d2e6b5fae3c * new load_bytes argument to form_field_value
sylvain.thenault@logilab.fr
parents: 1060
diff changeset
   604
    def form_field_encoding(self, field):
1393
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   605
        """return encoding used for the given (text) field"""
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   606
        entity = self.edited_entity
1107
961a478593a5 has_metadata is a schema method
sylvain.thenault@logilab.fr
parents: 1101
diff changeset
   607
        if field.eidparam and entity.e_schema.has_metadata(field.name, 'encoding') and (
1061
7d2e6b5fae3c * new load_bytes argument to form_field_value
sylvain.thenault@logilab.fr
parents: 1060
diff changeset
   608
            entity.has_eid() or '%s_encoding' % field.name in entity):
1360
13ae1121835e rename attribute_metadata method to attr_metadata to save a few chars
sylvain.thenault@logilab.fr
parents: 1338
diff changeset
   609
            return self.edited_entity.attr_metadata(field.name, 'encoding')
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
   610
        return super(EntityFieldsForm, self).form_field_encoding(field)
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
   611
849
8591d896db7e update some prototype, ChangeStateForm
sylvain.thenault@logilab.fr
parents: 848
diff changeset
   612
    def form_field_name(self, field):
1393
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   613
        """return qualified name for the given field"""
847
27c4ebe90d03 prefixed form methods to avoid potential conflicts with field names, button related method, a bit more serious renderer
sylvain.thenault@logilab.fr
parents: 844
diff changeset
   614
        if field.eidparam:
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   615
            return eid_param(field.name, self.edited_entity.eid)
847
27c4ebe90d03 prefixed form methods to avoid potential conflicts with field names, button related method, a bit more serious renderer
sylvain.thenault@logilab.fr
parents: 844
diff changeset
   616
        return field.name
27c4ebe90d03 prefixed form methods to avoid potential conflicts with field names, button related method, a bit more serious renderer
sylvain.thenault@logilab.fr
parents: 844
diff changeset
   617
849
8591d896db7e update some prototype, ChangeStateForm
sylvain.thenault@logilab.fr
parents: 848
diff changeset
   618
    def form_field_id(self, field):
1393
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   619
        """return dom id for the given field"""
847
27c4ebe90d03 prefixed form methods to avoid potential conflicts with field names, button related method, a bit more serious renderer
sylvain.thenault@logilab.fr
parents: 844
diff changeset
   620
        if field.eidparam:
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   621
            return eid_param(field.id, self.edited_entity.eid)
847
27c4ebe90d03 prefixed form methods to avoid potential conflicts with field names, button related method, a bit more serious renderer
sylvain.thenault@logilab.fr
parents: 844
diff changeset
   622
        return field.id
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
   623
1031
1a89683cb687 restore limit on form_field_vocabulary, actually used
sylvain.thenault@logilab.fr
parents: 1016
diff changeset
   624
    def form_field_vocabulary(self, field, limit=None):
1393
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   625
        """return vocabulary for the given field"""
903
63a8ab7eeb9c The value as returned by FieldWidget._render_attrs() is now always a list
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 902
diff changeset
   626
        role, rtype = field.role, field.name
1265
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1184
diff changeset
   627
        method = '%s_%s_vocabulary' % (role, rtype)
903
63a8ab7eeb9c The value as returned by FieldWidget._render_attrs() is now always a list
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 902
diff changeset
   628
        try:
1265
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1184
diff changeset
   629
            vocabfunc = getattr(self, method)
903
63a8ab7eeb9c The value as returned by FieldWidget._render_attrs() is now always a list
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 902
diff changeset
   630
        except AttributeError:
1265
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1184
diff changeset
   631
            try:
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1184
diff changeset
   632
                # XXX bw compat, <role>_<rtype>_vocabulary on the entity
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1184
diff changeset
   633
                vocabfunc = getattr(self.edited_entity, method)
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1184
diff changeset
   634
            except AttributeError:
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1184
diff changeset
   635
                vocabfunc = getattr(self, '%s_relation_vocabulary' % role)
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1184
diff changeset
   636
            else:
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1184
diff changeset
   637
                warn('found %s on %s, should be set on a specific form'
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1184
diff changeset
   638
                     % (method, self.edited_entity.id), DeprecationWarning)
1009
bcd0c3ae1935 typos, backport comment
sylvain.thenault@logilab.fr
parents: 944
diff changeset
   639
        # NOTE: it is the responsibility of `vocabfunc` to sort the result
bcd0c3ae1935 typos, backport comment
sylvain.thenault@logilab.fr
parents: 944
diff changeset
   640
        #       (direclty through RQL or via a python sort). This is also
bcd0c3ae1935 typos, backport comment
sylvain.thenault@logilab.fr
parents: 944
diff changeset
   641
        #       important because `vocabfunc` might return a list with
bcd0c3ae1935 typos, backport comment
sylvain.thenault@logilab.fr
parents: 944
diff changeset
   642
        #       couples (label, None) which act as separators. In these
bcd0c3ae1935 typos, backport comment
sylvain.thenault@logilab.fr
parents: 944
diff changeset
   643
        #       cases, it doesn't make sense to sort results afterwards.
1031
1a89683cb687 restore limit on form_field_vocabulary, actually used
sylvain.thenault@logilab.fr
parents: 1016
diff changeset
   644
        return vocabfunc(rtype, limit)
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   645
902
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   646
    def subject_relation_vocabulary(self, rtype, limit=None):
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   647
        """defaut vocabulary method for the given relation, looking for
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   648
        relation's object entities (i.e. self is the subject)
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   649
        """
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   650
        entity = self.edited_entity
902
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   651
        if isinstance(rtype, basestring):
1528
864ae7c15ef5 other fixlets
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1451
diff changeset
   652
            rtype = entity.schema.rschema(rtype)
902
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   653
        done = None
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   654
        assert not rtype.is_final(), rtype
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   655
        if entity.has_eid():
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   656
            done = set(e.eid for e in getattr(entity, str(rtype)))
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   657
        result = []
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   658
        rsetsize = None
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   659
        for objtype in rtype.objects(entity.e_schema):
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   660
            if limit is not None:
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   661
                rsetsize = limit - len(result)
1393
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   662
            result += self._relation_vocabulary(rtype, objtype, 'subject',
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   663
                                                rsetsize, done)
902
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   664
            if limit is not None and len(result) >= limit:
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   665
                break
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   666
        return result
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   667
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   668
    def object_relation_vocabulary(self, rtype, limit=None):
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   669
        """defaut vocabulary method for the given relation, looking for
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   670
        relation's subject entities (i.e. self is the object)
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   671
        """
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   672
        entity = self.edited_entity
902
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   673
        if isinstance(rtype, basestring):
1528
864ae7c15ef5 other fixlets
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1451
diff changeset
   674
            rtype = entity.schema.rschema(rtype)
902
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   675
        done = None
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   676
        if entity.has_eid():
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   677
            done = set(e.eid for e in getattr(entity, 'reverse_%s' % rtype))
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   678
        result = []
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   679
        rsetsize = None
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   680
        for subjtype in rtype.subjects(entity.e_schema):
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   681
            if limit is not None:
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   682
                rsetsize = limit - len(result)
1393
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   683
            result += self._relation_vocabulary(rtype, subjtype, 'object',
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   684
                                                rsetsize, done)
902
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   685
            if limit is not None and len(result) >= limit:
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   686
                break
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   687
        return result
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   688
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1437
diff changeset
   689
    def subject_in_state_vocabulary(self, rtype, limit=None):
1393
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   690
        """vocabulary method for the in_state relation, looking for relation's
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   691
        object entities (i.e. self is the subject) according to initial_state,
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   692
        state_of and next_state relation
1175
96747df28a1f backport subject_in_state_vocabulary to EntityFieldsForm, deprecate the old one
sylvain.thenault@logilab.fr
parents: 1147
diff changeset
   693
        """
1184
a33deae7c6a2 oops, this method doesn't belong anymore to entity class
sylvain.thenault@logilab.fr
parents: 1183
diff changeset
   694
        entity = self.edited_entity
a33deae7c6a2 oops, this method doesn't belong anymore to entity class
sylvain.thenault@logilab.fr
parents: 1183
diff changeset
   695
        if not entity.has_eid() or not entity.in_state:
1175
96747df28a1f backport subject_in_state_vocabulary to EntityFieldsForm, deprecate the old one
sylvain.thenault@logilab.fr
parents: 1147
diff changeset
   696
            # get the initial state
96747df28a1f backport subject_in_state_vocabulary to EntityFieldsForm, deprecate the old one
sylvain.thenault@logilab.fr
parents: 1147
diff changeset
   697
            rql = 'Any S where S state_of ET, ET name %(etype)s, ET initial_state S'
1184
a33deae7c6a2 oops, this method doesn't belong anymore to entity class
sylvain.thenault@logilab.fr
parents: 1183
diff changeset
   698
            rset = self.req.execute(rql, {'etype': str(entity.e_schema)})
1175
96747df28a1f backport subject_in_state_vocabulary to EntityFieldsForm, deprecate the old one
sylvain.thenault@logilab.fr
parents: 1147
diff changeset
   699
            if rset:
96747df28a1f backport subject_in_state_vocabulary to EntityFieldsForm, deprecate the old one
sylvain.thenault@logilab.fr
parents: 1147
diff changeset
   700
                return [(rset.get_entity(0, 0).view('combobox'), rset[0][0])]
96747df28a1f backport subject_in_state_vocabulary to EntityFieldsForm, deprecate the old one
sylvain.thenault@logilab.fr
parents: 1147
diff changeset
   701
            return []
96747df28a1f backport subject_in_state_vocabulary to EntityFieldsForm, deprecate the old one
sylvain.thenault@logilab.fr
parents: 1147
diff changeset
   702
        results = []
1184
a33deae7c6a2 oops, this method doesn't belong anymore to entity class
sylvain.thenault@logilab.fr
parents: 1183
diff changeset
   703
        for tr in entity.in_state[0].transitions(entity):
1175
96747df28a1f backport subject_in_state_vocabulary to EntityFieldsForm, deprecate the old one
sylvain.thenault@logilab.fr
parents: 1147
diff changeset
   704
            state = tr.destination_state[0]
96747df28a1f backport subject_in_state_vocabulary to EntityFieldsForm, deprecate the old one
sylvain.thenault@logilab.fr
parents: 1147
diff changeset
   705
            results.append((state.view('combobox'), state.eid))
96747df28a1f backport subject_in_state_vocabulary to EntityFieldsForm, deprecate the old one
sylvain.thenault@logilab.fr
parents: 1147
diff changeset
   706
        return sorted(results)
96747df28a1f backport subject_in_state_vocabulary to EntityFieldsForm, deprecate the old one
sylvain.thenault@logilab.fr
parents: 1147
diff changeset
   707
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   708
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   709
class CompositeForm(FieldsForm):
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   710
    """form composed for sub-forms"""
1995
ec95eaa2b711 turn renderers into appobjects
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   711
    form_renderer_id = 'composite'
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1406
diff changeset
   712
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   713
    def __init__(self, *args, **kwargs):
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   714
        super(CompositeForm, self).__init__(*args, **kwargs)
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   715
        self.forms = []
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   716
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   717
    def form_add_subform(self, subform):
1393
ff6758d7b96f cleanup, more docstring
sylvain.thenault@logilab.fr
parents: 1392
diff changeset
   718
        """mark given form as a subform and append it"""
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
   719
        subform.is_subform = True
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   720
        self.forms.append(subform)