web/form.py
author sylvain.thenault@logilab.fr
Wed, 11 Mar 2009 11:15:59 +0100
branchtls-sprint
changeset 1048 2a93712a6f8b
parent 1047 21d4d5e6aa45
child 1049 f8e92c2f3bef
permissions -rw-r--r--
fix format field vocabulary
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
751
ec16f43107d3 update import
sylvain.thenault@logilab.fr
parents: 692
diff changeset
     4
:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     5
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     6
"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     7
__docformat__ = "restructuredtext en"
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     8
848
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
     9
from warnings import warn
1016
26387b836099 use datetime instead of mx.DateTime
sylvain.thenault@logilab.fr
parents: 1013
diff changeset
    10
from datetime import date, datetime
26387b836099 use datetime instead of mx.DateTime
sylvain.thenault@logilab.fr
parents: 1013
diff changeset
    11
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    12
from simplejson import dumps
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    13
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    14
from logilab.common.compat import any
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    15
from logilab.mtconverter import html_escape
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    16
897
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
    17
from yams.constraints import SizeConstraint, StaticVocabularyConstraint
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
    18
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    19
from cubicweb import typed_eid
1047
21d4d5e6aa45 make forms selectable (appobject)
sylvain.thenault@logilab.fr
parents: 1032
diff changeset
    20
from cubicweb.appobject import AppObject
867
14a79faa3a56 fix implementation errors import DateTimePicker
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 865
diff changeset
    21
from cubicweb.utils import ustrftime
1047
21d4d5e6aa45 make forms selectable (appobject)
sylvain.thenault@logilab.fr
parents: 1032
diff changeset
    22
from cubicweb.selectors import yes, match_form_params, non_final_entity
751
ec16f43107d3 update import
sylvain.thenault@logilab.fr
parents: 692
diff changeset
    23
from cubicweb.view import NOINDEX, NOFOLLOW, View, EntityView, AnyRsetView
1048
2a93712a6f8b fix format field vocabulary
sylvain.thenault@logilab.fr
parents: 1047
diff changeset
    24
from cubicweb.schema import FormatConstraint
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    25
from cubicweb.common.registerers import accepts_registerer
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
    26
from cubicweb.common.uilib import toggle_action
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    27
from cubicweb.web import stdmsgs
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    28
from cubicweb.web.httpcache import NoHTTPCacheManager
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
    29
from cubicweb.web.controller import NAV_FORM_PARAMETERS, redirect_params
863
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
    30
