web/formfields.py
author Pierre-Yves David <pierre-yves.david@logilab.fr>
Tue, 08 Dec 2009 18:12:31 +0100
changeset 4069 5d149ba65dd0
parent 4044 3876c894e018
child 4101 7fa86fa51229
permissions -rw-r--r--
fix guess_field to handle non internationalizable definition
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
     1
"""field classes for form construction
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
     2
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
     3
:organization: Logilab
1977
606923dff11b big bunch of copyright / docstring update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1858
diff changeset
     4
:copyright: 2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
     5
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
1977
606923dff11b big bunch of copyright / docstring update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1858
diff changeset
     6
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
     7
"""
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
     8
__docformat__ = "restructuredtext en"
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
     9
2244
52e2431e7cce missing import
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2196
diff changeset
    10
from warnings import warn
1095
6917ebe281e9 test and fix guess_field, some pylint fixes
sylvain.thenault@logilab.fr
parents: 1081
diff changeset
    11
from datetime import datetime
6917ebe281e9 test and fix guess_field, some pylint fixes
sylvain.thenault@logilab.fr
parents: 1081
diff changeset
    12
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2244
diff changeset
    13
from logilab.mtconverter import xml_escape
2459
d088d0ff48a1 move RichString and co to yams, keeping only a small monkeypatch for cw-page-template here
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2362
diff changeset
    14
from yams.constraints import (SizeConstraint, StaticVocabularyConstraint,
d088d0ff48a1 move RichString and co to yams, keeping only a small monkeypatch for cw-page-template here
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2362
diff changeset
    15
                              FormatConstraint)
1095
6917ebe281e9 test and fix guess_field, some pylint fixes
sylvain.thenault@logilab.fr
parents: 1081
diff changeset
    16
2678
0308dc159b96 use yams api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2568
diff changeset
    17
from cubicweb.utils import ustrftime
4023
eae23c40627a drop common subpackage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4014
diff changeset
    18
from cubicweb import tags, uilib
1095
6917ebe281e9 test and fix guess_field, some pylint fixes
sylvain.thenault@logilab.fr
parents: 1081
diff changeset
    19
from cubicweb.web import INTERNAL_FIELD_VALUE
1265
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    20
from cubicweb.web.formwidgets import (
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    21
    HiddenInput, TextInput, FileInput, PasswordInput, TextArea, FCKEditor,
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1417
diff changeset
    22
    Radio, Select, DateTimePicker)
1095
6917ebe281e9 test and fix guess_field, some pylint fixes
sylvain.thenault@logilab.fr
parents: 1081
diff changeset
    23
1986
96c0e56cb0cf move widget selection's logic on fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    24
3334
8d831c02da9a fix sort of fields vocabulary: should consider option groups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3308
diff changeset
    25
def vocab_sort(vocab):
8d831c02da9a fix sort of fields vocabulary: should consider option groups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3308
diff changeset
    26
    """sort vocabulary, considering option groups"""
8d831c02da9a fix sort of fields vocabulary: should consider option groups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3308
diff changeset
    27
    result = []
8d831c02da9a fix sort of fields vocabulary: should consider option groups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3308
diff changeset
    28
    partresult = []
8d831c02da9a fix sort of fields vocabulary: should consider option groups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3308
diff changeset
    29
    for label, value in vocab:
8d831c02da9a fix sort of fields vocabulary: should consider option groups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3308
diff changeset
    30
        if value is None: # opt group start
8d831c02da9a fix sort of fields vocabulary: should consider option groups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3308
diff changeset
    31
            if partresult:
8d831c02da9a fix sort of fields vocabulary: should consider option groups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3308
diff changeset
    32
                result += sorted(partresult)
8d831c02da9a fix sort of fields vocabulary: should consider option groups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3308
diff changeset
    33
                partresult = []
8d831c02da9a fix sort of fields vocabulary: should consider option groups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3308
diff changeset
    34
            result.append( (label, value) )
8d831c02da9a fix sort of fields vocabulary: should consider option groups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3308
diff changeset
    35
        else:
8d831c02da9a fix sort of fields vocabulary: should consider option groups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3308
diff changeset
    36
            partresult.append( (label, value) )
8d831c02da9a fix sort of fields vocabulary: should consider option groups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3308
diff changeset
    37
    result += sorted(partresult)
8d831c02da9a fix sort of fields vocabulary: should consider option groups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3308
diff changeset
    38
    return result
8d831c02da9a fix sort of fields vocabulary: should consider option groups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3308
diff changeset
    39
8d831c02da9a fix sort of fields vocabulary: should consider option groups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3308
diff changeset
    40
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
    41
class Field(object):
1265
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    42
    """field class is introduced to control what's displayed in forms. It makes
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    43
    the link between something to edit and its display in the form. Actual
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    44
    display is handled by a widget associated to the field.
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    45
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    46
    Attributes
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    47
    ----------
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    48
    all the attributes described below have sensible default value which may be
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    49
    overriden by value given to field's constructor.
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1417
diff changeset
    50
1265
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    51
    :name:
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    52
       name of the field (basestring), should be unique in a form.
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    53
    :id:
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    54
       dom identifier (default to the same value as `name`), should be unique in
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    55
       a form.
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    56
    :label:
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    57
       label of the field (default to the same value as `name`).
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    58
    :help:
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    59
       help message about this field.
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    60
    :widget:
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    61
       widget associated to the field. Each field class has a default widget
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    62
       class which may be overriden per instance.
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    63
    :required:
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    64
       bool flag telling if the field is required or not.
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    65
    :initial:
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    66
       initial value, used when no value specified by other means.
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    67
    :choices:
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    68
       static vocabulary for this field. May be a list of values or a list of
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    69
       (label, value) tuples if specified.
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    70
    :sort:
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    71
       bool flag telling if the vocabulary (either static vocabulary specified
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    72
       in `choices` or dynamic vocabulary fetched from the form) should be
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    73
       sorted on label.
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    74
    :internationalizable:
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    75
       bool flag telling if the vocabulary labels should be translated using the
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    76
       current request language.
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    77
    :eidparam:
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    78
       bool flag telling if this field is linked to a specific entity
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    79
    :role:
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    80
       when the field is linked to an entity attribute or relation, tells the
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    81
       role of the entity in the relation (eg 'subject' or 'object')
2520
8c5cf48ae9ea new fieldset attribute on field, use to group fields by the default form renderer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2459
diff changeset
    82
    :fieldset:
8c5cf48ae9ea new fieldset attribute on field, use to group fields by the default form renderer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2459
diff changeset
    83
       optional fieldset to which this field belongs to
3874
7d0d4a6be046 [formfields] allow fields ordering with autoform_field_kwargs
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3873
diff changeset
    84
    :order:
7d0d4a6be046 [formfields] allow fields ordering with autoform_field_kwargs
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3873
diff changeset
    85
       key used by automatic forms to sort fields
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1417
diff changeset
    86
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
    87
    """
