web/form.py
author Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
Thu, 19 Feb 2009 21:36:39 +0100
branchtls-sprint
changeset 865 90a1aea85637
parent 864 e0947007542a
child 867 14a79faa3a56
permissions -rw-r--r--
DatePicker widget
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
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    10
from simplejson import dumps
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    11
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    12
from logilab.common.compat import any
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    13
from logilab.mtconverter import html_escape
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    14
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    15
from cubicweb import typed_eid
692
800592b8d39b replace deprecated cubicweb.common.selectors by its new module path (cubicweb.selectors)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 431
diff changeset
    16
from cubicweb.selectors import match_form_params
751
ec16f43107d3 update import
sylvain.thenault@logilab.fr
parents: 692
diff changeset
    17
from cubicweb.view import NOINDEX, NOFOLLOW, View, EntityView, AnyRsetView
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    18
from cubicweb.common.registerers import accepts_registerer
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    19
from cubicweb.web import stdmsgs
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    20
from cubicweb.web.httpcache import NoHTTPCacheManager
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    21
from cubicweb.web.controller import redirect_params
863
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
    22
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
    23
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    24
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    25
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    26
def relation_id(eid, rtype, target, reid):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    27
    if target == 'subject':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    28
        return u'%s:%s:%s' % (eid, rtype, reid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    29
    return u'%s:%s:%s' % (reid, rtype, eid)
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    30
        
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    31
def toggable_relation_link(eid, nodeid, label='x'):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    32
    js = u"javascript: togglePendingDelete('%s', %s);" % (nodeid, html_escape(dumps(eid)))
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
    33
    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
    34
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    35
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    36
class FormMixIn(object):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    37
    """abstract form mix-in"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    38
    category = 'form'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    39
    controller = 'edit'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    40
    domid = 'entityForm'
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
    http_cache_manager = NoHTTPCacheManager
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    43
    add_to_breadcrumbs = False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    44
    skip_relations = set()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    45
    
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    46
    def __init__(self, req, rset):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    47
        super(FormMixIn, self).__init__(req, rset)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    48
        self.maxrelitems = self.req.property_value('navigation.related-limit')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    49
        self.maxcomboitems = self.req.property_value('navigation.combobox-limit')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    50
        self.force_display = not not req.form.get('__force_display')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    51
        # get validation session data which may have been previously set.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    52
        # deleting validation errors here breaks form reloading (errors are
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    53
        # no more available), they have to be deleted by application's publish
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    54
        # method on successful commit
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    55
        formurl = req.url()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    56
        forminfo = req.get_session_data(formurl)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    57
        if forminfo:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    58
            req.data['formvalues'] = forminfo['values']
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    59
            req.data['formerrors'] = errex = forminfo['errors']
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    60
            req.data['displayederrors'] = set()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    61
            # if some validation error occured on entity creation, we have to
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    62
            # get the original variable name from its attributed eid
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    63
            foreid = errex.entity
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    64
            for var, eid in forminfo['eidmap'].items():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    65
                if foreid == eid:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    66
                    errex.eid = var
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    67
                    break
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    68
            else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    69
                errex.eid = foreid
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    70
        
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    71
    def html_headers(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    72
        """return a list of html headers (eg something to be inserted between
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    73
        <head> and </head> of the returned page
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    74
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    75
        by default forms are neither indexed nor followed
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    76
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    77
        return [NOINDEX, NOFOLLOW]
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 linkable(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    80
        """override since forms are usually linked by an action,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    81
        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
    82
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    83
        return False
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
    @property
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    86
    def limit(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    87
        if self.force_display:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    88
            return None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    89
        return self.maxrelitems + 1
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
    def need_multipart(self, entity, categories=('primary', 'secondary')):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    92
        """return a boolean indicating if form's enctype should be multipart
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    93
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    94
        for rschema, _, x in entity.relations_by_category(categories):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    95
            if entity.get_widget(rschema, x).need_multipart:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    96
                return True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    97
        # let's find if any of our inlined entities needs multipart
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    98
        for rschema, targettypes, x in entity.relations_by_category('inlineview'):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    99
            assert len(targettypes) == 1, \
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   100
                   "I'm not able to deal with several targets and inlineview"
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   101
            ttype = targettypes[0]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   102
            inlined_entity = self.vreg.etype_class(ttype)(self.req, None, None)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   103
            for irschema, _, x in inlined_entity.relations_by_category(categories):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   104
                if inlined_entity.get_widget(irschema, x).need_multipart:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   105
                    return True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   106
        return False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   107
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   108
    def error_message(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   109
        """return formatted error message
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   110
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   111
        This method should be called once inlined field errors has been consumed
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   112
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   113
        errex = self.req.data.get('formerrors')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   114
        # get extra errors
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   115
        if errex is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   116
            errormsg = self.req._('please correct the following errors:')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   117
            displayed = self.req.data['displayederrors']
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   118
            errors = sorted((field, err) for field, err in errex.errors.items()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   119
                            if not field in displayed)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   120
            if errors:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   121
                if len(errors) > 1:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   122
                    templstr = '<li>%s</li>\n' 
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   123
                else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   124
                    templstr = '&nbsp;%s\n'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   125
                for field, err in errors:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   126
                    if field is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   127
                        errormsg += templstr % err
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   128
                    else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   129
                        errormsg += templstr % '%s: %s' % (self.req._(field), err)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   130
                if len(errors) > 1:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   131
                    errormsg = '<ul>%s</ul>' % errormsg
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   132
            return u'<div class="errorMessage">%s</div>' % errormsg
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   133
        return u''
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   134
    
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   135
    def restore_pending_inserts(self, entity, cell=False):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   136
        """used to restore edition page as it was before clicking on
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   137
        'search for <some entity type>'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   138
        
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   139
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   140
        eid = entity.eid
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   141
        cell = cell and "div_insert_" or "tr"
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   142
        pending_inserts = set(self.req.get_pending_inserts(eid))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   143
        for pendingid in pending_inserts:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   144
            eidfrom, rtype, eidto = pendingid.split(':')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   145
            if typed_eid(eidfrom) == entity.eid: # subject
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   146
                label = display_name(self.req, rtype, 'subject')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   147
                reid = eidto
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   148
            else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   149
                label = display_name(self.req, rtype, 'object')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   150
                reid = eidfrom
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   151
            jscall = "javascript: cancelPendingInsert('%s', '%s', null, %s);" \
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   152
                     % (pendingid, cell, eid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   153
            rset = self.req.eid_rset(reid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   154
            eview = self.view('text', rset, row=0)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   155
            # XXX find a clean way to handle baskets
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   156
            if rset.description[0][0] == 'Basket':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   157
                eview = '%s (%s)' % (eview, display_name(self.req, 'Basket'))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   158
            yield rtype, pendingid, jscall, label, reid, eview
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   159
        
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   160
    
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   161
    def force_display_link(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   162
        return (u'<span class="invisible">' 
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   163
                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
   164
                u'</span>' % self.req._('view all'))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   165
    
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   166
    def relations_table(self, entity):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   167
        """yiels 3-tuples (rtype, target, related_list)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   168
        where <related_list> itself a list of :
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   169
          - node_id (will be the entity element's DOM id)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   170
          - appropriate javascript's togglePendingDelete() function call
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   171
          - status 'pendingdelete' or ''
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   172
          - oneline view of related entity
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
        eid = entity.eid
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   175
        pending_deletes = self.req.get_pending_deletes(eid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   176
        # XXX (adim) : quick fix to get Folder relations
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   177
        for label, rschema, target in entity.srelations_by_category(('generic', 'metadata'), 'add'):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   178
            if rschema in self.skip_relations:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   179
                continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   180
            relatedrset = entity.related(rschema, target, limit=self.limit)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   181
            toggable_rel_link = self.toggable_relation_link_func(rschema)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   182
            related = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   183
            for row in xrange(relatedrset.rowcount):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   184
                nodeid = relation_id(eid, rschema, target, relatedrset[row][0])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   185
                if nodeid in pending_deletes:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   186
                    status = u'pendingDelete'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   187
                    label = '+'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   188
                else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   189
                    status = u''
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   190
                    label = 'x'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   191
                dellink = toggable_rel_link(eid, nodeid, label)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   192
                eview = self.view('oneline', relatedrset, row=row)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   193
                related.append((nodeid, dellink, status, eview))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   194
            yield (rschema, target, related)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   195
        
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   196
    def toggable_relation_link_func(self, rschema):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   197
        if not rschema.has_perm(self.req, 'delete'):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   198
            return lambda x, y, z: u''
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   199
        return toggable_relation_link
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   200
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   201
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   202
    def redirect_url(self, entity=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   203
        """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
   204
        specified in current form params, else return the result the reset_url
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   205
        method which should be defined in concrete classes
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   206
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   207
        rparams = redirect_params(self.req.form)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   208
        if rparams:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   209
            return self.build_url('view', **rparams)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   210
        return self.reset_url(entity)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   211
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   212
    def reset_url(self, entity):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   213
        raise NotImplementedError('implement me 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
    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
   216
    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
   217
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   218
    def button_ok(self, label=None, tabindex=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   219
        label = self.req._(label or stdmsgs.BUTTON_OK).capitalize()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   220
        return self.BUTTON_STR % ('defaultsubmit', label, tabindex or 2)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   221
    
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   222
    def button_apply(self, label=None, tabindex=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   223
        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
   224
        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
   225
                                         label, tabindex or 3)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   226
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   227
    def button_delete(self, label=None, tabindex=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   228
        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
   229
        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
   230
                                         label, tabindex or 3)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   231
    
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   232
    def button_cancel(self, label=None, tabindex=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   233
        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
   234
        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
   235
                                         label, tabindex or 4)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   236
    
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   237
    def button_reset(self, label=None, tabindex=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   238
        label = self.req._(label or stdmsgs.BUTTON_CANCEL).capitalize()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   239
        return u'<input class="validateButton" type="reset" value="%s" tabindex="%s"/>' % (
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   240
            label, tabindex or 4)
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   241
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   242
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   243
###############################################################################
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   244
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   245
from cubicweb.common import tags
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   246
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   247
# widgets ############
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   248
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   249
class FieldWidget(object):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   250
    def __init__(self, attrs=None):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   251
        self.attrs = attrs or {}
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
    def render(self, form, field):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   254
        raise NotImplementedError
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   255
    
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   256
class Input(FieldWidget):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   257
    type = None
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   258
    
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   259
    def render(self, form, field):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   260
        name, value, attrs = self._render_attrs(form, field)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   261
        if attrs is None:
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   262
            return tags.input(name=name, value=value)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   263
        return tags.input(name=name, value=value, type=self.type, **attrs)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   264
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   265
    def _render_attrs(self, form, field):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   266
        name = form.context[field]['name'] # qualified name
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   267
        value = form.context[field]['value']
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   268
        #fattrs = field.widget_attributes(self)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   269
        attrs = self.attrs.copy()
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   270
        #attrs.update(fattrs)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   271
        # XXX id
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   272
        return name, value, attrs
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   273
    
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   274
class TextInput(Input):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   275
    type = 'text'
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   276
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   277
class PasswordInput(Input):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   278
    type = 'password'
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   279
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   280
class FileInput(Input):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   281
    type = 'file'
864
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   282
    
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   283
    def _render_attrs(self, form, field):
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   284
        name = form.context[field]['name'] # qualified name
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   285
        return name, None, {}
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   286
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   287
class HiddenInput(Input):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   288
    type = 'hidden'
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   289
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   290
class Button(Input):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   291
    type = 'button'
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   292
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   293
class TextArea(FieldWidget):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   294
    def render(self, form, field):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   295
        name, value, attrs = self._render_attrs(form, field)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   296
        if attrs is None:
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   297
            return tags.textarea(value, name=name)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   298
        return tags.textarea(value, name=name, **attrs)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   299
864
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   300
class Select(FieldWidget):
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   301
    def __init__(self, vocabulary=()):
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   302
        self.vocabulary = ()
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   303
        
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   304
    def render(self, form, field):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   305
        name, value, attrs = self._render_attrs(form, field)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   306
        if self.vocabulary:
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   307
            # static vocabulary defined in form definition
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   308
            vocab = self.vocabulary
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   309
        else:
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   310
            vocab = form.get_vocabulary(field)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   311
        options = []
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   312
        for label, value in vocab:
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   313
            options.append(tags.option(label, value=value))
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   314
        if attrs is None:
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   315
            return tags.select(name=name, options=options)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   316
        return tags.select(name=name, options=options, **attrs)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   317
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   318
864
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   319
class CheckBox(FieldWidget):
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   320
865
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   321
    def _render_attrs(self, form, field):
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   322
        name, value, attrs = super(CheckBox, self)._render_attrs(form, field)
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   323
        if value:
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   324
            attrs['checked'] = u'checked'
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   325
        return name, None, attrs
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   326
        
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   327
class Radio(FieldWidget):
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   328
    pass
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   329
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   330
class DateTimePicker(TextInput):
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   331
    monthnames = ("january", "february", "march", "april",
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   332
                  "may", "june", "july", "august",
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   333
                  "september", "october", "november", "december")
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   334
    
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   335
    daynames = ("monday", "tuesday", "wednesday", "thursday",
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   336
                "friday", "saturday", "sunday")
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   337
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   338
    @classmethod
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   339
    def add_localized_infos(cls, req):
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   340
        """inserts JS variables defining localized months and days"""
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   341
        # import here to avoid dependancy from cubicweb-common to simplejson
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   342
        _ = req._
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   343
        monthnames = [_(mname) for mname in cls.monthnames]
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   344
        daynames = [_(dname) for dname in cls.daynames]
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   345
        req.html_headers.define_var('MONTHNAMES', monthnames)
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   346
        req.html_headers.define_var('DAYNAMES', daynames)
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   347
    
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   348
    def render(self, form, field):
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   349
        txtwidget = super(DateTimePicker, self).render(form, field)
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   350
        cal_button - self._render_calendar_popup(form, field)
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   351
        return txtwidget + cal_button
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   352
    
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   353
    def _render_calendar_popup(self, form, field):
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   354
        req = form.req
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   355
        name, value, attrs = self._render_attrs(form, field)
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   356
        helperid = '%shelper' % name
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   357
        if not value:
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   358
            value = _today()
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   359
        year, month = value.year, value.month
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   360
        onclick = "toggleCalendar('%s', '%s', %s, %s);" % (
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   361
            helperid, name, year, month)
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   362
        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
   363
<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
   364
                % (helperid, inputid, year, month,
90a1aea85637 DatePicker widget
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 864
diff changeset
   365
                   self.iconurl, req._('calendar'), helperid) )
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   366
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   367
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   368
# fields ############
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   369
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   370
class Field(object):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   371
    """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
   372
    """
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   373
    widget = TextInput
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   374
    needs_multipart = False
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   375
    creation_rank = 0
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
    def __init__(self, name=None, id=None, label=None,
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   378
                 widget=None, required=False, initial=None, help=None,
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   379
                 eidparam=True):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   380
        self.required = required
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   381
        if widget is not None:
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   382
            self.widget = widget
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   383
        if isinstance(self.widget, type):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   384
            self.widget = self.widget()
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   385
        self.name = name
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   386
        self.label = label or name
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   387
        self.id = id or name
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   388
        self.initial = initial
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   389
        self.help = help
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   390
        self.eidparam = eidparam
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   391
        # global fields ordering in forms
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   392
        Field.creation_rank += 1
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   393
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   394
    def set_name(self, name):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   395
        self.name = name
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   396
        if not self.id:
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   397
            self.id = name
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   398
        if not self.label:
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   399
            self.label = name
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   400
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   401
    def format_value(self, req, value):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   402
        return unicode(value)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   403
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   404
    def render(self, form):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   405
        return self.widget.render(form, self)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   406
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   407
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   408
class StringField(Field):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   409
    def __init__(self, max_length=None, **kwargs):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   410
        super(StringField, self).__init__(**kwargs)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   411
        self.max_length = max_length
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   412
        
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   413
class TextField(Field):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   414
    widget = TextArea
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   415
    def __init__(self, row=None, col=None, **kwargs):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   416
        super(TextField, self).__init__(**kwargs)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   417
        self.row = row
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   418
        self.col = col
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   419
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   420
class RichTextField(Field):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   421
    pass
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   422
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   423
class IntField(Field):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   424
    def __init__(self, min=None, max=None, **kwargs):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   425
        super(IntField, self).__init__(**kwargs)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   426
        self.min = min
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   427
        self.max = max
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   428
864
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   429
class FloatField(IntField):    
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   430
    def format_value(self, req, value):
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   431
        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
   432
        if value is None:
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   433
            return u''
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   434
        return formatstr % float(value)
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   435
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   436
class DateField(StringField):
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   437
    propname = 'ui.date-format'
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   438
    
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   439
    def format_value(self, req, value):
864
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   440
        return value and ustrftime(value, req.property_value(self.propname)) or u''
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   441
864
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   442
class DateTimeField(DateField):
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   443
    propname = 'ui.datetime-format'
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   444
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   445
    
864
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   446
class FileField(StringField):
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   447
    needs_multipart = True
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   448
863
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   449
class HiddenInitialValueField(Field):
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   450
    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
   451
        super(HiddenInitialValueField, self).__init__(name=name,
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   452
                                                      widget=HiddenInput)
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   453
        self.visible_field = visible_field
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   454
                 
863
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   455
class RelationField(Field):
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   456
    def __init__(self, role='subject', **kwargs):
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   457
        super(RelationField, self).__init__(**kwargs)
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   458
        self.role = role
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   459
        
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   460
# forms ############
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   461
class metafieldsform(type):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   462
    def __new__(mcs, name, bases, classdict):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   463
        allfields = []
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   464
        for base in bases:
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   465
            if hasattr(base, '_fields_'):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   466
                allfields += base._fields_
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   467
        clsfields = (item for item in classdict.items()
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   468
                     if isinstance(item[1], Field))
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   469
        for name, field in sorted(clsfields, key=lambda x: x[1].creation_rank):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   470
            if not field.name:
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   471
                field.set_name(name)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   472
            allfields.append(field)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   473
        classdict['_fields_'] = allfields
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   474
        return super(metafieldsform, mcs).__new__(mcs, name, bases, classdict)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   475
    
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   476
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   477
class FieldsForm(object):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   478
    __metaclass__ = metafieldsform
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   479
    
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   480
    def __init__(self, req, id=None, title=None, action='edit',
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   481
                 redirect_path=None):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   482
        self.req = req
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   483
        self.id = id or 'form'
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   484
        self.title = title
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   485
        self.action = action
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   486
        self.redirect_path = None
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   487
        self.fields = list(self.__class__._fields_)
848
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   488
        self.fields.append(TextField(name='__errorurl', widget=HiddenInput,
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   489
                                     initial=req.url()))
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   490
        self.context = {}
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   491
        
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   492
    @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
   493
    def form_needs_multipart(self):
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   494
        return any(field.needs_multipart for field in self.fields) 
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   495
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
   496
    def form_render(self, **values):
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   497
        renderer = values.pop('renderer', FormRenderer())
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
   498
        self.form_build_context(values)
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   499
        return renderer.render(self)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   500
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
   501
    def form_build_context(self, values):
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   502
        self.context = context = {}
849
8591d896db7e update some prototype, ChangeStateForm
sylvain.thenault@logilab.fr
parents: 848
diff changeset
   503
        # on validation error, we get a dictionnary of previously submitted values
8591d896db7e update some prototype, ChangeStateForm
sylvain.thenault@logilab.fr
parents: 848
diff changeset
   504
        previous_values = self.req.data.get('formvalues')
8591d896db7e update some prototype, ChangeStateForm
sylvain.thenault@logilab.fr
parents: 848
diff changeset
   505
        if previous_values:
8591d896db7e update some prototype, ChangeStateForm
sylvain.thenault@logilab.fr
parents: 848
diff changeset
   506
            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
   507
        for field in self.fields:
863
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   508
            context[field] = {'value': self.form_field_value(field, values),
849
8591d896db7e update some prototype, ChangeStateForm
sylvain.thenault@logilab.fr
parents: 848
diff changeset
   509
                              'name': self.form_field_name(field),
8591d896db7e update some prototype, ChangeStateForm
sylvain.thenault@logilab.fr
parents: 848
diff changeset
   510
                              'id': self.form_field_id(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
   511
                              }
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
   512
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
   513
    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
   514
        """looks for field's value in
849
8591d896db7e update some prototype, ChangeStateForm
sylvain.thenault@logilab.fr
parents: 848
diff changeset
   515
        1. kw args given to render_form (including previously submitted form
8591d896db7e update some prototype, ChangeStateForm
sylvain.thenault@logilab.fr
parents: 848
diff changeset
   516
           values if any)
848
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   517
        2. req.form
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   518
        3. field's initial value
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   519
        """
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   520
        if field.name in values:
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   521
            value = values[field.name]
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   522
        elif field.name in self.req.form:
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   523
            value = self.req.form[field.name]
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   524
        else:
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   525
            value = field.initial
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
   526
        return field.format_value(self.req, value) 
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
   527
849
8591d896db7e update some prototype, ChangeStateForm
sylvain.thenault@logilab.fr
parents: 848
diff changeset
   528
    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
   529
        return field.name
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   530
849
8591d896db7e update some prototype, ChangeStateForm
sylvain.thenault@logilab.fr
parents: 848
diff changeset
   531
    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
   532
        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
   533
   
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
   534
    def form_field_vocabulary(self, field):
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   535
        raise NotImplementedError
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
   536
    
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
   537
    BUTTON_STR = u'<input class="validateButton" type="submit" name="%s" value="%s" tabindex="%s"/>'
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
   538
    ACTION_SUBMIT_STR = u'<input class="validateButton" type="button" onclick="postForm(\'%s\', \'%s\', \'%s\')" value="%s" tabindex="%s"/>'
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
   539
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
   540
    def button_ok(self, label=None, tabindex=None):
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
   541
        label = self.req._(label or stdmsgs.BUTTON_OK).capitalize()
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
   542
        return self.BUTTON_STR % ('defaultsubmit', label, tabindex or 2)
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
   543
    
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
   544
    def button_apply(self, label=None, tabindex=None):
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
   545
        label = self.req._(label or stdmsgs.BUTTON_APPLY).capitalize()
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
   546
        return self.ACTION_SUBMIT_STR % ('__action_apply', label, self.id, label, tabindex or 3)
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
   547
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
   548
    def button_delete(self, label=None, tabindex=None):
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
   549
        label = self.req._(label or stdmsgs.BUTTON_DELETE).capitalize()
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
   550
        return self.ACTION_SUBMIT_STR % ('__action_delete', label, self.id, label, tabindex or 3)
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
   551
    
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
   552
    def button_cancel(self, label=None, tabindex=None):
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
   553
        label = self.req._(label or stdmsgs.BUTTON_CANCEL).capitalize()
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
   554
        return self.ACTION_SUBMIT_STR % ('__action_cancel', label, self.id, label, tabindex or 4)
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
   555
    
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
   556
    def button_reset(self, label=None, tabindex=None):
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
   557
        label = self.req._(label or stdmsgs.BUTTON_CANCEL).capitalize()
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
   558
        return u'<input class="validateButton" type="reset" value="%s" tabindex="%s"/>' % (
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
   559
            label, tabindex or 4)
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   560
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   561
    
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   562
class EntityFieldsForm(FieldsForm):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   563
    def __init__(self, *args, **kwargs):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   564
        kwargs.setdefault('id', 'entityForm')
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   565
        super(EntityFieldsForm, self).__init__(*args, **kwargs)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   566
        self.fields.append(TextField(name='__type', widget=HiddenInput))
864
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   567
        self.fields.append(TextField(name='eid', widget=HiddenInput,
e0947007542a basic implementation of Date / Float fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 863
diff changeset
   568
                                     eidparam=False))
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   569
        
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
   570
    def form_render(self, entity, **values):
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   571
        self.entity = entity
863
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   572
        eschema = self.entity.e_schema
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   573
        for field in self.fields[:]:
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   574
            fieldname = field.name
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   575
            if fieldname != 'eid' and (
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   576
                (eschema.has_subject_relation(fieldname) or
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   577
                eschema.has_object_relation(fieldname))):
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   578
                self.fields.append(self.build_hidden_field(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
   579
        return super(EntityFieldsForm, self).form_render(**values)
863
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   580
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   581
    def build_hidden_field(self, field):
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   582
        """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
   583
        before the modification
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   584
        """
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   585
        # 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
   586
        # to describe attribute fields => role is 'subject'
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   587
        role = getattr(field, 'role', 'subject')
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   588
        if role == 'subject':
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   589
            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
   590
        else:
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   591
            name = 'edito-%s' % field.name
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   592
        return HiddenInitialValueField(field, name=name)
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   593
    
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
   594
    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
   595
        """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
   596
        1. handle special __type and eid fields
849
8591d896db7e update some prototype, ChangeStateForm
sylvain.thenault@logilab.fr
parents: 848
diff changeset
   597
        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
   598
           form values if any)
848
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   599
        3. looks in req.form
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   600
        4. if entity has an eid:
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   601
             1. looks for an associated attribute / method
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   602
             2. use field's initial value
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   603
           else:
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   604
             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
   605
             2. use field's initial value
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   606
             
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   607
        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
   608
        """
863
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   609
        fieldname = field.name
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   610
        if fieldname.startswith('edits-') or fieldname.startswith('edito-'):
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   611
            value = self.form_field_value(field.visible_field, values)
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   612
            if value is None or not self.entity.has_eid():
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   613
                value = INTERNAL_FIELD_VALUE
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   614
        elif fieldname == '__type':
848
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   615
            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
   616
        elif fieldname == 'eid':
848
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   617
            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
   618
        elif fieldname in values:
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   619
            value = values[fieldname]
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   620
        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
   621
            value = self.req.form[fieldname]
848
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   622
        else:
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   623
            if self.entity.has_eid():
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   624
                # 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
   625
                # 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
   626
                # undesired value)
863
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   627
                value = getattr(self.entity, fieldname, field.initial)
848
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   628
            else:
863
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   629
                defaultattr = 'default_%s' % fieldname
848
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   630
                if hasattr(self.entity, defaultattr):
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   631
                    # 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
   632
                    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
   633
                         % (defaultattr, self.entity.id), DeprecationWarning)
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   634
                    value = getattr(self.entity, defaultattr)
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   635
                elif hasattr(self, defaultattr):
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   636
                    # 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
   637
                    value = getattr(self, defaultattr)
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   638
                else:
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   639
                    # use field's initial value
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   640
                    value = field.initial
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   641
            if callable(value):
f5aca5c5f6ca set __errorurl, fix retreiving of field's value
sylvain.thenault@logilab.fr
parents: 847
diff changeset
   642
                values = value()
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
   643
        return field.format_value(self.req, value) 
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   644
849
8591d896db7e update some prototype, ChangeStateForm
sylvain.thenault@logilab.fr
parents: 848
diff changeset
   645
    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
   646
        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
   647
            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
   648
        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
   649
849
8591d896db7e update some prototype, ChangeStateForm
sylvain.thenault@logilab.fr
parents: 848
diff changeset
   650
    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
   651
        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
   652
            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
   653
        return field.id
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   654
        
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
   655
    def form_field_vocabulary(self, field):
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   656
        choices = self.vocabfunc(entity)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   657
        if self.sort:
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   658
            choices = sorted(choices)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   659
        if self.rschema.rproperty(self.subjtype, self.objtype, 'internationalizable'):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   660
            return zip((entity.req._(v) for v in choices), choices)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   661
        return zip(choices, choices)
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   662
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   663
    
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   664
# form renderers ############
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   665
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   666
class FormRenderer(object):
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
   667
    
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   668
    def render(self, form):
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   669
        data = []
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   670
        w = data.append
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
   671
        # XXX form_needs_multipart
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   672
        w(u'<form action="%s" onsubmit="return freezeFormButtons(\'%s\');" method="post" id="%s">'
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   673
          % (form.req.build_url(form.action), form.id, form.id))
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   674
        w(u'<div id="progress">%s</div>' % _('validating...'))
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   675
        w(u'<fieldset>')
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   676
        w(tags.input(type='hidden', name='__form_id', value=form.id))
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   677
        if form.redirect_path:
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   678
            w(tags.input(type='hidden', name='__redirect_path', value=form.redirect_path))
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
   679
        self.render_fields(w, form)
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
   680
        self.render_buttons(w, form)
844
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   681
        w(u'</fieldset>')
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   682
        w(u'</form>')
8ab6f64c3750 start django like forms
sylvain.thenault@logilab.fr
parents: 765
diff changeset
   683
        return '\n'.join(data)
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
   684
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
   685
    def render_fields(self, w, form):
863
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   686
        fields = form.fields[:]
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   687
        for field in form.fields:
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   688
            if isinstance(field.widget, HiddenInput):
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   689
                w(field.render(form))
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   690
                fields.remove(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
   691
        w(u'<table>')
863
4fde01fc39ca restore previous hidden input behaviour (edits- / edito- fields)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 849
diff changeset
   692
        for field in fields:
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
   693
            w(u'<tr>')
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
   694
            w('<th>%s</th>' % self.render_label(form, field))
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
   695
            w(u'<td style="width:100%;">')
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
   696
            w(field.render(form))
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
   697
            w(u'</td></tr>')
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
   698
        w(u'</table>')
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
   699
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
   700
    def render_buttons(self, w, form):
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
   701
        for button in form.buttons():
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
   702
            w(button)
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
   703
        
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
   704
    def render_label(self, form, field):
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
   705
        label = form.req._(field.label)
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
   706
        attrs = {'for': form.context[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
   707
        if field.required:
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
   708
            attrs['class'] = 'required'
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
   709
        return tags.label(label, **attrs)
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
   710