from cubicweb.web import INTERNAL_FIELD_VALUE, eid_param
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
    31
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    32
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    33
def relation_id(eid, rtype, target, reid):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    34
    if target == 'subject':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    35
        return u'%s:%s:%s' % (eid, rtype, reid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    36
    return u'%s:%s:%s' % (reid, rtype, eid)
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    37
        
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    38
def toggable_relation_link(eid, nodeid, label='x'):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    39
    js = u"javascript: togglePendingDelete('%s', %s);" % (nodeid, html_escape(dumps(eid)))
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    40
    return u'[<a class="handle" href="%s" id="handle%s">%s</a>]' % (js, nodeid, label)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    41
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    42
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    43
class FormMixIn(object):
944
e9da555f19c5 [forms] a note (understanding the cause would be nice)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 913
diff changeset
    44
    """abstract form mix-in
e9da555f19c5 [forms] a note (understanding the cause would be nice)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 913
diff changeset
    45
    XXX: you should inherit from this FIRST (obscure pb with super call)"""
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    46
    category = 'form'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    47
    controller = 'edit'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    48
    domid = 'entityForm'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    49
    
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    50
    http_cache_manager = NoHTTPCacheManager
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    51
    add_to_breadcrumbs = False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    52
    skip_relations = set()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    53
    
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    54
    def __init__(self, req, rset):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    55
        super(FormMixIn, self).__init__(req, rset)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    56
        self.maxrelitems = self.req.property_value('navigation.related-limit')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    57
        self.maxcomboitems = self.req.property_value('navigation.combobox-limit')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    58
        self.force_display = not not req.form.get('__force_display')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    59
        # get validation session data which may have been previously set.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    60
        # deleting validation errors here breaks form reloading (errors are
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    61
        # no more available), they have to be deleted by application's publish
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    62
        # method on successful commit
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    63
        formurl = req.url()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    64
        forminfo = req.get_session_data(formurl)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    65
        if forminfo:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    66
            req.data['formvalues'] = forminfo['values']
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    67
            req.data['formerrors'] = errex = forminfo['errors']
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    68
            req.data['displayederrors'] = set()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    69
            # if some validation error occured on entity creation, we have to
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    70
            # get the original variable name from its attributed eid
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    71
            foreid = errex.entity
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    72
            for var, eid in forminfo['eidmap'].items():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    73
                if foreid == eid:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    74
                    errex.eid = var
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    75
                    break
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    76
            else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    77
                errex.eid = foreid
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    78
        
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    79
    def html_headers(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    80
        """return a list of html headers (eg something to be inserted between
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    81
        <head> and </head> of the returned page
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    82
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    83
        by default forms are neither indexed nor followed
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    84
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    85
        return [NOINDEX, NOFOLLOW]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    86
        
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    87
    def linkable(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    88
        """override since forms are usually linked by an action,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    89
        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
    90
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    91
        return False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    92
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    93
    @property
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    94
    def limit(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    95
        if self.force_display:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    96
            return None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    97
        return self.maxrelitems + 1
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    98
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    99
    def need_multipart(self, entity, categories=('primary', 'secondary')):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   100
        """return a boolean indicating if form's enctype should be multipart
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   101
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   102
        for rschema, _, x in entity.relations_by_category(categories):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   103
            if entity.get_widget(rschema, x).need_multipart:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   104
                return True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   105
        # let's find if any of our inlined entities needs multipart
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   106
        for rschema, targettypes, x in entity.relations_by_category('inlineview'):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   107
            assert len(targettypes) == 1, \
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   108
                   "I'm not able to deal with several targets and inlineview"
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   109
            ttype = targettypes[0]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   110
            inlined_entity = self.vreg.etype_class(ttype)(self.req, None, None)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   111
            for irschema, _, x in inlined_entity.relations_by_category(categories):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   112
                if inlined_entity.get_widget(irschema, x).need_multipart:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   113
                    return True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   114
        return False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   115
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   116
    def error_message(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   117
        """return formatted error message
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   118
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   119
        This method should be called once inlined field errors has been consumed
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   120
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   121
        errex = self.req.data.get('formerrors')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   122
        # get extra errors
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   123
        if errex is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   124
            errormsg = self.req._('please correct the following errors:')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   125
            displayed = self.req.data['displayederrors']
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   126
            errors = sorted((field, err) for field, err in errex.errors.items()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   127
                            if not field in displayed)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   128
            if errors:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   129
                if len(errors) > 1:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   130
                    templstr = '<li>%s</li>\n' 
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   131
                else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   132
                    templstr = '&nbsp;%s\n'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   133
                for field, err in errors:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   134
                    if field is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   135
                        errormsg += templstr % err
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   136
                    else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   137
                        errormsg += templstr % '%s: %s' % (self.req._(field), err)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   138
                if len(errors) > 1:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   139
                    errormsg = '<ul>%s</ul>' % errormsg
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   140
            return u'<div class="errorMessage">%s</div>' % errormsg
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   141
        return u''
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   142
    
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   143
    def restore_pending_inserts(self, entity, cell=False):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   144
        """used to restore edition page as it was before clicking on
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   145
        'search for <some entity type>'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   146
        
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   147
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   148
        eid = entity.eid
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   149
        cell = cell and "div_insert_" or "tr"
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   150
        pending_inserts = set(self.req.get_pending_inserts(eid))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   151
        for pendingid in pending_inserts:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   152
            eidfrom, rtype, eidto = pendingid.split(':')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   153
            if typed_eid(eidfrom) == entity.eid: # subject
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   154
                label = display_name(self.req, rtype, 'subject')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   155
                reid = eidto
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   156
            else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   157
                label = display_name(self.req, rtype, 'object')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   158
                reid = eidfrom
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   159
            jscall = "javascript: cancelPendingInsert('%s', '%s', null, %s);" \
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   160
                     % (pendingid, cell, eid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   161
            rset = self.req.eid_rset(reid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   162
            eview = self.view('text', rset, row=0)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   163
            # XXX find a clean way to handle baskets
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   164
            if rset.description[0][0] == 'Basket':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   165
                eview = '%s (%s)' % (eview, display_name(self.req, 'Basket'))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   166
            yield rtype, pendingid, jscall, label, reid, eview
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   167
        
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   168
    
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   169
    def force_display_link(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   170
        return (u'<span class="invisible">' 
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   171
                u'[<a href="javascript: window.location.href+=\'&amp;__force_display=1\'">%s</a>]'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   172
                u'</span>' % self.req._('view all'))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   173
    
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   174
    def relations_table(self, entity):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   175
        """yiels 3-tuples (rtype, target, related_list)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   176
        where <related_list> itself a list of :
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   177
          - node_id (will be the entity element's DOM id)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   178
          - appropriate javascript's togglePendingDelete() function call
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   179
          - status 'pendingdelete' or ''
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   180
          - oneline view of related entity
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   181
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   182
        eid = entity.eid
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   183
        pending_deletes = self.req.get_pending_deletes(eid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   184
        # XXX (adim) : quick fix to get Folder relations
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   185
        for label, rschema, target in entity.srelations_by_category(('generic', 'metadata'), 'add'):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   186
            if rschema in self.skip_relations:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   187
                continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   188
            relatedrset = entity.related(rschema, target, limit=self.limit)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   189
            toggable_rel_link = self.toggable_relation_link_func(rschema)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   190
            related = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   191
            for row in xrange(relatedrset.rowcount):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   192
                nodeid = relation_id(eid, rschema, target, relatedrset[row][0])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   193
                if nodeid in pending_deletes:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   194
                    status = u'pendingDelete'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   195
                    label = '+'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   196
                else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   197
                    status = u''
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   198
                    label = 'x'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   199
                dellink = toggable_rel_link(eid, nodeid, label)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   200
                eview = self.view('oneline', relatedrset, row=row)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   201
                related.append((nodeid, dellink, status, eview))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   202
            yield (rschema, target, related)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   203
        
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   204
    def toggable_relation_link_func(self, rschema):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   205
        if not rschema.has_perm(self.req, 'delete'):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   206
            return lambda x, y, z: u''
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   207
        return toggable_relation_link
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   208
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   209
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   210
    def redirect_url(self, entity=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   211
        """return a url to use as next direction if there are some information
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   212
        specified in current form params, else return the result the reset_url
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   213
        method which should be defined in concrete classes
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   214
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   215
        rparams = redirect_params(self.req.form)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   216
        if rparams:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   217
            return self.build_url('view', **rparams)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   218
        return self.reset_url(entity)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   219
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   220
    def reset_url(self, entity):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   221
        raise NotImplementedError('implement me in concrete classes')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   222
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   223
    BUTTON_STR = u'<input class="validateButton" type="submit" name="%s" value="%s" tabindex="%s"/>'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   224
    ACTION_SUBMIT_STR = u'<input class="validateButton" type="button" onclick="postForm(\'%s\', \'%s\', \'%s\')" value="%s" tabindex="%s"/>'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   225
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   226
    def button_ok(self, label=None, tabindex=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   227
        label = self.req._(label or stdmsgs.BUTTON_OK).capitalize()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   228
        return self.BUTTON_STR % ('defaultsubmit', label, tabindex or 2)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   229
    
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   230
    def button_apply(self, label=None, tabindex=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   231
        label = self.req._(label or stdmsgs.BUTTON_APPLY).capitalize()
863
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   232
        return self.ACTION_SUBMIT_STR % ('__action_apply', label, self.domid,
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   233
                                         label, tabindex or 3)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   234
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   235
    def button_delete(self, label=None, tabindex=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   236
        label = self.req._(label or stdmsgs.BUTTON_DELETE).capitalize()
863
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   237
        return self.ACTION_SUBMIT_STR % ('__action_delete', label, self.domid,
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   238
                                         label, tabindex or 3)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   239
    
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   240
    def button_cancel(self, label=None, tabindex=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   241
        label = self.req._(label or stdmsgs.BUTTON_CANCEL).capitalize()
863
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   242
        return self.ACTION_SUBMIT_STR % ('__action_cancel', label, self.domid,
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   243
                                         label, tabindex or 4)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   244
    
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   245
    def button_reset(self, label=None, tabindex=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   246
        label = self.req._(label or stdmsgs.BUTTON_CANCEL).capitalize()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   247
        return u'<input class="validateButton" type="reset" value="%s" tabindex="%s"/>' % (
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   248
            label, tabindex or 4)
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   249
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   250
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   251
###############################################################################
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   252
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   253
from cubicweb.common import tags
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   254
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   255
# widgets ############
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   256
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   257
class FieldWidget(object):
905
64fd6eaaa9a4 add needs_css and needs_js on widgets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 904
diff changeset
   258
    needs_js = ()
64fd6eaaa9a4 add needs_css and needs_js on widgets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 904
diff changeset
   259
    needs_css = ()
1032
25ec009daa95 by default, don't set id attribute for hidden inputs
sylvain.thenault@logilab.fr
parents: 1031
diff changeset
   260
    setdomid = True
905
64fd6eaaa9a4 add needs_css and needs_js on widgets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 904
diff changeset
   261
    
1032
25ec009daa95 by default, don't set id attribute for hidden inputs
sylvain.thenault@logilab.fr
parents: 1031
diff changeset
   262
    def __init__(self, attrs=None, setdomid=None):
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   263
        self.attrs = attrs or {}
1032
25ec009daa95 by default, don't set id attribute for hidden inputs
sylvain.thenault@logilab.fr
parents: 1031
diff changeset
   264
        if setdomid is not None:
25ec009daa95 by default, don't set id attribute for hidden inputs
sylvain.thenault@logilab.fr
parents: 1031
diff changeset
   265
            # override class's default value
25ec009daa95 by default, don't set id attribute for hidden inputs
sylvain.thenault@logilab.fr
parents: 1031
diff changeset
   266
            self.setdomid = setdomid
897
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
   267
905
64fd6eaaa9a4 add needs_css and needs_js on widgets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 904
diff changeset
   268
    def add_media(self, form):
64fd6eaaa9a4 add needs_css and needs_js on widgets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 904
diff changeset
   269
        """adds media (CSS & JS) required by this widget"""
64fd6eaaa9a4 add needs_css and needs_js on widgets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 904
diff changeset
   270
        req = form.req
64fd6eaaa9a4 add needs_css and needs_js on widgets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 904
diff changeset
   271
        if self.needs_js:
64fd6eaaa9a4 add needs_css and needs_js on widgets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 904
diff changeset
   272
            req.add_js(self.needs_js)
64fd6eaaa9a4 add needs_css and needs_js on widgets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 904
diff changeset
   273
        if self.needs_css:
64fd6eaaa9a4 add needs_css and needs_js on widgets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 904
diff changeset
   274
            req.add_css(self.needs_css)
64fd6eaaa9a4 add needs_css and needs_js on widgets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 904
diff changeset
   275
        
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   276
    def render(self, form, field):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   277
        raise NotImplementedError
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
   278
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
   279
    def _render_attrs(self, form, field):
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
   280
        name = form.context[field]['name']
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
   281
        values = form.context[field]['value']
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
   282
        if not isinstance(values, (tuple, list)):
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
   283
            values = (values,)
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   284
        attrs = dict(self.attrs)
1032
25ec009daa95 by default, don't set id attribute for hidden inputs
sylvain.thenault@logilab.fr
parents: 1031
diff changeset
   285
        if self.setdomid:
25ec009daa95 by default, don't set id attribute for hidden inputs
sylvain.thenault@logilab.fr
parents: 1031
diff changeset
   286
            attrs['id'] = form.context[field]['id']
910
a86ab461b8fd fix DateTimePicker implementation, it should now work
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 907
diff changeset
   287
        return name, values, attrs
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
   288
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   289
class Input(FieldWidget):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   290
    type = None
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   291
    
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   292
    def render(self, form, field):
905
64fd6eaaa9a4 add needs_css and needs_js on widgets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 904
diff changeset
   293
        self.add_media(form)
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
   294
        name, values, attrs = self._render_attrs(form, field)
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
   295
        inputs = [tags.input(name=name, value=value, type=self.type, **attrs)
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
   296
                  for value in values]
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
   297
        return u'\n'.join(inputs)
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   298
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   299
class TextInput(Input):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   300
    type = 'text'
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   301
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   302
class PasswordInput(Input):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   303
    type = 'password'
908
136d91725ecf confirmation in password widget
sylvain.thenault@logilab.fr
parents: 907
diff changeset
   304
    
136d91725ecf confirmation in password widget
sylvain.thenault@logilab.fr
parents: 907
diff changeset
   305
    def render(self, form, field):
136d91725ecf confirmation in password widget
sylvain.thenault@logilab.fr
parents: 907
diff changeset
   306
        self.add_media(form)
136d91725ecf confirmation in password widget
sylvain.thenault@logilab.fr
parents: 907
diff changeset
   307
        name, values, attrs = self._render_attrs(form, field)
911
sylvain.thenault@logilab.fr
parents: 908
diff changeset
   308
        assert len(values) == 1
sylvain.thenault@logilab.fr
parents: 908
diff changeset
   309
        inputs = [tags.input(name=name, value=values[0], type=self.type, **attrs),
908
136d91725ecf confirmation in password widget
sylvain.thenault@logilab.fr
parents: 907
diff changeset
   310
                  '<br/>',
136d91725ecf confirmation in password widget
sylvain.thenault@logilab.fr
parents: 907
diff changeset
   311
                  tags.input(name=name+'-confirm', type=self.type, **attrs),
136d91725ecf confirmation in password widget
sylvain.thenault@logilab.fr
parents: 907
diff changeset
   312
                  '&nbsp;', tags.span(form.req._('confirm password'),
136d91725ecf confirmation in password widget
sylvain.thenault@logilab.fr
parents: 907
diff changeset
   313
                                      **{'class': 'emphasis'})]
136d91725ecf confirmation in password widget
sylvain.thenault@logilab.fr
parents: 907
diff changeset
   314
        return u'\n'.join(inputs)
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   315
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   316
class FileInput(Input):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   317
    type = 'file'
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   318
    
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   319
    def _render_attrs(self, form, field):
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   320
        # ignore value which makes no sense here (XXX even on form validation error?)
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   321
        name, values, attrs = super(FileInput, self)._render_attrs(form, field)
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   322
        return name, ('',), attrs
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   323
        
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   324
class HiddenInput(Input):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   325
    type = 'hidden'
1032
25ec009daa95 by default, don't set id attribute for hidden inputs
sylvain.thenault@logilab.fr
parents: 1031
diff changeset
   326
    setdomid = False # by default, don't set id attribute on hidden input
897
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
   327
    
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   328
class ButtonInput(Input):
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   329
    type = 'button'
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   330
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   331
class TextArea(FieldWidget):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   332
    def render(self, form, 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
   333
        name, values, attrs = self._render_attrs(form, field)
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   334
        attrs.setdefault('onkeypress', 'autogrow(this)')
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
   335
        if not values:
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
   336
            value = u''
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
   337
        elif len(values) == 1:
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
   338
            value = values[0]
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
   339
        else:
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
   340
            raise ValueError('a textarea is not supposed to be multivalued')
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   341
        return tags.textarea(value, name=name, **attrs)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   342
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   343
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   344
class FCKEditor(TextArea):
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   345
    def __init__(self, attrs):
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   346
        super(FCKEditor, self).__init__(attrs)
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   347
        self.attrs['cubicweb:type'] = 'wysiwyg'
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   348
    
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   349
    def render(self, form, field):
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   350
        form.req.fckeditor_config()
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   351
        return super(self, FCKEditor, self).render(form, field)
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   352
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   353
894
e1f848785e3d test and fixes
sylvain.thenault@logilab.fr
parents: 892
diff changeset
   354
#class EditableFile(Widget):
e1f848785e3d test and fixes
sylvain.thenault@logilab.fr
parents: 892
diff changeset
   355
#    # XXX
e1f848785e3d test and fixes
sylvain.thenault@logilab.fr
parents: 892
diff changeset
   356
#    pass
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   357
864
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   358
class Select(FieldWidget):
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
   359
    def __init__(self, attrs=None, multiple=False):
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   360
        super(Select, self).__init__(attrs)
901
0dcf01eb97a0 implement default vocabulary method on Field, provide a specific one on RelationField
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 900
diff changeset
   361
        self.multiple = multiple
864
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   362
        
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   363
    def render(self, form, 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
   364
        name, curvalues, attrs = self._render_attrs(form, field)
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
   365
        vocab = field.vocabulary(form)
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   366
        options = []
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   367
        for label, value in vocab:
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
   368
            if value in curvalues:
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
   369
                options.append(tags.option(label, value=value, selected='selected'))
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
   370
            else:
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
   371
                options.append(tags.option(label, value=value))
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   372
        if attrs is None:
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   373
            return tags.select(name=name, options=options)
901
0dcf01eb97a0 implement default vocabulary method on Field, provide a specific one on RelationField
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 900
diff changeset
   374
        return tags.select(name=name, multiple=self.multiple,
0dcf01eb97a0 implement default vocabulary method on Field, provide a specific one on RelationField
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 900
diff changeset
   375
                           options=options, **attrs)
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   376
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   377
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   378
class CheckBox(Input):
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   379
    type = 'checkbox'
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   380
    
865
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   381
    def _render_attrs(self, form, field):
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   382
        name, values, attrs = super(CheckBox, self)._render_attrs(form, field)
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   383
        if values and values[0]:
865
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   384
            attrs['checked'] = u'checked'
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   385
        return name, values, attrs
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   386
865
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   387
        
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   388
class Radio(FieldWidget):
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   389
    pass
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   390
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   391
865
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   392
class DateTimePicker(TextInput):
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   393
    monthnames = ('january', 'february', 'march', 'april',
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   394
                  'may', 'june', 'july', 'august',
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   395
                  'september', 'october', 'november', 'december')
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   396
    daynames = ('monday', 'tuesday', 'wednesday', 'thursday',
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   397
                'friday', 'saturday', 'sunday')
865
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   398
905
64fd6eaaa9a4 add needs_css and needs_js on widgets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 904
diff changeset
   399
    needs_js = ('cubicweb.ajax.js', 'cubicweb.calendar.js')
64fd6eaaa9a4 add needs_css and needs_js on widgets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 904
diff changeset
   400
    needs_css = ('cubicweb.calendar_popup.css',)
64fd6eaaa9a4 add needs_css and needs_js on widgets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 904
diff changeset
   401
    
865
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   402
    @classmethod
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   403
    def add_localized_infos(cls, req):
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   404
        """inserts JS variables defining localized months and days"""
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   405
        # import here to avoid dependancy from cubicweb-common to simplejson
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   406
        _ = req._
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   407
        monthnames = [_(mname) for mname in cls.monthnames]
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   408
        daynames = [_(dname) for dname in cls.daynames]
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   409
        req.html_headers.define_var('MONTHNAMES', monthnames)
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   410
        req.html_headers.define_var('DAYNAMES', daynames)
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   411
    
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   412
    def render(self, form, field):
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   413
        txtwidget = super(DateTimePicker, self).render(form, field)
910
a86ab461b8fd fix DateTimePicker implementation, it should now work
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 907
diff changeset
   414
        self.add_localized_infos(form.req)
867
14a79faa3a56 fix implementation errors import DateTimePicker
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 865
diff changeset
   415
        cal_button = self._render_calendar_popup(form, field)
865
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   416
        return txtwidget + cal_button
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   417
    
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   418
    def _render_calendar_popup(self, form, field):
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   419
        req = form.req
867
14a79faa3a56 fix implementation errors import DateTimePicker
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 865
diff changeset
   420
        value = form.context[field]['rawvalue']
14a79faa3a56 fix implementation errors import DateTimePicker
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 865
diff changeset
   421
        inputid = form.context[field]['id']
14a79faa3a56 fix implementation errors import DateTimePicker
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 865
diff changeset
   422
        helperid = '%shelper' % inputid
865
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   423
        if not value:
1016
26387b836099 use datetime instead of mx.DateTime
sylvain.thenault@logilab.fr
parents: 1013
diff changeset
   424
            value = date.today()
865
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   425
        year, month = value.year, value.month
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   426
        onclick = "toggleCalendar('%s', '%s', %s, %s);" % (
867
14a79faa3a56 fix implementation errors import DateTimePicker
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 865
diff changeset
   427
            helperid, inputid, year, month)
865
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   428
        return (u"""<a onclick="toggleCalendar('%s', '%s', %s, %s);" class="calhelper">
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   429
<img src="%s" title="%s" alt="" /></a><div class="calpopup hidden" id="%s"></div>"""
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   430
                % (helperid, inputid, year, month,
867
14a79faa3a56 fix implementation errors import DateTimePicker
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 865
diff changeset
   431
                   req.external_resource('CALENDAR_ICON'),
14a79faa3a56 fix implementation errors import DateTimePicker
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 865
diff changeset
   432
                   req._('calendar'), helperid) )
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   433
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   434
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   435
# fields ############
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   436
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   437
class Field(object):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   438
    """field class is introduced to control what's displayed in edition form
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   439
    """
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   440
    widget = TextInput
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   441
    needs_multipart = False
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   442
    creation_rank = 0
904
4f1ce95aa686 fix label generation in forms
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 903
diff changeset
   443
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   444
    def __init__(self, name=None, id=None, label=None,
901
0dcf01eb97a0 implement default vocabulary method on Field, provide a specific one on RelationField
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 900
diff changeset
   445
                 widget=None, required=False, initial=None,
0dcf01eb97a0 implement default vocabulary method on Field, provide a specific one on RelationField
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 900
diff changeset
   446
                 choices=None, help=None, eidparam=False):
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   447
        self.required = required
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   448
        if widget is not None:
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   449
            self.widget = widget
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   450
        if isinstance(self.widget, type):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   451
            self.widget = self.widget()
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   452
        self.name = name
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   453
        self.label = label or name
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   454
        self.id = id or name
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   455
        self.initial = initial
901
0dcf01eb97a0 implement default vocabulary method on Field, provide a specific one on RelationField
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 900
diff changeset
   456
        self.choices = choices or ()
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   457
        self.help = help
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   458
        self.eidparam = eidparam
901
0dcf01eb97a0 implement default vocabulary method on Field, provide a specific one on RelationField
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 900
diff changeset
   459
        self.role = 'subject'
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   460
        # global fields ordering in forms
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   461
        Field.creation_rank += 1
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   462
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   463
    def set_name(self, name):
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   464
        assert name
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   465
        self.name = name
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   466
        if not self.id:
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   467
            self.id = name
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   468
        if not self.label:
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   469
            self.label = name
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   470
            
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   471
    def is_visible(self):
904
4f1ce95aa686 fix label generation in forms
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 903
diff changeset
   472
        return not isinstance(self.widget, HiddenInput)
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   473
    
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   474
    def actual_fields(self, form):
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   475
        yield self
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   476
900
8f95ebbe2fd8 field debug helper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 899
diff changeset
   477
    def __unicode__(self):
8f95ebbe2fd8 field debug helper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 899
diff changeset
   478
        return u'<%s name=%r label=%r id=%r initial=%r>' % (
8f95ebbe2fd8 field debug helper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 899
diff changeset
   479
            self.__class__.__name__, self.name, self.label,
8f95ebbe2fd8 field debug helper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 899
diff changeset
   480
            self.id, self.initial)
8f95ebbe2fd8 field debug helper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 899
diff changeset
   481
8f95ebbe2fd8 field debug helper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 899
diff changeset
   482
    def __repr__(self):
8f95ebbe2fd8 field debug helper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 899
diff changeset
   483
        return self.__unicode__().encode('utf-8')
8f95ebbe2fd8 field debug helper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 899
diff changeset
   484
    
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   485
    def format_value(self, req, value):
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
   486
        if isinstance(value, (list, tuple)):
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
   487
            return [self.format_single_value(req, val) for val in value]
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
   488
        return self.format_single_value(req, value)
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
   489
    
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
   490
    def format_single_value(self, req, value):
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
   491
        if value is None:
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
   492
            return u''
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   493
        return unicode(value)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   494
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   495
    def get_widget(self, form):
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   496
        return self.widget
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   497
    
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   498
    def example_format(self, req):
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   499
        return u''
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   500
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   501
    def render(self, form, renderer):
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   502
        return self.get_widget(form).render(form, self)
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   503
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   504
901
0dcf01eb97a0 implement default vocabulary method on Field, provide a specific one on RelationField
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 900
diff changeset
   505
    def vocabulary(self, form):
0dcf01eb97a0 implement default vocabulary method on Field, provide a specific one on RelationField
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 900
diff changeset
   506
        return self.choices
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   507
901
0dcf01eb97a0 implement default vocabulary method on Field, provide a specific one on RelationField
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 900
diff changeset
   508
    
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   509
class StringField(Field):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   510
    def __init__(self, max_length=None, **kwargs):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   511
        super(StringField, self).__init__(**kwargs)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   512
        self.max_length = max_length
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   513
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   514
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   515
class TextField(Field):
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   516
    widget = TextArea
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
   517
    def __init__(self, rows=10, cols=80, **kwargs):
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   518
        super(TextField, self).__init__(**kwargs)
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
   519
        self.rows = rows
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
   520
        self.cols = cols
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   521
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   522
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   523
class RichTextField(TextField):
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   524
    widget = None
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   525
    def __init__(self, format_field=None, **kwargs):
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   526
        super(RichTextField, self).__init__(**kwargs)
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   527
        self.format_field = format_field
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   528
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   529
    def get_widget(self, form):
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   530
        if self.widget is None:
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   531
            if self.use_fckeditor(form):
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   532
                return FCKEditor()
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   533
            return TextArea()
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   534
        return self.widget
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   535
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   536
    def get_format_field(self, form):
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   537
        if self.format_field:
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   538
            return self.format_field
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   539
        # we have to cache generated field since it's use as key in the
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   540
        # context dictionnary
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   541
        try:
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   542
            return form.req.data[self]
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   543
        except KeyError:
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   544
            if self.use_fckeditor(form):
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   545
                # if fckeditor is used and format field isn't explicitly
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   546
                # deactivated, we want an hidden field for the format
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   547
                widget = HiddenInput()
1048
2a93712a6f8b fix format field vocabulary
sylvain.thenault@logilab.fr
parents: 1047
diff changeset
   548
                choices = None
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   549
            else:
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   550
                # else we want a format selector
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   551
                # XXX compute vocabulary
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   552
                widget = Select
1048
2a93712a6f8b fix format field vocabulary
sylvain.thenault@logilab.fr
parents: 1047
diff changeset
   553
                req = form.req
2a93712a6f8b fix format field vocabulary
sylvain.thenault@logilab.fr
parents: 1047
diff changeset
   554
                choices = [(req._(format), format) for format in FormatConstraint().vocabulary(req=req)]
2a93712a6f8b fix format field vocabulary
sylvain.thenault@logilab.fr
parents: 1047
diff changeset
   555
            field = StringField(name=self.name + '_format', widget=widget,
2a93712a6f8b fix format field vocabulary
sylvain.thenault@logilab.fr
parents: 1047
diff changeset
   556
                                choices=choices)
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   557
            form.req.data[self] = field
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   558
            return field
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   559
    
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   560
    def actual_fields(self, form):
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   561
        yield self
894
e1f848785e3d test and fixes
sylvain.thenault@logilab.fr
parents: 892
diff changeset
   562
        format_field = self.get_format_field(form)
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   563
        if format_field:
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   564
            yield format_field
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   565
            
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   566
    def use_fckeditor(self, form):
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   567
        """return True if fckeditor should be used to edit entity's attribute named
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   568
        `attr`, according to user preferences
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   569
        """
1013
948a3882c94a add a use_fckeditor method on http request
sylvain.thenault@logilab.fr
parents: 1009
diff changeset
   570
        if form.req.use_fckeditor():
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   571
            return form.form_format_field_value(self) == 'text/html'
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   572
        return False
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   573
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   574
    def render(self, form, renderer):
894
e1f848785e3d test and fixes
sylvain.thenault@logilab.fr
parents: 892
diff changeset
   575
        format_field = self.get_format_field(form)
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   576
        if format_field:
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   577
            result = format_field.render(form, renderer)
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   578
        else:
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   579
            result = u''
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   580
        return result + self.get_widget(form).render(form, self)
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   581
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   582
    
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   583
class FileField(StringField):
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   584
    widget = FileInput
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   585
    needs_multipart = True
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   586
    
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   587
    def __init__(self, format_field=None, encoding_field=None, **kwargs):
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   588
        super(FileField, self).__init__(**kwargs)
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   589
        self.format_field = format_field
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   590
        self.encoding_field = encoding_field
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   591
        
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   592
    def actual_fields(self, form):
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   593
        yield self
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   594
        if self.format_field:
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   595
            yield self.format_field
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   596
        if self.encoding_field:
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   597
            yield self.encoding_field
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   598
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   599
    def render(self, form, renderer):
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   600
        wdgs = [self.get_widget(form).render(form, self)]
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   601
        if self.format_field or self.encoding_field:
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   602
            divid = '%s-advanced' % form.context[self]['name']
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   603
            wdgs.append(u'<a href="%s" title="%s"><img src="%s" alt="%s"/></a>' %
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   604
                        (html_escape(toggle_action(divid)),
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   605
                         form.req._('show advanced fields'),
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   606
                         html_escape(form.req.build_url('data/puce_down.png')),
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   607
                         form.req._('show advanced fields')))
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   608
            wdgs.append(u'<div id="%s" class="hidden">' % divid)
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   609
            if self.format_field:
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   610
                wdgs.append(self.render_subfield(form, self.format_field, renderer))
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   611
            if self.encoding_field:
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   612
                wdgs.append(self.render_subfield(form, self.encoding_field, renderer))
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   613
            wdgs.append(u'</div>')            
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   614
        if not self.required and form.context[self]['value']:
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   615
            # trick to be able to delete an uploaded file
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   616
            wdgs.append(u'<br/>')
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   617
            wdgs.append(tags.input(name=u'%s__detach' % form.context[self]['name'],
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   618
                                   type=u'checkbox'))
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   619
            wdgs.append(form.req._('detach attached file'))
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   620
        return u'\n'.join(wdgs)
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   621
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   622
    def render_subfield(self, form, field, renderer):
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   623
        return (renderer.render_label(form, field)
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   624
                + field.render(form, renderer)
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   625
                + renderer.render_help(form, field)
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   626
                + u'<br/>')
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   627
        
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   628
    
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   629
class IntField(Field):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   630
    def __init__(self, min=None, max=None, **kwargs):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   631
        super(IntField, self).__init__(**kwargs)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   632
        self.min = min
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   633
        self.max = max
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   634
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   635
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
   636
class BooleanField(Field):
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
   637
    widget = Radio
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
   638
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   639
864
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   640
class FloatField(IntField):    
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
   641
    def format_single_value(self, req, value):
864
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   642
        formatstr = entity.req.property_value('ui.float-format')
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   643
        if value is None:
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   644
            return u''
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   645
        return formatstr % float(value)
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   646
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   647
    def render_example(self, req):
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   648
        return self.format_value(req, 1.234)
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   649
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   650
864
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   651
class DateField(StringField):
899
48d465b5171a rename propname into format_prop
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 898
diff changeset
   652
    format_prop = 'ui.date-format'
905
64fd6eaaa9a4 add needs_css and needs_js on widgets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 904
diff changeset
   653
    widget = DateTimePicker
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   654
    
899
48d465b5171a rename propname into format_prop
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 898
diff changeset
   655
    def format_single_value(self, req, value):
48d465b5171a rename propname into format_prop
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 898
diff changeset
   656
        return value and ustrftime(value, req.property_value(self.format_prop)) or u''
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   657
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   658
    def render_example(self, req):
1016
26387b836099 use datetime instead of mx.DateTime
sylvain.thenault@logilab.fr
parents: 1013
diff changeset
   659
        return self.format_value(req, datetime.now())
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   660
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   661
864
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   662
class DateTimeField(DateField):
899
48d465b5171a rename propname into format_prop
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 898
diff changeset
   663
    format_prop = 'ui.datetime-format'
864
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   664
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   665
899
48d465b5171a rename propname into format_prop
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 898
diff changeset
   666
class TimeField(DateField):
48d465b5171a rename propname into format_prop
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 898
diff changeset
   667
    format_prop = 'ui.datetime-format'
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   668
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   669
863
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   670
class HiddenInitialValueField(Field):
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   671
    def __init__(self, visible_field, name):
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   672
        super(HiddenInitialValueField, self).__init__(name=name,
898
583f64567256 fix HiddenRelationField bug
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 897
diff changeset
   673
                                                      widget=HiddenInput,
583f64567256 fix HiddenRelationField bug
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 897
diff changeset
   674
                                                      eidparam=True)
863
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   675
        self.visible_field = visible_field
897
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
   676
    
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   677
                 
863
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   678
class RelationField(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
   679
    def __init__(self, **kwargs):
863
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   680
        super(RelationField, self).__init__(**kwargs)
897
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
   681
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
   682
    @staticmethod
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
   683
    def fromcardinality(card, role, **kwargs):
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
   684
        return RelationField(widget=Select(multiple=card in '*+'),
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
   685
                             **kwargs)
863
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   686
        
901
0dcf01eb97a0 implement default vocabulary method on Field, provide a specific one on RelationField
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 900
diff changeset
   687
    def vocabulary(self, form):
0dcf01eb97a0 implement default vocabulary method on Field, provide a specific one on RelationField
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 900
diff changeset
   688
        entity = form.entity
0dcf01eb97a0 implement default vocabulary method on Field, provide a specific one on RelationField
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 900
diff changeset
   689
        req = entity.req
0dcf01eb97a0 implement default vocabulary method on Field, provide a specific one on RelationField
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 900
diff changeset
   690
        # first see if its specified by __linkto form parameters
0dcf01eb97a0 implement default vocabulary method on Field, provide a specific one on RelationField
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 900
diff changeset
   691
        linkedto = entity.linked_to(self.name, self.role)
0dcf01eb97a0 implement default vocabulary method on Field, provide a specific one on RelationField
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 900
diff changeset
   692
        if linkedto:
0dcf01eb97a0 implement default vocabulary method on Field, provide a specific one on RelationField
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 900
diff changeset
   693
            entities = (req.eid_rset(eid).get_entity(0, 0) for eid in linkedto)
0dcf01eb97a0 implement default vocabulary method on Field, provide a specific one on RelationField
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 900
diff changeset
   694
            return [(entity.view('combobox'), entity.eid) for entity in entities]
0dcf01eb97a0 implement default vocabulary method on Field, provide a specific one on RelationField
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 900
diff changeset
   695
        # it isn't, check if the entity provides a method to get correct values
0dcf01eb97a0 implement default vocabulary method on Field, provide a specific one on RelationField
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 900
diff changeset
   696
        res = []
0dcf01eb97a0 implement default vocabulary method on Field, provide a specific one on RelationField
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 900
diff changeset
   697
        if not self.required:
0dcf01eb97a0 implement default vocabulary method on Field, provide a specific one on RelationField
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 900
diff changeset
   698
            res.append(('', INTERNAL_FIELD_VALUE))
0dcf01eb97a0 implement default vocabulary method on Field, provide a specific one on RelationField
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 900
diff changeset
   699
        # vocabulary doesn't include current values, add them
0dcf01eb97a0 implement default vocabulary method on Field, provide a specific one on RelationField
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 900
diff changeset
   700
        if entity.has_eid():
0dcf01eb97a0 implement default vocabulary method on Field, provide a specific one on RelationField
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 900
diff changeset
   701
            rset = entity.related(self.name, self.role)
0dcf01eb97a0 implement default vocabulary method on Field, provide a specific one on RelationField
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 900
diff changeset
   702
            relatedvocab = [(e.view('combobox'), e.eid) for e in rset.entities()]
0dcf01eb97a0 implement default vocabulary method on Field, provide a specific one on RelationField
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 900
diff changeset
   703
        else:
0dcf01eb97a0 implement default vocabulary method on Field, provide a specific one on RelationField
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 900
diff changeset
   704
            relatedvocab = []
0dcf01eb97a0 implement default vocabulary method on Field, provide a specific one on RelationField
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 900
diff changeset
   705
        return res + form.form_field_vocabulary(self) + relatedvocab
0dcf01eb97a0 implement default vocabulary method on Field, provide a specific one on RelationField
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 900
diff changeset
   706
    
0dcf01eb97a0 implement default vocabulary method on Field, provide a specific one on RelationField
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 900
diff changeset
   707
    def format_single_value(self, req, value):
0dcf01eb97a0 implement default vocabulary method on Field, provide a specific one on RelationField
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 900
diff changeset
   708
        return value
0dcf01eb97a0 implement default vocabulary method on Field, provide a specific one on RelationField
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 900
diff changeset
   709
    
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   710
# forms ############
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   711
class metafieldsform(type):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   712
    def __new__(mcs, name, bases, classdict):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   713
        allfields = []
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   714
        for base in bases:
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   715
            if hasattr(base, '_fields_'):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   716
                allfields += base._fields_
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   717
        clsfields = (item for item in classdict.items()
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   718
                     if isinstance(item[1], Field))
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   719
        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
   720
            if not field.name:
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   721
                field.set_name(fieldname)
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   722
            allfields.append(field)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   723
        classdict['_fields_'] = allfields
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   724
        return super(metafieldsform, mcs).__new__(mcs, name, bases, classdict)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   725
    
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   726
1047
21d4d5e6aa45 make forms selectable (appobject)
sylvain.thenault@logilab.fr
parents: 1032
diff changeset
   727
class FieldsForm(FormMixIn, AppObject):
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   728
    __metaclass__ = metafieldsform
1047
21d4d5e6aa45 make forms selectable (appobject)
sylvain.thenault@logilab.fr
parents: 1032
diff changeset
   729
    __registry__ = 'forms'
21d4d5e6aa45 make forms selectable (appobject)
sylvain.thenault@logilab.fr
parents: 1032
diff changeset
   730
    __select__ = yes()
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   731
    
1047
21d4d5e6aa45 make forms selectable (appobject)
sylvain.thenault@logilab.fr
parents: 1032
diff changeset
   732
    def __init__(self, req, rset=None, domid=None, title=None, action='edit',
21d4d5e6aa45 make forms selectable (appobject)
sylvain.thenault@logilab.fr
parents: 1032
diff changeset
   733
                 onsubmit="return freezeFormButtons('%(domid)s');",
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   734
                 cssclass=None, cssstyle=None, cwtarget=None, buttons=None,
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   735
                 redirect_path=None, set_error_url=True, copy_nav_params=False):
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   736
        self.req = req
1047
21d4d5e6aa45 make forms selectable (appobject)
sylvain.thenault@logilab.fr
parents: 1032
diff changeset
   737
        self.rset = rset
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   738
        self.config = req.vreg.config
887
51e371245bc5 various fixes to have change state and deletion forms working
sylvain.thenault@logilab.fr
parents: 874
diff changeset
   739
        self.domid = domid or 'form'
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   740
        self.title = title
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   741
        self.action = action
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   742
        self.onsubmit = onsubmit
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   743
        self.cssclass = cssclass
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   744
        self.cssstyle = cssstyle
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   745
        self.cwtarget = cwtarget
887
51e371245bc5 various fixes to have change state and deletion forms working
sylvain.thenault@logilab.fr
parents: 874
diff changeset
   746
        self.redirect_path = redirect_path
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   747
        self.fields = list(self.__class__._fields_)
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   748
        if set_error_url:
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   749
            self.form_add_hidden('__errorurl', req.url())
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   750
        if copy_nav_params:
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   751
            for param in NAV_FORM_PARAMETERS:
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   752
                value = req.form.get(param)
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   753
                if value:
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   754
                    self.form_add_hidden(param, initial=value)
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   755
        self.buttons = buttons or []
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   756
        self.context = {}
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   757
        
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   758
    @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
   759
    def form_needs_multipart(self):
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   760
        return any(field.needs_multipart for field in self.fields) 
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   761
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   762
    def form_add_hidden(self, name, value=None, **kwargs):
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
   763
        self.fields.append(StringField(name=name, widget=HiddenInput,
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
   764
                                       initial=value, **kwargs))
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   765
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
   766
    def form_render(self, **values):
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   767
        renderer = values.pop('renderer', FormRenderer())
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   768
        return renderer.render(self, values)
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   769
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
   770
    def form_build_context(self, values):
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   771
        self.context = context = {}
849
8591d896db7e update some prototype, ChangeStateForm
sylvain.thenault@logilab.fr
parents: 848
diff changeset
   772
        # on validation error, we get a dictionnary of previously submitted values
8591d896db7e update some prototype, ChangeStateForm
sylvain.thenault@logilab.fr
parents: 848
diff changeset
   773
        previous_values = self.req.data.get('formvalues')
8591d896db7e update some prototype, ChangeStateForm
sylvain.thenault@logilab.fr
parents: 848
diff changeset
   774
        if previous_values:
8591d896db7e update some prototype, ChangeStateForm
sylvain.thenault@logilab.fr
parents: 848
diff changeset
   775
            values.update(previous_values)
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
   776
        for field in self.fields:
894
e1f848785e3d test and fixes
sylvain.thenault@logilab.fr
parents: 892
diff changeset
   777
            for field in field.actual_fields(self):
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   778
                value = self.form_field_value(field, values)
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   779
                context[field] = {'value': field.format_value(self.req, value),
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   780
                                  'rawvalue': value,
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   781
                                  'name': self.form_field_name(field),
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   782
                                  'id': self.form_field_id(field),
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   783
                                  }
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
   784
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
   785
    def form_field_value(self, field, values):
848
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   786
        """looks for field's value in
849
8591d896db7e update some prototype, ChangeStateForm
sylvain.thenault@logilab.fr
parents: 848
diff changeset
   787
        1. kw args given to render_form (including previously submitted form
8591d896db7e update some prototype, ChangeStateForm
sylvain.thenault@logilab.fr
parents: 848
diff changeset
   788
           values if any)
848
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   789
        2. req.form
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   790
        3. field's initial value
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   791
        """
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   792
        if field.name in values:
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   793
            value = values[field.name]
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   794
        elif field.name in self.req.form:
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   795
            value = self.req.form[field.name]
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   796
        else:
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   797
            value = field.initial
897
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
   798
        return value
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
   799
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   800
    def form_format_field_value(self, field, values):
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   801
        return self.req.property_value('ui.default-text-format')
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   802
    
849
8591d896db7e update some prototype, ChangeStateForm
sylvain.thenault@logilab.fr
parents: 848
diff changeset
   803
    def form_field_name(self, 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
   804
        return field.name
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   805
849
8591d896db7e update some prototype, ChangeStateForm
sylvain.thenault@logilab.fr
parents: 848
diff changeset
   806
    def form_field_id(self, 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
   807
        return field.id
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
   808
   
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
   809
    def form_field_vocabulary(self, field):
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   810
        raise NotImplementedError
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   811
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   812
    def form_buttons(self):
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   813
        return self.buttons
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   814
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   815
   
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   816
class EntityFieldsForm(FieldsForm):
1047
21d4d5e6aa45 make forms selectable (appobject)
sylvain.thenault@logilab.fr
parents: 1032
diff changeset
   817
    __select__ = non_final_entity()
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   818
    
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   819
    def __init__(self, *args, **kwargs):
887
51e371245bc5 various fixes to have change state and deletion forms working
sylvain.thenault@logilab.fr
parents: 874
diff changeset
   820
        kwargs.setdefault('domid', 'entityForm')
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   821
        self.entity = kwargs.pop('entity', None)
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   822
        super(EntityFieldsForm, self).__init__(*args, **kwargs)
887
51e371245bc5 various fixes to have change state and deletion forms working
sylvain.thenault@logilab.fr
parents: 874
diff changeset
   823
        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
   824
        self.form_add_hidden('eid')
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   825
        
874
90d98d80af82 EntityFieldsForm.form_render() doesn't need entity anymore
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 869
diff changeset
   826
    def form_render(self, **values):
90d98d80af82 EntityFieldsForm.form_render() doesn't need entity anymore
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 869
diff changeset
   827
        self.form_add_entity_hiddens(self.entity.e_schema)
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   828
        return super(EntityFieldsForm, self).form_render(**values)
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   829
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   830
    def form_add_entity_hiddens(self, eschema):
863
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   831
        for field in self.fields[:]:
894
e1f848785e3d test and fixes
sylvain.thenault@logilab.fr
parents: 892
diff changeset
   832
            for field in field.actual_fields(self):
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   833
                fieldname = field.name
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   834
                if fieldname != 'eid' and (
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   835
                    (eschema.has_subject_relation(fieldname) or
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   836
                     eschema.has_object_relation(fieldname))):
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   837
                    field.eidparam = True
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   838
                    self.fields.append(self.form_entity_hidden_field(field))
863
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   839
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   840
    def form_entity_hidden_field(self, field):
863
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   841
        """returns the hidden field which will indicate the value
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   842
        before the modification
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   843
        """
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   844
        # Only RelationField has a `role` attribute, others are used
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   845
        # to describe attribute fields => role is 'subject'
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   846
        if getattr(field, 'role', 'subject') == 'subject':
863
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   847
            name = 'edits-%s' % field.name
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   848
        else:
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   849
            name = 'edito-%s' % field.name
898
583f64567256 fix HiddenRelationField bug
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 897
diff changeset
   850
        return HiddenInitialValueField(field, name=name)
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
   851
        
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
   852
    def form_field_value(self, field, values):
848
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   853
        """look for field's value with the following rules:
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   854
        1. handle special __type and eid fields
849
8591d896db7e update some prototype, ChangeStateForm
sylvain.thenault@logilab.fr
parents: 848
diff changeset
   855
        2. looks in kw args given to render_form (including previously submitted
8591d896db7e update some prototype, ChangeStateForm
sylvain.thenault@logilab.fr
parents: 848
diff changeset
   856
           form values if any)
848
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   857
        3. looks in req.form
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   858
        4. if entity has an eid:
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   859
             1. looks for an associated attribute / method
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   860
             2. use field's initial value
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   861
           else:
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   862
             1. looks for a default_<fieldname> attribute / method on the form
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   863
             2. use field's initial value
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   864
             
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   865
        values found in step 4 may be a callable which'll then be called.
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   866
        """
863
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   867
        fieldname = field.name
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   868
        if fieldname.startswith('edits-') or fieldname.startswith('edito-'):
888
603327e9aef4 fix field value for hidden edit[s|à] fields
sylvain.thenault@logilab.fr
parents: 887
diff changeset
   869
            # edit[s|o]- fieds must have the actual value stored on the entity
603327e9aef4 fix field value for hidden edit[s|à] fields
sylvain.thenault@logilab.fr
parents: 887
diff changeset
   870
            if self.entity.has_eid():
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
   871
                value = self.form_field_entity_value(field.visible_field, default_initial=False)
888
603327e9aef4 fix field value for hidden edit[s|à] fields
sylvain.thenault@logilab.fr
parents: 887
diff changeset
   872
            else:
863
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   873
                value = INTERNAL_FIELD_VALUE
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   874
        elif fieldname == '__type':
848
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   875
            value = self.entity.id
863
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   876
        elif fieldname == 'eid':
848
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   877
            value = self.entity.eid
863
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   878
        elif fieldname in values:
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   879
            value = values[fieldname]
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   880
        elif fieldname in self.req.form:
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   881
            value = self.req.form[fieldname]
848
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   882
        else:
888
603327e9aef4 fix field value for hidden edit[s|à] fields
sylvain.thenault@logilab.fr
parents: 887
diff changeset
   883
            if self.entity.has_eid() and field.eidparam:
848
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   884
                # use value found on the entity or field's initial value if it's
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   885
                # not an attribute of the entity (XXX may conflicts and get
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   886
                # undesired value)
888
603327e9aef4 fix field value for hidden edit[s|à] fields
sylvain.thenault@logilab.fr
parents: 887
diff changeset
   887
                value = self.form_field_entity_value(field, default_initial=True)
848
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   888
            else:
863
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   889
                defaultattr = 'default_%s' % fieldname
848
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   890
                if hasattr(self.entity, defaultattr):
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   891
                    # XXX bw compat, default_<field name> on the entity
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   892
                    warn('found %s on %s, should be set on a specific form'
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   893
                         % (defaultattr, self.entity.id), DeprecationWarning)
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   894
                    value = getattr(self.entity, defaultattr)
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   895
                elif hasattr(self, defaultattr):
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   896
                    # search for default_<field name> on the form instance
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   897
                    value = getattr(self, defaultattr)
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   898
                else:
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   899
                    # use field's initial value
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   900
                    value = field.initial
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   901
            if callable(value):
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   902
                values = value()
897
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
   903
        return value
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   904
    
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   905
    def form_format_field_value(self, field, values):
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   906
        entity = self.entity
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   907
        if field.eidparam and entity.has_format(field.name) and (
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   908
            entity.has_eid() or '%s_format' % field.name in entity):
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   909
            return self.entity.format(field.name) == 'text/html'
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
   910
        return self.req.property_value('ui.default-text-format')
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   911
888
603327e9aef4 fix field value for hidden edit[s|à] fields
sylvain.thenault@logilab.fr
parents: 887
diff changeset
   912
    def form_field_entity_value(self, field, default_initial=True):
603327e9aef4 fix field value for hidden edit[s|à] fields
sylvain.thenault@logilab.fr
parents: 887
diff changeset
   913
        attr = field.name 
603327e9aef4 fix field value for hidden edit[s|à] fields
sylvain.thenault@logilab.fr
parents: 887
diff changeset
   914
        if field.role == 'object':
603327e9aef4 fix field value for hidden edit[s|à] fields
sylvain.thenault@logilab.fr
parents: 887
diff changeset
   915
            attr += '_object'
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   916
        else:
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   917
            attrtype = self.entity.e_schema.destination(attr)
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   918
            if attrtype == 'Password':
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   919
                return self.entity.has_eid() and INTERNAL_FIELD_VALUE or ''
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   920
            if attrtype == 'Bytes':
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   921
                # XXX value should reflect if some file is already attached
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
   922
                return self.entity.has_eid()
888
603327e9aef4 fix field value for hidden edit[s|à] fields
sylvain.thenault@logilab.fr
parents: 887
diff changeset
   923
        if default_initial:
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
   924
            value = getattr(self.entity, attr, field.initial)
888
603327e9aef4 fix field value for hidden edit[s|à] fields
sylvain.thenault@logilab.fr
parents: 887
diff changeset
   925
        else:
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
   926
            value = getattr(self.entity, attr)
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
   927
        if isinstance(field, RelationField):
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
   928
            # in this case, value is the list of related entities
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
   929
            value = [ent.eid for ent in value]
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
   930
        return value
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
   931
    
849
8591d896db7e update some prototype, ChangeStateForm
sylvain.thenault@logilab.fr
parents: 848
diff changeset
   932
    def form_field_name(self, 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
   933
        if field.eidparam:
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
   934
            return eid_param(field.name, self.entity.eid)
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
   935
        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
   936
849
8591d896db7e update some prototype, ChangeStateForm
sylvain.thenault@logilab.fr
parents: 848
diff changeset
   937
    def form_field_id(self, 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
   938
        if field.eidparam:
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
   939
            return eid_param(field.id, self.entity.eid)
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
   940
        return field.id
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   941
        
1031
1a89683cb687 restore limit on form_field_vocabulary, actually used
sylvain.thenault@logilab.fr
parents: 1016
diff changeset
   942
    def form_field_vocabulary(self, field, limit=None):
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
   943
        role, rtype = field.role, field.name
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
   944
        try:
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
   945
            vocabfunc = getattr(self.entity, '%s_%s_vocabulary' % (role, rtype))
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
   946
        except AttributeError:
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
   947
            vocabfunc = getattr(self, '%s_relation_vocabulary' % role)
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
   948
        else:
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
   949
            # XXX bw compat, default_<field name> on the entity
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
   950
            warn('found %s_%s_vocabulary on %s, should be set on a specific form'
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
   951
                 % (role, rtype, self.entity.id), DeprecationWarning)
1009
bcd0c3ae1935 typos, backport comment
sylvain.thenault@logilab.fr
parents: 944
diff changeset
   952
        # NOTE: it is the responsibility of `vocabfunc` to sort the result
bcd0c3ae1935 typos, backport comment
sylvain.thenault@logilab.fr
parents: 944
diff changeset
   953
        #       (direclty through RQL or via a python sort). This is also
bcd0c3ae1935 typos, backport comment
sylvain.thenault@logilab.fr
parents: 944
diff changeset
   954
        #       important because `vocabfunc` might return a list with
bcd0c3ae1935 typos, backport comment
sylvain.thenault@logilab.fr
parents: 944
diff changeset
   955
        #       couples (label, None) which act as separators. In these
bcd0c3ae1935 typos, backport comment
sylvain.thenault@logilab.fr
parents: 944
diff changeset
   956
        #       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
   957
        return vocabfunc(rtype, limit)
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
   958
## XXX BACKPORT ME
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
   959
##         if self.sort:
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
   960
##             choices = sorted(choices)
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
   961
##         if self.rschema.rproperty(self.subjtype, self.objtype, 'internationalizable'):
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
   962
##             return zip((entity.req._(v) for v in choices), choices)
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   963
902
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   964
    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
   965
        """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
   966
        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
   967
        """
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   968
        entity = self.entity
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   969
        if isinstance(rtype, basestring):
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   970
            rtype = entity.schema.rschema(rtype)
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   971
        done = None
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   972
        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
   973
        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
   974
            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
   975
        result = []
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   976
        rsetsize = None
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   977
        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
   978
            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
   979
                rsetsize = limit - len(result)
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   980
            result += self.relation_vocabulary(rtype, objtype, 'subject',
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   981
                                               rsetsize, done)
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   982
            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
   983
                break
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   984
        return result
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   985
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   986
    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
   987
        """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
   988
        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
   989
        """
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   990
        entity = self.entity
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   991
        if isinstance(rtype, basestring):
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   992
            rtype = entity.schema.rschema(rtype)
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   993
        done = None
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   994
        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
   995
            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
   996
        result = []
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   997
        rsetsize = None
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
   998
        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
   999
            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
  1000
                rsetsize = limit - len(result)
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
  1001
            result += self.relation_vocabulary(rtype, subjtype, 'object',
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
  1002
                                               rsetsize, done)
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
  1003
            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
  1004
                break
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
  1005
        return result
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
  1006
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
  1007
    def relation_vocabulary(self, rtype, targettype, role,
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
  1008
                            limit=None, done=None):
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
  1009
        if done is None:
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
  1010
            done = set()
1009
bcd0c3ae1935 typos, backport comment
sylvain.thenault@logilab.fr
parents: 944
diff changeset
  1011
        rset = self.entity.unrelated(rtype, targettype, role, limit)
902
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
  1012
        res = []
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
  1013
        for entity in rset.entities():
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
  1014
            if entity.eid in done:
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
  1015
                continue
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
  1016
            done.add(entity.eid)
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
  1017
            res.append((entity.view('combobox'), entity.eid))
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
  1018
        return res
e4de959c76af vocabulary methods are now defined on forms, not on entities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 901
diff changeset
  1019
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1020
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1021
class MultipleFieldsForm(FieldsForm):
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1022
    def __init__(self, *args, **kwargs):
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1023
        super(MultipleFieldsForm, self).__init__(*args, **kwargs)
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1024
        self.forms = []
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1025
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1026
    def form_add_subform(self, subform):
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1027
        self.forms.append(subform)
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
  1028
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
  1029
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
  1030
# form renderers ############
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
  1031
class FormRenderer(object):
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
  1032
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
  1033
    # renderer interface ######################################################
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
  1034
    
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
  1035
    def render(self, form, values, display_help=True):
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
  1036
        data = []
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
  1037
        w = data.append
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1038
        w(self.open_form(form))
896
6e0379fc1988 put form buttons in a separate table
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 894
diff changeset
  1039
        w(u'<div id="progress">%s</div>' % form.req._('validating...'))
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
  1040
        w(u'<fieldset>')
887
51e371245bc5 various fixes to have change state and deletion forms working
sylvain.thenault@logilab.fr
parents: 874
diff changeset
  1041
        w(tags.input(type='hidden', name='__form_id', value=form.domid))
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
  1042
        if form.redirect_path:
887
51e371245bc5 various fixes to have change state and deletion forms working
sylvain.thenault@logilab.fr
parents: 874
diff changeset
  1043
            w(tags.input(type='hidden', name='__redirectpath', value=form.redirect_path))
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
  1044
        self.render_fields(w, form, values, display_help)
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
  1045
        self.render_buttons(w, form)
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
  1046
        w(u'</fieldset>')
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
  1047
        w(u'</form>')
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
  1048
        return '\n'.join(data)
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
  1049
        
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
  1050
    def render_label(self, form, field):
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
  1051
        label = form.req._(field.label)
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
  1052
        attrs = {'for': form.context[field]['id']}
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
  1053
        if field.required:
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
  1054
            attrs['class'] = 'required'
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
  1055
        return tags.label(label, **attrs)
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
  1056
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
  1057
    def render_help(self, form, field):
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
  1058
        help = [ u'<br/>' ]
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
  1059
        descr = field.help
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
  1060
        if descr:
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
  1061
            help.append('<span class="helper">%s</span>' % req._(descr))
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
  1062
        example = field.example_format(form.req)
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
  1063
        if example:
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
  1064
            help.append('<span class="helper">(%s: %s)</span>'
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
  1065
                        % (req._('sample format'), example))
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
  1066
        return u'&nbsp;'.join(help)
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
  1067
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
  1068
    # specific methods (mostly to ease overriding) #############################
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
  1069
    
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1070
    def open_form(self, form):
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1071
        if form.form_needs_multipart:
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1072
            enctype = 'multipart/form-data'
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1073
        else:
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1074
            enctype = 'application/x-www-form-urlencoded'
1009
bcd0c3ae1935 typos, backport comment
sylvain.thenault@logilab.fr
parents: 944
diff changeset
  1075
        tag = ('<form action="%s" method="post" id="%s" enctype="%s"' % (
887
51e371245bc5 various fixes to have change state and deletion forms working
sylvain.thenault@logilab.fr
parents: 874
diff changeset
  1076
            html_escape(form.action or '#'), form.domid, enctype))
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1077
        if form.onsubmit:
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1078
            tag += ' onsubmit="%s"' % html_escape(form.onsubmit)
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1079
        if form.cssstyle:
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1080
            tag += ' style="%s"' % html_escape(form.cssstyle)
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1081
        if form.cssclass:
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1082
            tag += ' class="%s"' % html_escape(form.cssclass)
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1083
        if form.cwtarget:
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1084
            tag += ' cubicweb:target="%s"' % html_escape(form.cwtarget)
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1085
        return tag + '>'
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1086
        
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
  1087
    def render_fields(self, w, form, values, display_help=True):
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1088
        form.form_build_context(values)
863
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
  1089
        fields = form.fields[:]
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
  1090
        for field in form.fields:
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
  1091
            if not field.is_visible():
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
  1092
                w(field.render(form, self))
863
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
  1093
                fields.remove(field)
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1094
        if fields:
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1095
            w(u'<table>')
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1096
            for field in fields:
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1097
                w(u'<tr>')
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1098
                w('<th>%s</th>' % self.render_label(form, field))
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1099
                w(u'<td style="width:100%;">')
907
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
  1100
                w(field.render(form, self))
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
  1101
                if display_help == True:
192800415f59 FileField backport
sylvain.thenault@logilab.fr
parents: 905
diff changeset
  1102
                    w(self.render_help(form, field))
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1103
                w(u'</td></tr>')
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1104
            w(u'</table>')
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1105
        for childform in getattr(form, 'forms', []):
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1106
            self.render_fields(w, childform, values)
892
1558772340a7 rich field / fckeditor handling
sylvain.thenault@logilab.fr
parents: 888
diff changeset
  1107
        
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
  1108
    def render_buttons(self, w, form):
896
6e0379fc1988 put form buttons in a separate table
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 894
diff changeset
  1109
        w(u'<table class="formButtonBar">\n<tr>\n')
869
168ad6d424d1 form to edit multiple entities, use it in DeleteConfForm
sylvain.thenault@logilab.fr
parents: 867
diff changeset
  1110
        for button in form.form_buttons():
896
6e0379fc1988 put form buttons in a separate table
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 894
diff changeset
  1111
            w(u'<td>%s</td>\n' % button)
6e0379fc1988 put form buttons in a separate table
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 894
diff changeset
  1112
        w(u'</tr></table>')
897
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1113
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1114
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1115
def stringfield_from_constraints(constraints, **kwargs):
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1116
    field = None
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1117
    for cstr in constraints:
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1118
        if isinstance(cstr, StaticVocabularyConstraint):
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1119
            return StringField(widget=Select(vocabulary=cstr.vocabulary),
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1120
                               **kwargs)
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1121
        if isinstance(cstr, SizeConstraint) and cstr.max is not None:
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1122
            if cstr.max > 257:
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1123
                field = textfield_from_constraint(cstr, **kwargs)
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1124
            else:
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1125
                field = StringField(max_length=cstr.max, **kwargs)
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1126
    return field or TextField(**kwargs)
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
  1127
        
897
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1128
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1129
def textfield_from_constraint(constraint, **kwargs):
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1130
    if 256 < constraint.max < 513:
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1131
        rows, cols = 5, 60
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1132
    else:
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1133
        rows, cols = 10, 80
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1134
    return TextField(rows, cols, **kwargs)
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1135
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1136
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1137
def find_field(eclass, subjschema, rschema, role='subject'):
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1138
    """return the most adapated widget to edit the relation
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1139
    'subjschema rschema objschema' according to information found in the schema
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1140
    """
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1141
    fieldclass = None
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1142
    if role == 'subject':
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1143
        objschema = rschema.objects(subjschema)[0]
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1144
        cardidx = 0
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1145
    else:
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1146
        objschema = rschema.subjects(subjschema)[0]
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1147
        cardidx = 1
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1148
    card = rschema.rproperty(subjschema, objschema, 'cardinality')[cardidx]
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1149
    required = card in '1+'
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1150
    if rschema in eclass.widgets:
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1151
        fieldclass = eclass.widgets[rschema]
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1152
        if isinstance(fieldclass, basestring):
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1153
            return StringField(name=rschema.type)
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1154
    elif not rschema.is_final():
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1155
        return RelationField.fromcardinality(card, role,name=rschema.type,
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1156
                                             required=required)
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1157
    else:
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1158
        fieldclass = FIELDS[objschema]
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1159
    if fieldclass is StringField:
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1160
        constraints = rschema.rproperty(subjschema, objschema, 'constraints')
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1161
        return stringfield_from_constraints(constraints, name=rschema.type,
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1162
                                            required=required)
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1163
    return fieldclass(name=rschema.type, required=required)
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1164
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1165
FIELDS = {
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1166
    'Boolean':  BooleanField,
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1167
    'Bytes':    FileField,
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1168
    'Date':     DateField,
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1169
    'Datetime': DateTimeField,
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1170
    'Int':      IntField,
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1171
    'Float':    FloatField,
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1172
    'Decimal':  StringField,
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1173
    'Password': StringField,
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1174
    'String' :  StringField,
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1175
    'Time':     TimeField,
f5b91f11d8b6 provide basic methods to build fields from schema constraints / cardinality
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 896
diff changeset
  1176
    }