1265
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    88
    # default widget associated to this class of fields. May be overriden per
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    89
    # instance
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
    90
    widget = TextInput
1265
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    91
    # does this field requires a multipart form
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
    92
    needs_multipart = False
1265
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    93
    # class attribute used for ordering of fields in a form
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    94
    __creation_rank = 0
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
    95
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1417
diff changeset
    96
    def __init__(self, name=None, id=None, label=None, help=None,
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
    97
                 widget=None, required=False, initial=None,
1265
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
    98
                 choices=None, sort=True, internationalizable=False,
3874
7d0d4a6be046 [formfields] allow fields ordering with autoform_field_kwargs
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3873
diff changeset
    99
                 eidparam=False, role='subject', fieldset=None, order=None):
1265
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
   100
        self.name = name
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
   101
        self.id = id or name
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
   102
        self.label = label or name
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
   103
        self.help = help
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   104
        self.required = required
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   105
        self.initial = initial
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   106
        self.choices = choices
1265
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
   107
        self.sort = sort
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
   108
        self.internationalizable = internationalizable
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   109
        self.eidparam = eidparam
1095
6917ebe281e9 test and fix guess_field, some pylint fixes
sylvain.thenault@logilab.fr
parents: 1081
diff changeset
   110
        self.role = role
2520
8c5cf48ae9ea new fieldset attribute on field, use to group fields by the default form renderer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2459
diff changeset
   111
        self.fieldset = fieldset
1986
96c0e56cb0cf move widget selection's logic on fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   112
        self.init_widget(widget)
3874
7d0d4a6be046 [formfields] allow fields ordering with autoform_field_kwargs
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3873
diff changeset
   113
        self.order = order
1265
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
   114
        # ordering number for this field instance
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
   115
        self.creation_rank = Field.__creation_rank
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
   116
        Field.__creation_rank += 1
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1417
diff changeset
   117
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   118
    def __unicode__(self):
1562
e6d2c07c0c58 [forms/widgets] fix relation field not sorting its vocabulary, revert hack on Select widget
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1505
diff changeset
   119
        return u'<%s name=%r label=%r id=%r initial=%r visible=%r @%x>' % (
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   120
            self.__class__.__name__, self.name, self.label,
1562
e6d2c07c0c58 [forms/widgets] fix relation field not sorting its vocabulary, revert hack on Select widget
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1505
diff changeset
   121
            self.id, self.initial, self.is_visible(), id(self))
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   122
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   123
    def __repr__(self):
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   124
        return self.__unicode__().encode('utf-8')
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   125
1986
96c0e56cb0cf move widget selection's logic on fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   126
    def init_widget(self, widget):
96c0e56cb0cf move widget selection's logic on fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   127
        if widget is not None:
96c0e56cb0cf move widget selection's logic on fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   128
            self.widget = widget
2091
a7ea618e5478 don't set select widget when a vocabulary widget is already specified on the field class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2086
diff changeset
   129
        elif self.choices and not self.widget.vocabulary_widget:
a7ea618e5478 don't set select widget when a vocabulary widget is already specified on the field class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2086
diff changeset
   130
            self.widget = Select()
1986
96c0e56cb0cf move widget selection's logic on fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   131
        if isinstance(self.widget, type):
96c0e56cb0cf move widget selection's logic on fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   132
            self.widget = self.widget()
96c0e56cb0cf move widget selection's logic on fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   133
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   134
    def set_name(self, name):
1265
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
   135
        """automatically set .id and .label when name is set"""
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   136
        assert name
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   137
        self.name = name
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   138
        if not self.id:
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   139
            self.id = name
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   140
        if not self.label:
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   141
            self.label = name
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1417
diff changeset
   142
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   143
    def is_visible(self):
1265
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
   144
        """return true if the field is not an hidden field"""
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   145
        return not isinstance(self.widget, HiddenInput)
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1417
diff changeset
   146
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   147
    def actual_fields(self, form):
1265
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
   148
        """return actual fields composing this field in case of a compound
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
   149
        field, usually simply return self
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
   150
        """
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   151
        yield self
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1417
diff changeset
   152
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   153
    def format_value(self, req, value):
1265
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
   154
        """return value suitable for display where value may be a list or tuple
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
   155
        of values
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
   156
        """
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   157
        if isinstance(value, (list, tuple)):
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   158
            return [self.format_single_value(req, val) for val in value]
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   159
        return self.format_single_value(req, value)
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1417
diff changeset
   160
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   161
    def format_single_value(self, req, value):
1265
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
   162
        """return value suitable for display"""
1306
e70ad982374a bool handling
sylvain.thenault@logilab.fr
parents: 1305
diff changeset
   163
        if value is None or value is False:
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   164
            return u''
1306
e70ad982374a bool handling
sylvain.thenault@logilab.fr
parents: 1305
diff changeset
   165
        if value is True:
e70ad982374a bool handling
sylvain.thenault@logilab.fr
parents: 1305
diff changeset
   166
            return u'1'
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   167
        return unicode(value)
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   168
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   169
    def get_widget(self, form):
1265
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
   170
        """return the widget instance associated to this field"""
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   171
        return self.widget
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1417
diff changeset
   172
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   173
    def example_format(self, req):
1265
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
   174
        """return a sample string describing what can be given as input for this
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
   175
        field
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1417
diff changeset
   176
        """
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   177
        return u''
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   178
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   179
    def render(self, form, renderer):
1265
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
   180
        """render this field, which is part of form, using the given form
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
   181
        renderer
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
   182
        """
2522
562f5dcf2345 widget.render now takes the renderer as third argument (keeping minimal bw compat)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2520
diff changeset
   183
        widget = self.get_widget(form)
3873
4d95109582c7 [web] remove widget.render backward compatibility
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3790
diff changeset
   184
        return widget.render(form, self, renderer)
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   185
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   186
    def vocabulary(self, form):
1265
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
   187
        """return vocabulary for this field. This method will be called by
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1417
diff changeset
   188
        widgets which desire it."""
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   189
        if self.choices is not None:
1181
620ec8e6ae19 cleanup, various fix to get something working
sylvain.thenault@logilab.fr
parents: 1147
diff changeset
   190
            if callable(self.choices):
2196
b08521e4eaab vocabulary method (eg field.choices) should now take the form instance as argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2146
diff changeset
   191
                try:
b08521e4eaab vocabulary method (eg field.choices) should now take the form instance as argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2146
diff changeset
   192
                    vocab = self.choices(form=form)
b08521e4eaab vocabulary method (eg field.choices) should now take the form instance as argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2146
diff changeset
   193
                except TypeError:
3533
88ceed15a3d3 nicer deprecation messages
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3510
diff changeset
   194
                    warn('[3.3] vocabulary method (eg field.choices) should now take '
2196
b08521e4eaab vocabulary method (eg field.choices) should now take the form instance as argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2146
diff changeset
   195
                         'the form instance as argument', DeprecationWarning)
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3388
diff changeset
   196
                    vocab = self.choices(req=form._cw)
1181
620ec8e6ae19 cleanup, various fix to get something working
sylvain.thenault@logilab.fr
parents: 1147
diff changeset
   197
            else:
620ec8e6ae19 cleanup, various fix to get something working
sylvain.thenault@logilab.fr
parents: 1147
diff changeset
   198
                vocab = self.choices
620ec8e6ae19 cleanup, various fix to get something working
sylvain.thenault@logilab.fr
parents: 1147
diff changeset
   199
            if vocab and not isinstance(vocab[0], (list, tuple)):
620ec8e6ae19 cleanup, various fix to get something working
sylvain.thenault@logilab.fr
parents: 1147
diff changeset
   200
                vocab = [(x, x) for x in vocab]
1265
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
   201
        else:
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
   202
            vocab = form.form_field_vocabulary(self)
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
   203
        if self.internationalizable:
3790
34fdb8fb49d1 [B] web: weird display with internationalizable (Closes: #503071)
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 3689
diff changeset
   204
            # the short-cirtcuit 'and' boolean operator is used here to permit
34fdb8fb49d1 [B] web: weird display with internationalizable (Closes: #503071)
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 3689
diff changeset
   205
            # a valid empty string in vocabulary without attempting to translate
34fdb8fb49d1 [B] web: weird display with internationalizable (Closes: #503071)
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 3689
diff changeset
   206
            # it by gettext (which can lead to weird strings display)
3890
d7a270f50f54 backport stable branch (one more time painfully)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3720 3874
diff changeset
   207
            vocab = [(label and form._cw._(label), value) for label, value in vocab]
1265
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
   208
        if self.sort:
3334
8d831c02da9a fix sort of fields vocabulary: should consider option groups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3308
diff changeset
   209
            vocab = vocab_sort(vocab)
1265
e5cdd5c0dce3 handle sort/internationalizable on Field base class + fix guess_field to deal with internationalizable and default values
sylvain.thenault@logilab.fr
parents: 1181
diff changeset
   210
        return vocab
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1417
diff changeset
   211
1307
8c3336c5ddba new form_init callback
sylvain.thenault@logilab.fr
parents: 1306
diff changeset
   212
    def form_init(self, form):
3510
bf746bf4a394 rename form_build_context to build_context, and call it from form, not renderer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3496
diff changeset
   213
        """method called before by build_context to trigger potential field
1307
8c3336c5ddba new form_init callback
sylvain.thenault@logilab.fr
parents: 1306
diff changeset
   214
        initialization requiring the form instance
8c3336c5ddba new form_init callback
sylvain.thenault@logilab.fr
parents: 1306
diff changeset
   215
        """
8c3336c5ddba new form_init callback
sylvain.thenault@logilab.fr
parents: 1306
diff changeset
   216
        pass
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1417
diff changeset
   217
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   218
    def process_form_value(self, form):
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   219
        """process posted form and return correctly typed value"""
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   220
        widget = self.get_widget(form)
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   221
        return widget.process_field_data(form, self)
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   222
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   223
    def process_posted(self, form):
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   224
        for field in self.actual_fields(form):
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   225
            if field is self:
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   226
                yield field.name, field.process_form_value(form)
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   227
            else:
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   228
                # recursive function: we might have compound fields
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   229
                # of compound fields (of compound fields of ...)
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   230
                for fieldname, value in field.process_posted(form):
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   231
                    yield fieldname, value
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   232
1986
96c0e56cb0cf move widget selection's logic on fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   233
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   234
class StringField(Field):
1986
96c0e56cb0cf move widget selection's logic on fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   235
    widget = TextArea
96c0e56cb0cf move widget selection's logic on fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   236
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   237
    def __init__(self, max_length=None, **kwargs):
1986
96c0e56cb0cf move widget selection's logic on fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   238
        self.max_length = max_length # must be set before super call
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   239
        super(StringField, self).__init__(**kwargs)
1986
96c0e56cb0cf move widget selection's logic on fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   240
96c0e56cb0cf move widget selection's logic on fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   241
    def init_widget(self, widget):
96c0e56cb0cf move widget selection's logic on fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   242
        if widget is None:
96c0e56cb0cf move widget selection's logic on fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   243
            if self.choices:
1988
b5c5c088bb03 if choices is set and widget not explicitly specified, use Select in base field
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1986
diff changeset
   244
                widget = Select()
1986
96c0e56cb0cf move widget selection's logic on fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   245
            elif self.max_length and self.max_length < 257:
1988
b5c5c088bb03 if choices is set and widget not explicitly specified, use Select in base field
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1986
diff changeset
   246
                widget = TextInput()
2344
22b5ea0679ed [formfields] set a reasonable minimal minimum length to input/text, also set the max length if applicable (closes #344538)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2332
diff changeset
   247
1986
96c0e56cb0cf move widget selection's logic on fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   248
        super(StringField, self).init_widget(widget)
1573
d34589d35daa drop TextField, this is simply a StringField with a text area widget
sylvain.thenault@logilab.fr
parents: 1564
diff changeset
   249
        if isinstance(self.widget, TextArea):
d34589d35daa drop TextField, this is simply a StringField with a text area widget
sylvain.thenault@logilab.fr
parents: 1564
diff changeset
   250
            self.init_text_area(self.widget)
2362
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2360
diff changeset
   251
        elif isinstance(self.widget, TextInput):
2360
1d43aa551ba9 [formwidgets,formfields] hum, this way
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2356
diff changeset
   252
            self.init_text_input(self.widget)
1d43aa551ba9 [formwidgets,formfields] hum, this way
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2356
diff changeset
   253
1d43aa551ba9 [formwidgets,formfields] hum, this way
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2356
diff changeset
   254
    def init_text_input(self, widget):
1d43aa551ba9 [formwidgets,formfields] hum, this way
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2356
diff changeset
   255
        if self.max_length:
1d43aa551ba9 [formwidgets,formfields] hum, this way
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2356
diff changeset
   256
            widget.attrs.setdefault('size', min(45, self.max_length))
1d43aa551ba9 [formwidgets,formfields] hum, this way
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2356
diff changeset
   257
            widget.attrs.setdefault('maxlength', self.max_length)
1573
d34589d35daa drop TextField, this is simply a StringField with a text area widget
sylvain.thenault@logilab.fr
parents: 1564
diff changeset
   258
d34589d35daa drop TextField, this is simply a StringField with a text area widget
sylvain.thenault@logilab.fr
parents: 1564
diff changeset
   259
    def init_text_area(self, widget):
d34589d35daa drop TextField, this is simply a StringField with a text area widget
sylvain.thenault@logilab.fr
parents: 1564
diff changeset
   260
        if self.max_length < 513:
d34589d35daa drop TextField, this is simply a StringField with a text area widget
sylvain.thenault@logilab.fr
parents: 1564
diff changeset
   261
            widget.attrs.setdefault('cols', 60)
d34589d35daa drop TextField, this is simply a StringField with a text area widget
sylvain.thenault@logilab.fr
parents: 1564
diff changeset
   262
            widget.attrs.setdefault('rows', 5)
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   263
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   264
1573
d34589d35daa drop TextField, this is simply a StringField with a text area widget
sylvain.thenault@logilab.fr
parents: 1564
diff changeset
   265
class RichTextField(StringField):
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   266
    widget = None
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   267
    def __init__(self, format_field=None, **kwargs):
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   268
        super(RichTextField, self).__init__(**kwargs)
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   269
        self.format_field = format_field
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   270
2348
acf4b6a59558 [formwidgets] ensure textarea for richstring has not ridicuously small size (close #344547)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2347
diff changeset
   271
    def init_text_area(self, widget):
acf4b6a59558 [formwidgets] ensure textarea for richstring has not ridicuously small size (close #344547)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2347
diff changeset
   272
        pass
acf4b6a59558 [formwidgets] ensure textarea for richstring has not ridicuously small size (close #344547)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2347
diff changeset
   273
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   274
    def get_widget(self, form):
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   275
        if self.widget is None:
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   276
            if self.use_fckeditor(form):
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   277
                return FCKEditor()
1573
d34589d35daa drop TextField, this is simply a StringField with a text area widget
sylvain.thenault@logilab.fr
parents: 1564
diff changeset
   278
            widget = TextArea()
d34589d35daa drop TextField, this is simply a StringField with a text area widget
sylvain.thenault@logilab.fr
parents: 1564
diff changeset
   279
            self.init_text_area(widget)
d34589d35daa drop TextField, this is simply a StringField with a text area widget
sylvain.thenault@logilab.fr
parents: 1564
diff changeset
   280
            return widget
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   281
        return self.widget
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   282
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   283
    def get_format_field(self, form):
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   284
        if self.format_field:
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   285
            return self.format_field
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   286
        # we have to cache generated field since it's use as key in the
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   287
        # context dictionnary
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3388
diff changeset
   288
        req = form._cw
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   289
        try:
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   290
            return req.data[self]
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   291
        except KeyError:
2724
7966d87202d7 format field should inherit from parent field's eidparam
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2723
diff changeset
   292
            fkwargs = {'eidparam': self.eidparam}
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   293
            if self.use_fckeditor(form):
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   294
                # if fckeditor is used and format field isn't explicitly
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   295
                # deactivated, we want an hidden field for the format
1858
69e41c88e195 connect format field to form_field_format for its initial value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1836
diff changeset
   296
                fkwargs['widget'] = HiddenInput()
69e41c88e195 connect format field to form_field_format for its initial value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1836
diff changeset
   297
                fkwargs['initial'] = 'text/html'
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   298
            else:
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   299
                # else we want a format selector
1858
69e41c88e195 connect format field to form_field_format for its initial value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1836
diff changeset
   300
                fkwargs['widget'] = Select()
1095
6917ebe281e9 test and fix guess_field, some pylint fixes
sylvain.thenault@logilab.fr
parents: 1081
diff changeset
   301
                fcstr = FormatConstraint()
3347
428f95118556 fix vocab param to avoid deprecation warning
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3337
diff changeset
   302
                fkwargs['choices'] = fcstr.vocabulary(form=form)
1858
69e41c88e195 connect format field to form_field_format for its initial value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1836
diff changeset
   303
                fkwargs['internationalizable'] = True
69e41c88e195 connect format field to form_field_format for its initial value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1836
diff changeset
   304
                fkwargs['initial'] = lambda f: f.form_field_format(self)
3385
68953ecddd2b [forms] work-in-progress: let guess_field and RichTextField.get_format_field handle eidparam of meta fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3384
diff changeset
   305
            fkwargs['eidparam'] = self.eidparam
1858
69e41c88e195 connect format field to form_field_format for its initial value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1836
diff changeset
   306
            field = StringField(name=self.name + '_format', **fkwargs)
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   307
            req.data[self] = field
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   308
            return field
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1417
diff changeset
   309
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   310
    def actual_fields(self, form):
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   311
        yield self
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   312
        format_field = self.get_format_field(form)
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   313
        if format_field:
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   314
            yield format_field
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1417
diff changeset
   315
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   316
    def use_fckeditor(self, form):
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   317
        """return True if fckeditor should be used to edit entity's attribute named
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   318
        `attr`, according to user preferences
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   319
        """
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3388
diff changeset
   320
        if form._cw.use_fckeditor():
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   321
            return form.form_field_format(self) == 'text/html'
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   322
        return False
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   323
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   324
    def render(self, form, renderer):
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   325
        format_field = self.get_format_field(form)
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   326
        if format_field:
1793
fdac26e003e7 fix vertical alignment pb. with descr. format list and textarea inputs
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1758
diff changeset
   327
            # XXX we want both fields to remain vertically aligned
2723
d38c2b01d766 don't set display: block on hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2362
diff changeset
   328
            if format_field.is_visible():
d38c2b01d766 don't set display: block on hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2362
diff changeset
   329
                format_field.widget.attrs['style'] = 'display: block'
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   330
            result = format_field.render(form, renderer)
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   331
        else:
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   332
            result = u''
2522
562f5dcf2345 widget.render now takes the renderer as third argument (keeping minimal bw compat)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2520
diff changeset
   333
        return result + self.get_widget(form).render(form, self, renderer)
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   334
1417
06af20e663f2 remove spaces
sylvain.thenault@logilab.fr
parents: 1393
diff changeset
   335
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   336
class FileField(StringField):
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   337
    widget = FileInput
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   338
    needs_multipart = True
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1417
diff changeset
   339
3496
35a67ac6efe8 support name metadata on guess_field; add name_field to FileField
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3347
diff changeset
   340
    def __init__(self, format_field=None, encoding_field=None, name_field=None,
35a67ac6efe8 support name metadata on guess_field; add name_field to FileField
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3347
diff changeset
   341
                 **kwargs):
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   342
        super(FileField, self).__init__(**kwargs)
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   343
        self.format_field = format_field
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   344
        self.encoding_field = encoding_field
3496
35a67ac6efe8 support name metadata on guess_field; add name_field to FileField
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3347
diff changeset
   345
        self.name_field = name_field
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1417
diff changeset
   346
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   347
    def actual_fields(self, form):
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   348
        yield self
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   349
        if self.format_field:
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   350
            yield self.format_field
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   351
        if self.encoding_field:
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   352
            yield self.encoding_field
3496
35a67ac6efe8 support name metadata on guess_field; add name_field to FileField
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3347
diff changeset
   353
        if self.name_field:
35a67ac6efe8 support name metadata on guess_field; add name_field to FileField
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3347
diff changeset
   354
            yield self.name_field
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   355
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   356
    def render(self, form, renderer):
2522
562f5dcf2345 widget.render now takes the renderer as third argument (keeping minimal bw compat)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2520
diff changeset
   357
        wdgs = [self.get_widget(form).render(form, self, renderer)]
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   358
        if self.format_field or self.encoding_field:
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   359
            divid = '%s-advanced' % form.context[self]['name']
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   360
            wdgs.append(u'<a href="%s" title="%s"><img src="%s" alt="%s"/></a>' %
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2244
diff changeset
   361
                        (xml_escape(uilib.toggle_action(divid)),
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3388
diff changeset
   362
                         form._cw._('show advanced fields'),
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3388
diff changeset
   363
                         xml_escape(form._cw.build_url('data/puce_down.png')),
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3388
diff changeset
   364
                         form._cw._('show advanced fields')))
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   365
            wdgs.append(u'<div id="%s" class="hidden">' % divid)
3496
35a67ac6efe8 support name metadata on guess_field; add name_field to FileField
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3347
diff changeset
   366
            if self.name_field:
35a67ac6efe8 support name metadata on guess_field; add name_field to FileField
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3347
diff changeset
   367
                wdgs.append(self.render_subfield(form, self.name_field, renderer))
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   368
            if self.format_field:
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   369
                wdgs.append(self.render_subfield(form, self.format_field, renderer))
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   370
            if self.encoding_field:
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   371
                wdgs.append(self.render_subfield(form, self.encoding_field, renderer))
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1417
diff changeset
   372
            wdgs.append(u'</div>')
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   373
        if not self.required and form.context[self]['value']:
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   374
            # trick to be able to delete an uploaded file
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   375
            wdgs.append(u'<br/>')
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   376
            wdgs.append(tags.input(name=u'%s__detach' % form.context[self]['name'],
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   377
                                   type=u'checkbox'))
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3388
diff changeset
   378
            wdgs.append(form._cw._('detach attached file'))
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   379
        return u'\n'.join(wdgs)
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   380
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   381
    def render_subfield(self, form, field, renderer):
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   382
        return (renderer.render_label(form, field)
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   383
                + field.render(form, renderer)
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   384
                + renderer.render_help(form, field)
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   385
                + u'<br/>')
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   386
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   387
    def process_form_value(self, form):
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3388
diff changeset
   388
        posted = form._cw.form
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   389
        value = posted.get(form.form_field_name(self))
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   390
        formkey = form.form_field_name(self)
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   391
        if ('%s__detach' % form.context[self]['name']) in posted:
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   392
            # drop current file value
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   393
            value = None
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   394
        # no need to check value when nor explicit detach nor new file
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   395
        # submitted, since it will think the attribute is not modified
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   396
        elif value:
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   397
            filename, _, stream = value
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   398
            # value is a  3-uple (filename, mimetype, stream)
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   399
            value = Binary(stream.read())
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   400
            if not val.getvalue(): # usually an unexistant file
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   401
                value = None
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   402
            else:
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   403
                value.filename = filename
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   404
        return value
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   405
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1417
diff changeset
   406
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   407
class EditableFileField(FileField):
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   408
    editable_formats = ('text/plain', 'text/html', 'text/rest')
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1417
diff changeset
   409
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   410
    def render(self, form, renderer):
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   411
        wdgs = [super(EditableFileField, self).render(form, renderer)]
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   412
        if form.form_field_format(self) in self.editable_formats:
1392
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1307
diff changeset
   413
            data = form.form_field_value(self, load_bytes=True)
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   414
            if data:
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   415
                encoding = form.form_field_encoding(self)
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   416
                try:
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   417
                    form.context[self]['value'] = unicode(data.getvalue(), encoding)
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   418
                except UnicodeError:
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   419
                    pass
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   420
                else:
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   421
                    if not self.required:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3388
diff changeset
   422
                        msg = form._cw._(
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   423
                            'You can either submit a new file using the browse button above'
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   424
                            ', or choose to remove already uploaded file by checking the '
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   425
                            '"detach attached file" check-box, or edit file content online '
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   426
                            'with the widget below.')
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   427
                    else:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3388
diff changeset
   428
                        msg = form._cw._(
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   429
                            'You can either submit a new file using the browse button above'
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   430
                            ', or edit file content online with the widget below.')
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   431
                    wdgs.append(u'<p><b>%s</b></p>' % msg)
2522
562f5dcf2345 widget.render now takes the renderer as third argument (keeping minimal bw compat)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2520
diff changeset
   432
                    wdgs.append(TextArea(setdomid=False).render(form, self, renderer))
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   433
                    # XXX restore form context?
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   434
        return '\n'.join(wdgs)
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   435
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   436
    def process_form_value(self, form):
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3388
diff changeset
   437
        value = form._cw.form.get(form.form_field_name(self))
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   438
        if isinstance(value, unicode):
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   439
            # file modified using a text widget
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   440
            encoding = form.form_field_encoding(self)
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   441
            return Binary(value.encode(encoding))
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   442
        return super(EditableFileField, self).process_form_value(form)
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   443
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1417
diff changeset
   444
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   445
class IntField(Field):
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   446
    def __init__(self, min=None, max=None, **kwargs):
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   447
        super(IntField, self).__init__(**kwargs)
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   448
        self.min = min
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   449
        self.max = max
1758
d46f59e5efd3 some widget adjustments
sylvain.thenault@logilab.fr
parents: 1738
diff changeset
   450
        if isinstance(self.widget, TextInput):
d46f59e5efd3 some widget adjustments
sylvain.thenault@logilab.fr
parents: 1738
diff changeset
   451
            self.widget.attrs.setdefault('size', 5)
d46f59e5efd3 some widget adjustments
sylvain.thenault@logilab.fr
parents: 1738
diff changeset
   452
            self.widget.attrs.setdefault('maxlength', 15)
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   453
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   454
    def process_form_value(self, form):
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   455
        return int(Field.process_form_value(self, form))
1986
96c0e56cb0cf move widget selection's logic on fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   456
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   457
class BooleanField(Field):
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   458
    widget = Radio
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1417
diff changeset
   459
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   460
    def vocabulary(self, form):
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   461
        if self.choices:
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   462
            return self.choices
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3388
diff changeset
   463
        return [(form._cw._('yes'), '1'), (form._cw._('no'), '')]
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   464
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   465
    def process_form_value(self, form):
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   466
        return bool(Field.process_form_value(self, form))
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   467
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1417
diff changeset
   468
class FloatField(IntField):
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   469
    def format_single_value(self, req, value):
1095
6917ebe281e9 test and fix guess_field, some pylint fixes
sylvain.thenault@logilab.fr
parents: 1081
diff changeset
   470
        formatstr = req.property_value('ui.float-format')
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   471
        if value is None:
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   472
            return u''
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   473
        return formatstr % float(value)
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   474
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   475
    def render_example(self, req):
2086
be76ce00a05e fix TimeField format_prop, use format_single_value directly in render_example
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1989
diff changeset
   476
        return self.format_single_value(req, 1.234)
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   477
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   478
    def process_form_value(self, form):
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   479
        return float(Field.process_form_value(self, form))
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   480
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   481
class DateField(StringField):
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   482
    format_prop = 'ui.date-format'
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   483
    widget = DateTimePicker
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1417
diff changeset
   484
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   485
    def format_single_value(self, req, value):
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   486
        return value and ustrftime(value, req.property_value(self.format_prop)) or u''
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   487
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   488
    def render_example(self, req):
2086
be76ce00a05e fix TimeField format_prop, use format_single_value directly in render_example
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1989
diff changeset
   489
        return self.format_single_value(req, datetime.now())
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   490
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   491
    def process_form_value(self, form):
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   492
        # widget is supposed to return a date as a correctly formatted string
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   493
        date = Field.process_form_value(self, form)
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   494
        # but for some widgets, it might be simpler to return date objects
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   495
        # directly, so handle that case :
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   496
        if isinstance(date, basestring):
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   497
            date = form.parse_date(wdgdate, 'Date')
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   498
        return date
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   499
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   500
class DateTimeField(DateField):
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   501
    format_prop = 'ui.datetime-format'
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   502
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   503
    def process_form_value(self, form):
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   504
        # widget is supposed to return a date as a correctly formatted string
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   505
        date = Field.process_form_value(self, form)
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   506
        # but for some widgets, it might be simpler to return date objects
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   507
        # directly, so handle that case :
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   508
        if isinstance(date, basestring):
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   509
            date = form.parse_datetime(wdgdate, 'Datetime')
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   510
        return date
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   511
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   512
class TimeField(DateField):
2086
be76ce00a05e fix TimeField format_prop, use format_single_value directly in render_example
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1989
diff changeset
   513
    format_prop = 'ui.time-format'
1758
d46f59e5efd3 some widget adjustments
sylvain.thenault@logilab.fr
parents: 1738
diff changeset
   514
    widget = TextInput
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   515
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   516
    def process_form_value(self, form):
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   517
        # widget is supposed to return a date as a correctly formatted string
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   518
        time = Field.process_form_value(self, form)
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   519
        # but for some widgets, it might be simpler to return time objects
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   520
        # directly, so handle that case :
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   521
        if isinstance(time, basestring):
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   522
            time = form.parse_time(wdgdate, 'Time')
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3385
diff changeset
   523
        return time
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1417
diff changeset
   524
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   525
class RelationField(Field):
3246
9e4adca73a95 stop setting sort to false by default on relation field and explain why
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2726
diff changeset
   526
    # XXX (syt): iirc, we originaly don't sort relation vocabulary since we want
9e4adca73a95 stop setting sort to false by default on relation field and explain why
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2726
diff changeset
   527
    # to let entity.unrelated_rql control this, usually to get most recently
9e4adca73a95 stop setting sort to false by default on relation field and explain why
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2726
diff changeset
   528
    # modified entities in the select box instead of by alphabetical order. Now,
9e4adca73a95 stop setting sort to false by default on relation field and explain why
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2726
diff changeset
   529
    # we first use unrelated_rql to get the vocabulary, which may be limited
9e4adca73a95 stop setting sort to false by default on relation field and explain why
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2726
diff changeset
   530
    # (hence we get the latest modified entities) and we can sort here for
9e4adca73a95 stop setting sort to false by default on relation field and explain why
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2726
diff changeset
   531
    # better readability
9e4adca73a95 stop setting sort to false by default on relation field and explain why
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2726
diff changeset
   532
    #
9e4adca73a95 stop setting sort to false by default on relation field and explain why
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2726
diff changeset
   533
    # def __init__(self, **kwargs):
9e4adca73a95 stop setting sort to false by default on relation field and explain why
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2726
diff changeset
   534
    #     kwargs.setdefault('sort', False)
9e4adca73a95 stop setting sort to false by default on relation field and explain why
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2726
diff changeset
   535
    #     super(RelationField, self).__init__(**kwargs)
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   536
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   537
    @staticmethod
1095
6917ebe281e9 test and fix guess_field, some pylint fixes
sylvain.thenault@logilab.fr
parents: 1081
diff changeset
   538
    def fromcardinality(card, **kwargs):
1738
2cfd50c8a415 should not override potential explicit widget
sylvain.thenault@logilab.fr
parents: 1709
diff changeset
   539
        kwargs.setdefault('widget', Select(multiple=card in '*+'))
2cfd50c8a415 should not override potential explicit widget
sylvain.thenault@logilab.fr
parents: 1709
diff changeset
   540
        return RelationField(**kwargs)
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1417
diff changeset
   541
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   542
    def vocabulary(self, form):
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1108
diff changeset
   543
        entity = form.edited_entity
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3388
diff changeset
   544
        req = entity._cw
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   545
        # first see if its specified by __linkto form parameters
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   546
        linkedto = entity.linked_to(self.name, self.role)
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   547
        if linkedto:
2680
66472d85d548 [R] use req.entity_from_eid
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2678
diff changeset
   548
            entities = (req.entity_from_eid(eid) for eid in linkedto)
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   549
            return [(entity.view('combobox'), entity.eid) for entity in entities]
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   550
        # it isn't, check if the entity provides a method to get correct values
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   551
        res = []
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   552
        if not self.required:
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   553
            res.append(('', INTERNAL_FIELD_VALUE))
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   554
        # vocabulary doesn't include current values, add them
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   555
        if entity.has_eid():
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   556
            rset = entity.related(self.name, self.role)
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   557
            relatedvocab = [(e.view('combobox'), e.eid) for e in rset.entities()]
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   558
        else:
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   559
            relatedvocab = []
1562
e6d2c07c0c58 [forms/widgets] fix relation field not sorting its vocabulary, revert hack on Select widget
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1505
diff changeset
   560
        vocab = res + form.form_field_vocabulary(self) + relatedvocab
e6d2c07c0c58 [forms/widgets] fix relation field not sorting its vocabulary, revert hack on Select widget
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1505
diff changeset
   561
        if self.sort:
3334
8d831c02da9a fix sort of fields vocabulary: should consider option groups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3308
diff changeset
   562
            vocab = vocab_sort(vocab)
1562
e6d2c07c0c58 [forms/widgets] fix relation field not sorting its vocabulary, revert hack on Select widget
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1505
diff changeset
   563
        return vocab
1437
ea75dfe32317 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1417
diff changeset
   564
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   565
    def format_single_value(self, req, value):
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   566
        return value
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   567
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   568
2523
1d245fbbeb90 some new field/widgets classes: CompoundField, IntervalWidget, HorizontalLayoutWidget
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2522
diff changeset
   569
class CompoundField(Field):
1d245fbbeb90 some new field/widgets classes: CompoundField, IntervalWidget, HorizontalLayoutWidget
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2522
diff changeset
   570
    def __init__(self, fields, *args, **kwargs):
1d245fbbeb90 some new field/widgets classes: CompoundField, IntervalWidget, HorizontalLayoutWidget
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2522
diff changeset
   571
        super(CompoundField, self).__init__(*args, **kwargs)
1d245fbbeb90 some new field/widgets classes: CompoundField, IntervalWidget, HorizontalLayoutWidget
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2522
diff changeset
   572
        self.fields = fields
1d245fbbeb90 some new field/widgets classes: CompoundField, IntervalWidget, HorizontalLayoutWidget
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2522
diff changeset
   573
2549
3d8c62e5e2d4 [R forms] use a subfields(form) method to get a chance to adapt to context
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2523
diff changeset
   574
    def subfields(self, form):
3d8c62e5e2d4 [R forms] use a subfields(form) method to get a chance to adapt to context
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2523
diff changeset
   575
        return self.fields
2568
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2549
diff changeset
   576
2523
1d245fbbeb90 some new field/widgets classes: CompoundField, IntervalWidget, HorizontalLayoutWidget
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2522
diff changeset
   577
    def actual_fields(self, form):
1d245fbbeb90 some new field/widgets classes: CompoundField, IntervalWidget, HorizontalLayoutWidget
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2522
diff changeset
   578
        return [self] + list(self.fields)
1d245fbbeb90 some new field/widgets classes: CompoundField, IntervalWidget, HorizontalLayoutWidget
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2522
diff changeset
   579
1d245fbbeb90 some new field/widgets classes: CompoundField, IntervalWidget, HorizontalLayoutWidget
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2522
diff changeset
   580
1453
a9841184be7c guess_field now takes an entity schema as first argument, not an entity class
sylvain.thenault@logilab.fr
parents: 1437
diff changeset
   581
def guess_field(eschema, rschema, role='subject', skip_meta_attr=True, **kwargs):
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   582
    """return the most adapated widget to edit the relation
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   583
    'subjschema rschema objschema' according to information found in the schema
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   584
    """
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   585
    fieldclass = None
4014
24f7d7eb4c23 yams api update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3890
diff changeset
   586
    rdef = eschema.rdef(rschema, role)
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   587
    if role == 'subject':
4014
24f7d7eb4c23 yams api update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3890
diff changeset
   588
        targetschema = rdef.object
3689
deb13e88e037 follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3575
diff changeset
   589
        if rschema.final:
4069
5d149ba65dd0 fix guess_field to handle non internationalizable definition
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 4044
diff changeset
   590
            if rdef.get('internationalizable'):
2095
897732d3ee5a avoid overriding specified values when guessing field
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2091
diff changeset
   591
                kwargs.setdefault('internationalizable', True)
1709
f7110f533d14 use yams.schema method for initial value
sylvain.thenault@logilab.fr
parents: 1706
diff changeset
   592
            def get_default(form, es=eschema, rs=rschema):
f7110f533d14 use yams.schema method for initial value
sylvain.thenault@logilab.fr
parents: 1706
diff changeset
   593
                return es.default(rs)
2095
897732d3ee5a avoid overriding specified values when guessing field
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2091
diff changeset
   594
            kwargs.setdefault('initial', get_default)
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   595
    else:
4014
24f7d7eb4c23 yams api update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3890
diff changeset
   596
        targetschema = rdef.subject
4044
3876c894e018 card referenced later
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4023
diff changeset
   597
    card = rdef.role_cardinality(role)
3876c894e018 card referenced later
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4023
diff changeset
   598
    kwargs['required'] = card in '1+'
1095
6917ebe281e9 test and fix guess_field, some pylint fixes
sylvain.thenault@logilab.fr
parents: 1081
diff changeset
   599
    kwargs['name'] = rschema.type
3308
88f5f89d8d1b fix generated label for object relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3299
diff changeset
   600
    if role == 'object':
3574
f179ccbd13e6 [forms] fix generated label for fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3563
diff changeset
   601
        kwargs.setdefault('label', (eschema.type, rschema.type + '_object'))
3308
88f5f89d8d1b fix generated label for object relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3299
diff changeset
   602
    else:
3574
f179ccbd13e6 [forms] fix generated label for fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3563
diff changeset
   603
        kwargs.setdefault('label', (eschema.type, rschema.type))
3385
68953ecddd2b [forms] work-in-progress: let guess_field and RichTextField.get_format_field handle eidparam of meta fields
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3384
diff changeset
   604
    kwargs['eidparam'] = True
4014
24f7d7eb4c23 yams api update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3890
diff changeset
   605
    kwargs.setdefault('help', rdef.description)
3689
deb13e88e037 follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3575
diff changeset
   606
    if rschema.final:
1104
58f27c3c0167 more guess_field tests and fixes
sylvain.thenault@logilab.fr
parents: 1101
diff changeset
   607
        if skip_meta_attr and rschema in eschema.meta_attributes():
1095
6917ebe281e9 test and fix guess_field, some pylint fixes
sylvain.thenault@logilab.fr
parents: 1081
diff changeset
   608
            return None
6917ebe281e9 test and fix guess_field, some pylint fixes
sylvain.thenault@logilab.fr
parents: 1081
diff changeset
   609
        fieldclass = FIELDS[targetschema]
6917ebe281e9 test and fix guess_field, some pylint fixes
sylvain.thenault@logilab.fr
parents: 1081
diff changeset
   610
        if fieldclass is StringField:
1104
58f27c3c0167 more guess_field tests and fixes
sylvain.thenault@logilab.fr
parents: 1101
diff changeset
   611
            if targetschema == 'Password':
58f27c3c0167 more guess_field tests and fixes
sylvain.thenault@logilab.fr
parents: 1101
diff changeset
   612
                # special case for Password field: specific PasswordInput widget
1147
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1108
diff changeset
   613
                kwargs.setdefault('widget', PasswordInput())
402e8a8b1d6a more form works
sylvain.thenault@logilab.fr
parents: 1108
diff changeset
   614
                return StringField(**kwargs)
1104
58f27c3c0167 more guess_field tests and fixes
sylvain.thenault@logilab.fr
parents: 1101
diff changeset
   615
            if eschema.has_metadata(rschema, 'format'):
58f27c3c0167 more guess_field tests and fixes
sylvain.thenault@logilab.fr
parents: 1101
diff changeset
   616
                # use RichTextField instead of StringField if the attribute has
58f27c3c0167 more guess_field tests and fixes
sylvain.thenault@logilab.fr
parents: 1101
diff changeset
   617
                # a "format" metadata. But getting information from constraints
58f27c3c0167 more guess_field tests and fixes
sylvain.thenault@logilab.fr
parents: 1101
diff changeset
   618
                # may be useful anyway...
4014
24f7d7eb4c23 yams api update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3890
diff changeset
   619
                for cstr in rdef.constraints:
1104
58f27c3c0167 more guess_field tests and fixes
sylvain.thenault@logilab.fr
parents: 1101
diff changeset
   620
                    if isinstance(cstr, StaticVocabularyConstraint):
58f27c3c0167 more guess_field tests and fixes
sylvain.thenault@logilab.fr
parents: 1101
diff changeset
   621
                        raise Exception('rich text field with static vocabulary')
58f27c3c0167 more guess_field tests and fixes
sylvain.thenault@logilab.fr
parents: 1101
diff changeset
   622
                return RichTextField(**kwargs)
1574
0c6dbb774f54 drop text field usage
sylvain.thenault@logilab.fr
parents: 1573
diff changeset
   623
            # init StringField parameters according to constraints
4014
24f7d7eb4c23 yams api update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3890
diff changeset
   624
            for cstr in rdef.constraints:
1574
0c6dbb774f54 drop text field usage
sylvain.thenault@logilab.fr
parents: 1573
diff changeset
   625
                if isinstance(cstr, StaticVocabularyConstraint):
1577
25b46db3cb81 should set field's choices
sylvain.thenault@logilab.fr
parents: 1574
diff changeset
   626
                    kwargs.setdefault('choices', cstr.vocabulary)
1986
96c0e56cb0cf move widget selection's logic on fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   627
                    break
4014
24f7d7eb4c23 yams api update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3890
diff changeset
   628
            for cstr in rdef.constraints:
1574
0c6dbb774f54 drop text field usage
sylvain.thenault@logilab.fr
parents: 1573
diff changeset
   629
                if isinstance(cstr, SizeConstraint) and cstr.max is not None:
0c6dbb774f54 drop text field usage
sylvain.thenault@logilab.fr
parents: 1573
diff changeset
   630
                    kwargs['max_length'] = cstr.max
0c6dbb774f54 drop text field usage
sylvain.thenault@logilab.fr
parents: 1573
diff changeset
   631
            return StringField(**kwargs)
1104
58f27c3c0167 more guess_field tests and fixes
sylvain.thenault@logilab.fr
parents: 1101
diff changeset
   632
        if fieldclass is FileField:
3496
35a67ac6efe8 support name metadata on guess_field; add name_field to FileField
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3347
diff changeset
   633
            for metadata in ('format', 'encoding', 'name'):
1104
58f27c3c0167 more guess_field tests and fixes
sylvain.thenault@logilab.fr
parents: 1101
diff changeset
   634
                metaschema = eschema.has_metadata(rschema, metadata)
58f27c3c0167 more guess_field tests and fixes
sylvain.thenault@logilab.fr
parents: 1101
diff changeset
   635
                if metaschema is not None:
1453
a9841184be7c guess_field now takes an entity schema as first argument, not an entity class
sylvain.thenault@logilab.fr
parents: 1437
diff changeset
   636
                    kwargs['%s_field' % metadata] = guess_field(eschema, metaschema,
1104
58f27c3c0167 more guess_field tests and fixes
sylvain.thenault@logilab.fr
parents: 1101
diff changeset
   637
                                                                skip_meta_attr=False)
1095
6917ebe281e9 test and fix guess_field, some pylint fixes
sylvain.thenault@logilab.fr
parents: 1081
diff changeset
   638
        return fieldclass(**kwargs)
6917ebe281e9 test and fix guess_field, some pylint fixes
sylvain.thenault@logilab.fr
parents: 1081
diff changeset
   639
    kwargs['role'] = role
6917ebe281e9 test and fix guess_field, some pylint fixes
sylvain.thenault@logilab.fr
parents: 1081
diff changeset
   640
    return RelationField.fromcardinality(card, **kwargs)
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   641
1986
96c0e56cb0cf move widget selection's logic on fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   642
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   643
FIELDS = {
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   644
    'Boolean':  BooleanField,
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   645
    'Bytes':    FileField,
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   646
    'Date':     DateField,
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   647
    'Datetime': DateTimeField,
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   648
    'Int':      IntField,
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   649
    'Float':    FloatField,
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   650
    'Decimal':  StringField,
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   651
    'Password': StringField,
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   652
    'String' :  StringField,
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   653
    'Time':     TimeField,
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   654
    }