web/formwidgets.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Mon, 16 Jun 2014 10:22:24 +0200
changeset 9953 643b19d79e4a
parent 9821 2077c8da1893
child 10222 75d6096216d7
child 10404 797db633d60c
permissions -rw-r--r--
[CWEP002] introduce RQLRelationRewriter Refactor existing RQLRewriter for later reuse of rewriting relation as specified by CWEP002. Work is different because we simply want to replace a relation by another rql snippet and we don't have to bother with EXISTS, subqueries and all. This rewriter is not yet plugged into the querier. Depends on yams 0.40 API. Related to #3546717
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
9222
ec65ca70aac9 [date picker widgets] use bare jquery expression rather than jqNode
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9134
diff changeset
     1
# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5384
diff changeset
     2
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5384
diff changeset
     3
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5384
diff changeset
     4
# This file is part of CubicWeb.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5384
diff changeset
     5
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5384
diff changeset
     6
# CubicWeb is free software: you can redistribute it and/or modify it under the
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5384
diff changeset
     7
# terms of the GNU Lesser General Public License as published by the Free
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5384
diff changeset
     8
# Software Foundation, either version 2.1 of the License, or (at your option)
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5384
diff changeset
     9
# any later version.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5384
diff changeset
    10
#
5424
8ecbcbff9777 replace logilab-common by CubicWeb in disclaimer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5421
diff changeset
    11
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5384
diff changeset
    12
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5384
diff changeset
    13
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5384
diff changeset
    14
# details.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5384
diff changeset
    15
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5384
diff changeset
    16
# You should have received a copy of the GNU Lesser General Public License along
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5384
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    18
"""
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    19
Widgets
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    20
~~~~~~~
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    21
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    22
.. Note::
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    23
   A widget is responsible for the display of a field. It may use more than one
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    24
   HTML input tags. When the form is posted, a widget is also reponsible to give
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    25
   back to the field something it can understand.
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    26
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    27
   Of course you can not use any widget with any field...
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    28
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    29
.. autoclass:: cubicweb.web.formwidgets.FieldWidget
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    30
6880
4be32427b2b9 [book] fixes some references and other doc construction pbs
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6682
diff changeset
    31
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    32
HTML <input> based widgets
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    33
''''''''''''''''''''''''''
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    34
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    35
.. autoclass:: cubicweb.web.formwidgets.HiddenInput
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    36
.. autoclass:: cubicweb.web.formwidgets.TextInput
9716
c44224387028 [widget] Addition of EmailInput
Alain Begey <alain@unlish.com>
parents: 9377
diff changeset
    37
.. autoclass:: cubicweb.web.formwidgets.EmailInput
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    38
.. autoclass:: cubicweb.web.formwidgets.PasswordSingleInput
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    39
.. autoclass:: cubicweb.web.formwidgets.FileInput
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    40
.. autoclass:: cubicweb.web.formwidgets.ButtonInput
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    41
6880
4be32427b2b9 [book] fixes some references and other doc construction pbs
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6682
diff changeset
    42
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    43
Other standard HTML widgets
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    44
'''''''''''''''''''''''''''
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    45
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    46
.. autoclass:: cubicweb.web.formwidgets.TextArea
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    47
.. autoclass:: cubicweb.web.formwidgets.Select
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    48
.. autoclass:: cubicweb.web.formwidgets.CheckBox
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    49
.. autoclass:: cubicweb.web.formwidgets.Radio
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
    50
6880
4be32427b2b9 [book] fixes some references and other doc construction pbs
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6682
diff changeset
    51
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    52
Date and time widgets
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    53
'''''''''''''''''''''
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    54
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    55
.. autoclass:: cubicweb.web.formwidgets.DateTimePicker
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    56
.. autoclass:: cubicweb.web.formwidgets.JQueryDateTimePicker
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    57
.. autoclass:: cubicweb.web.formwidgets.JQueryDatePicker
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    58
.. autoclass:: cubicweb.web.formwidgets.JQueryTimePicker
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    59
6880
4be32427b2b9 [book] fixes some references and other doc construction pbs
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6682
diff changeset
    60
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    61
Ajax / javascript widgets
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    62
'''''''''''''''''''''''''
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    63
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    64
.. autoclass:: cubicweb.web.formwidgets.FCKEditor
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    65
.. autoclass:: cubicweb.web.formwidgets.AjaxWidget
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    66
.. autoclass:: cubicweb.web.formwidgets.AutoCompletionWidget
6890
1b2fcb9356a3 [widgets, js] add a InOutWidget for multiple select
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 6880
diff changeset
    67
.. autoclass:: cubicweb.web.formwidgets.InOutWidget
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    68
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    69
.. kill or document StaticFileAutoCompletionWidget
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    70
.. kill or document LazyRestrictedAutoCompletionWidget
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    71
.. kill or document RestrictedAutoCompletionWidget
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    72
6880
4be32427b2b9 [book] fixes some references and other doc construction pbs
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6682
diff changeset
    73
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    74
Other widgets
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    75
'''''''''''''
6880
4be32427b2b9 [book] fixes some references and other doc construction pbs
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6682
diff changeset
    76
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    77
.. autoclass:: cubicweb.web.formwidgets.PasswordInput
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    78
.. autoclass:: cubicweb.web.formwidgets.IntervalWidget
8029
805d4e121b65 [ui lib] facet and form widget for Integer used to store binary mask. Closes #2054771
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
    79
.. autoclass:: cubicweb.web.formwidgets.BitSelect
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    80
.. autoclass:: cubicweb.web.formwidgets.HorizontalLayoutWidget
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    81
.. autoclass:: cubicweb.web.formwidgets.EditableURLWidget
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    82
6880
4be32427b2b9 [book] fixes some references and other doc construction pbs
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6682
diff changeset
    83
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    84
Form controls
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    85
'''''''''''''
6880
4be32427b2b9 [book] fixes some references and other doc construction pbs
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6682
diff changeset
    86
4be32427b2b9 [book] fixes some references and other doc construction pbs
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6682
diff changeset
    87
Those classes are not proper widget (they are not associated to field) but are
4be32427b2b9 [book] fixes some references and other doc construction pbs
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6682
diff changeset
    88
used as form controls. Their API is similar to widgets except that `field`
4be32427b2b9 [book] fixes some references and other doc construction pbs
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6682
diff changeset
    89
argument given to :meth:`render` will be `None`.
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    90
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    91
.. autoclass:: cubicweb.web.formwidgets.Button
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    92
.. autoclass:: cubicweb.web.formwidgets.SubmitButton
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    93
.. autoclass:: cubicweb.web.formwidgets.ResetButton
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
    94
.. autoclass:: cubicweb.web.formwidgets.ImgButton
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
    95
"""
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
    96
__docformat__ = "restructuredtext en"
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
    97
8719
539ed3fb27cb [towards py3k] import reduce() from functools (part of #2711624)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8695
diff changeset
    98
from functools import reduce
1096
e1fe98850bf7 cleanup
sylvain.thenault@logilab.fr
parents: 1081
diff changeset
    99
from datetime import date
1966
87ce7d336393 stop using autocomplete_initfuncs dict on entity classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1934
diff changeset
   100
from warnings import warn
1096
e1fe98850bf7 cleanup
sylvain.thenault@logilab.fr
parents: 1081
diff changeset
   101
4160
3fbdeef9a610 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4159
diff changeset
   102
from logilab.mtconverter import xml_escape
3fbdeef9a610 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4159
diff changeset
   103
from logilab.common.deprecation import deprecated
4481
56440a1f816a hidden usage of datetime function which has been moved to lgc
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4392
diff changeset
   104
from logilab.common.date import todatetime
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   105
4481
56440a1f816a hidden usage of datetime function which has been moved to lgc
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4392
diff changeset
   106
from cubicweb import tags, uilib
6449
613d83588998 [formwidgets] rewrite autocomplete cw widgets to get rid of div-style declaration API
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6448
diff changeset
   107
from cubicweb.utils import json_dumps
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2549
diff changeset
   108
from cubicweb.web import stdmsgs, INTERNAL_FIELD_VALUE, ProcessFormError
1330
92343a468e2a add some documentation, backport *CompletionWidget
sylvain.thenault@logilab.fr
parents: 1329
diff changeset
   109
4583
356f08325072 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4550
diff changeset
   110
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   111
class FieldWidget(object):
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   112
    """The abstract base class for widgets.
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   113
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   114
    **Attributes**
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   115
7879
9aae456abab5 [pylint] fix pylint detected errors and tweak it so that pylint -E will be much less verbose next time (+ update some copyrights on the way)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7453
diff changeset
   116
    Here are standard attributes of a widget, that may be set on concrete class
9aae456abab5 [pylint] fix pylint detected errors and tweak it so that pylint -E will be much less verbose next time (+ update some copyrights on the way)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7453
diff changeset
   117
    to override default behaviours:
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   118
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   119
    :attr:`needs_js`
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   120
       list of javascript files needed by the widget.
6880
4be32427b2b9 [book] fixes some references and other doc construction pbs
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6682
diff changeset
   121
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   122
    :attr:`needs_css`
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   123
       list of css files needed by the widget.
6880
4be32427b2b9 [book] fixes some references and other doc construction pbs
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6682
diff changeset
   124
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   125
    :attr:`setdomid`
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   126
       flag telling if HTML DOM identifier should be set on input.
6880
4be32427b2b9 [book] fixes some references and other doc construction pbs
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6682
diff changeset
   127
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   128
    :attr:`settabindex`
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   129
       flag telling if HTML tabindex attribute of inputs should be set.
6880
4be32427b2b9 [book] fixes some references and other doc construction pbs
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6682
diff changeset
   130
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   131
    :attr:`suffix`
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   132
       string to use a suffix when generating input, to ease usage as a
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   133
       sub-widgets (eg widget used by another widget)
6880
4be32427b2b9 [book] fixes some references and other doc construction pbs
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6682
diff changeset
   134
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   135
    :attr:`vocabulary_widget`
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   136
       flag telling if this widget expect a vocabulary
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   137
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   138
    Also, widget instances takes as first argument a `attrs` dictionary which
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   139
    will be stored in the attribute of the same name. It contains HTML
7879
9aae456abab5 [pylint] fix pylint detected errors and tweak it so that pylint -E will be much less verbose next time (+ update some copyrights on the way)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7453
diff changeset
   140
    attributes that should be set in the widget's input tag (though concrete
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   141
    classes may ignore it).
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   142
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   143
    .. currentmodule:: cubicweb.web.formwidgets
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   144
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   145
    **Form generation methods**
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   146
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   147
    .. automethod:: render
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   148
    .. automethod:: _render
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   149
    .. automethod:: values
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   150
    .. automethod:: attributes
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   151
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   152
    **Post handling methods**
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   153
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   154
    .. automethod:: process_field_data
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   155
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   156
    """
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   157
    needs_js = ()
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   158
    needs_css = ()
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   159
    setdomid = True
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   160
    settabindex = True
4371
0d337feb5374 [forms] new optional suffix attribute on widget objects, used to generage input name / dom id.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4305
diff changeset
   161
    suffix = None
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: 1989
diff changeset
   162
    # does this widget expect a vocabulary
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: 1989
diff changeset
   163
    vocabulary_widget = False
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1425
diff changeset
   164
4371
0d337feb5374 [forms] new optional suffix attribute on widget objects, used to generage input name / dom id.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4305
diff changeset
   165
    def __init__(self, attrs=None, setdomid=None, settabindex=None, suffix=None):
1330
92343a468e2a add some documentation, backport *CompletionWidget
sylvain.thenault@logilab.fr
parents: 1329
diff changeset
   166
        if attrs is None:
92343a468e2a add some documentation, backport *CompletionWidget
sylvain.thenault@logilab.fr
parents: 1329
diff changeset
   167
            attrs = {}
92343a468e2a add some documentation, backport *CompletionWidget
sylvain.thenault@logilab.fr
parents: 1329
diff changeset
   168
        self.attrs = attrs
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   169
        if setdomid is not None:
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   170
            # override class's default value
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   171
            self.setdomid = setdomid
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   172
        if settabindex is not None:
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   173
            # override class's default value
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   174
            self.settabindex = settabindex
4371
0d337feb5374 [forms] new optional suffix attribute on widget objects, used to generage input name / dom id.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4305
diff changeset
   175
        if suffix is not None:
0d337feb5374 [forms] new optional suffix attribute on widget objects, used to generage input name / dom id.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4305
diff changeset
   176
            self.suffix = suffix
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   177
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   178
    def add_media(self, form):
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   179
        """adds media (CSS & JS) required by this widget"""
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   180
        if self.needs_js:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3388
diff changeset
   181
            form._cw.add_js(self.needs_js)
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   182
        if self.needs_css:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3388
diff changeset
   183
            form._cw.add_css(self.needs_css)
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1425
diff changeset
   184
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   185
    def render(self, form, field, renderer=None):
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   186
        """Called to render the widget for the given `field` in the given
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   187
        `form`.  Return a unicode string containing the HTML snippet.
4372
0c44af150a49 introduce a default render implementation on the base widget, which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4371
diff changeset
   188
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   189
        You will usually prefer to override the :meth:`_render` method so you
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   190
        don't have to handle addition of needed javascript / css files.
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   191
        """
4372
0c44af150a49 introduce a default render implementation on the base widget, which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4371
diff changeset
   192
        self.add_media(form)
0c44af150a49 introduce a default render implementation on the base widget, which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4371
diff changeset
   193
        return self._render(form, field, renderer)
0c44af150a49 introduce a default render implementation on the base widget, which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4371
diff changeset
   194
0c44af150a49 introduce a default render implementation on the base widget, which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4371
diff changeset
   195
    def _render(self, form, field, renderer):
7879
9aae456abab5 [pylint] fix pylint detected errors and tweak it so that pylint -E will be much less verbose next time (+ update some copyrights on the way)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7453
diff changeset
   196
        """This is the method you have to implement in concrete widget classes.
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   197
        """
4372
0c44af150a49 introduce a default render implementation on the base widget, which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4371
diff changeset
   198
        raise NotImplementedError()
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   199
4304
0b53e850cdb5 refactor field's value retreiving from the widget (eg 'display value' concept):
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   200
    def format_value(self, form, field, value):
0b53e850cdb5 refactor field's value retreiving from the widget (eg 'display value' concept):
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   201
        return field.format_value(form._cw, value)
0b53e850cdb5 refactor field's value retreiving from the widget (eg 'display value' concept):
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   202
5367
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5111
diff changeset
   203
    def attributes(self, form, field):
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5111
diff changeset
   204
        """Return HTML attributes for the widget, automatically setting DOM
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5111
diff changeset
   205
        identifier and tabindex when desired (see :attr:`setdomid` and
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5111
diff changeset
   206
        :attr:`settabindex` attributes)
4304
0b53e850cdb5 refactor field's value retreiving from the widget (eg 'display value' concept):
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   207
        """
4371
0d337feb5374 [forms] new optional suffix attribute on widget objects, used to generage input name / dom id.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4305
diff changeset
   208
        attrs = dict(self.attrs)
0d337feb5374 [forms] new optional suffix attribute on widget objects, used to generage input name / dom id.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4305
diff changeset
   209
        if self.setdomid:
0d337feb5374 [forms] new optional suffix attribute on widget objects, used to generage input name / dom id.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4305
diff changeset
   210
            attrs['id'] = field.dom_id(form, self.suffix)
0d337feb5374 [forms] new optional suffix attribute on widget objects, used to generage input name / dom id.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4305
diff changeset
   211
        if self.settabindex and not 'tabindex' in attrs:
0d337feb5374 [forms] new optional suffix attribute on widget objects, used to generage input name / dom id.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4305
diff changeset
   212
            attrs['tabindex'] = form._cw.next_tabindex()
9718
927d035b6921 [formfields] Handle 'placeholder' attribute for text and textarea
Christophe de Vienne <christophe@unlish.com>
parents: 9716
diff changeset
   213
        if 'placeholder' in attrs:
927d035b6921 [formfields] Handle 'placeholder' attribute for text and textarea
Christophe de Vienne <christophe@unlish.com>
parents: 9716
diff changeset
   214
            attrs['placeholder'] = form._cw._(attrs['placeholder'])
5367
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5111
diff changeset
   215
        return attrs
4371
0d337feb5374 [forms] new optional suffix attribute on widget objects, used to generage input name / dom id.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4305
diff changeset
   216
0d337feb5374 [forms] new optional suffix attribute on widget objects, used to generage input name / dom id.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4305
diff changeset
   217
    def values(self, form, field):
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   218
        """Return the current *string* values (i.e. for display in an HTML
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   219
        string) for the given field. This method returns a list of values since
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   220
        it's suitable for all kind of widgets, some of them taking multiple
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   221
        values, but you'll get a single value in the list in most cases.
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   222
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   223
        Those values are searched in:
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   224
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   225
        1. previously submitted form values if any (on validation error)
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   226
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   227
        2. req.form (specified using request parameters)
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   228
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   229
        3. extra form values given to form.render call (specified the code
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   230
           generating the form)
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   231
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   232
        4. field's typed value (returned by its
6880
4be32427b2b9 [book] fixes some references and other doc construction pbs
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6682
diff changeset
   233
           :meth:`~cubicweb.web.formfields.Field.typed_value` method)
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   234
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   235
        Values found in 1. and 2. are expected te be already some 'display
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   236
        value' (eg a string) while those found in 3. and 4. are expected to be
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   237
        correctly typed value.
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   238
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   239
        3 and 4 are handle by the :meth:`typed_value` method to ease reuse in
7879
9aae456abab5 [pylint] fix pylint detected errors and tweak it so that pylint -E will be much less verbose next time (+ update some copyrights on the way)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7453
diff changeset
   240
        concrete classes.
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   241
        """
4658
25de2eb0432b [form] add a new ignore_req_params attribute on field controlling value's retreival
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4627
diff changeset
   242
        values = None
25de2eb0432b [form] add a new ignore_req_params attribute on field controlling value's retreival
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4627
diff changeset
   243
        if not field.ignore_req_params:
25de2eb0432b [form] add a new ignore_req_params attribute on field controlling value's retreival
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4627
diff changeset
   244
            qname = field.input_name(form, self.suffix)
25de2eb0432b [form] add a new ignore_req_params attribute on field controlling value's retreival
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4627
diff changeset
   245
            # value from a previous post that has raised a validation error
25de2eb0432b [form] add a new ignore_req_params attribute on field controlling value's retreival
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4627
diff changeset
   246
            if qname in form.form_previous_values:
25de2eb0432b [form] add a new ignore_req_params attribute on field controlling value's retreival
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4627
diff changeset
   247
                values = form.form_previous_values[qname]
25de2eb0432b [form] add a new ignore_req_params attribute on field controlling value's retreival
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4627
diff changeset
   248
            # value specified using form parameters
25de2eb0432b [form] add a new ignore_req_params attribute on field controlling value's retreival
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4627
diff changeset
   249
            elif qname in form._cw.form:
25de2eb0432b [form] add a new ignore_req_params attribute on field controlling value's retreival
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4627
diff changeset
   250
                values = form._cw.form[qname]
25de2eb0432b [form] add a new ignore_req_params attribute on field controlling value's retreival
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4627
diff changeset
   251
            elif field.name != qname and field.name in form._cw.form:
25de2eb0432b [form] add a new ignore_req_params attribute on field controlling value's retreival
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4627
diff changeset
   252
                # XXX compat: accept attr=value in req.form to specify value of
25de2eb0432b [form] add a new ignore_req_params attribute on field controlling value's retreival
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4627
diff changeset
   253
                # attr-subject
25de2eb0432b [form] add a new ignore_req_params attribute on field controlling value's retreival
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4627
diff changeset
   254
                values = form._cw.form[field.name]
25de2eb0432b [form] add a new ignore_req_params attribute on field controlling value's retreival
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4627
diff changeset
   255
        if values is None:
4304
0b53e850cdb5 refactor field's value retreiving from the widget (eg 'display value' concept):
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   256
            values = self.typed_value(form, field)
0b53e850cdb5 refactor field's value retreiving from the widget (eg 'display value' concept):
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   257
            if values != INTERNAL_FIELD_VALUE:
0b53e850cdb5 refactor field's value retreiving from the widget (eg 'display value' concept):
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   258
                values = self.format_value(form, field, values)
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   259
        if not isinstance(values, (tuple, list)):
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   260
            values = (values,)
4371
0d337feb5374 [forms] new optional suffix attribute on widget objects, used to generage input name / dom id.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4305
diff changeset
   261
        return values
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   262
4660
21ed77792c33 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4658
diff changeset
   263
    def typed_value(self, form, field):
21ed77792c33 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4658
diff changeset
   264
        """return field's *typed* value specified in:
21ed77792c33 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4658
diff changeset
   265
        3. extra form values given to render()
21ed77792c33 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4658
diff changeset
   266
        4. field's typed value
21ed77792c33 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4658
diff changeset
   267
        """
21ed77792c33 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4658
diff changeset
   268
        qname = field.input_name(form)
21ed77792c33 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4658
diff changeset
   269
        for key in ((field, form), qname):
21ed77792c33 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4658
diff changeset
   270
            try:
21ed77792c33 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4658
diff changeset
   271
                return form.formvalues[key]
21ed77792c33 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4658
diff changeset
   272
            except KeyError:
21ed77792c33 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4658
diff changeset
   273
                continue
21ed77792c33 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4658
diff changeset
   274
        if field.name != qname and field.name in form.formvalues:
21ed77792c33 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4658
diff changeset
   275
            return form.formvalues[field.name]
21ed77792c33 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4658
diff changeset
   276
        return field.typed_value(form)
21ed77792c33 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4658
diff changeset
   277
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2549
diff changeset
   278
    def process_field_data(self, form, field):
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   279
        """Return process posted value(s) for widget and return something
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   280
        understandable by the associated `field`. That value may be correctly
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   281
        typed or a string that the field may parse.
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   282
        """
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3388
diff changeset
   283
        posted = form._cw.form
4371
0d337feb5374 [forms] new optional suffix attribute on widget objects, used to generage input name / dom id.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4305
diff changeset
   284
        val = posted.get(field.input_name(form, self.suffix))
4169
341d19ef7b7c strip string by default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4163
diff changeset
   285
        if isinstance(val, basestring):
4392
91a56a30141e by default this is not the widget responsability to turn empty string into None,
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4382
diff changeset
   286
            val = val.strip()
4163
b2747ed057e6 substitute _render_attrs by values_and_attributes method, keeping bw compat
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   287
        return val
b2747ed057e6 substitute _render_attrs by values_and_attributes method, keeping bw compat
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   288
5367
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5111
diff changeset
   289
    # XXX deprecates
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5111
diff changeset
   290
    def values_and_attributes(self, form, field):
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5111
diff changeset
   291
        return self.values(form, field), self.attributes(form, field)
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5111
diff changeset
   292
1096
e1fe98850bf7 cleanup
sylvain.thenault@logilab.fr
parents: 1081
diff changeset
   293
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   294
class Input(FieldWidget):
1330
92343a468e2a add some documentation, backport *CompletionWidget
sylvain.thenault@logilab.fr
parents: 1329
diff changeset
   295
    """abstract widget class for <input> tag based widgets"""
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   296
    type = None
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1425
diff changeset
   297
4372
0c44af150a49 introduce a default render implementation on the base widget, which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4371
diff changeset
   298
    def _render(self, form, field, renderer):
1330
92343a468e2a add some documentation, backport *CompletionWidget
sylvain.thenault@logilab.fr
parents: 1329
diff changeset
   299
        """render the widget for the given `field` of `form`.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1425
diff changeset
   300
1330
92343a468e2a add some documentation, backport *CompletionWidget
sylvain.thenault@logilab.fr
parents: 1329
diff changeset
   301
        Generate one <input> tag for each field's value
92343a468e2a add some documentation, backport *CompletionWidget
sylvain.thenault@logilab.fr
parents: 1329
diff changeset
   302
        """
4163
b2747ed057e6 substitute _render_attrs by values_and_attributes method, keeping bw compat
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   303
        values, attrs = self.values_and_attributes(form, field)
1768
b59b7c422a8a ensure input widgets are displayed anyway if they get an empty list as values
sylvain.thenault@logilab.fr
parents: 1749
diff changeset
   304
        # ensure something is rendered
b59b7c422a8a ensure input widgets are displayed anyway if they get an empty list as values
sylvain.thenault@logilab.fr
parents: 1749
diff changeset
   305
        if not values:
b59b7c422a8a ensure input widgets are displayed anyway if they get an empty list as values
sylvain.thenault@logilab.fr
parents: 1749
diff changeset
   306
            values = (INTERNAL_FIELD_VALUE,)
4371
0d337feb5374 [forms] new optional suffix attribute on widget objects, used to generage input name / dom id.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4305
diff changeset
   307
        inputs = [tags.input(name=field.input_name(form, self.suffix),
0d337feb5374 [forms] new optional suffix attribute on widget objects, used to generage input name / dom id.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4305
diff changeset
   308
                             type=self.type, value=value, **attrs)
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   309
                  for value in values]
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   310
        return u'\n'.join(inputs)
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   311
1096
e1fe98850bf7 cleanup
sylvain.thenault@logilab.fr
parents: 1081
diff changeset
   312
1330
92343a468e2a add some documentation, backport *CompletionWidget
sylvain.thenault@logilab.fr
parents: 1329
diff changeset
   313
# basic html widgets ###########################################################
92343a468e2a add some documentation, backport *CompletionWidget
sylvain.thenault@logilab.fr
parents: 1329
diff changeset
   314
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   315
class TextInput(Input):
9701
46c8d8701240 an unicode string -> a unicode string
Rémi Cardona <remi.cardona@logilab.fr>
parents: 9700
diff changeset
   316
    """Simple <input type='text'>, will return a unicode string."""
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   317
    type = 'text'
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   318
1096
e1fe98850bf7 cleanup
sylvain.thenault@logilab.fr
parents: 1081
diff changeset
   319
9716
c44224387028 [widget] Addition of EmailInput
Alain Begey <alain@unlish.com>
parents: 9377
diff changeset
   320
class EmailInput(Input):
c44224387028 [widget] Addition of EmailInput
Alain Begey <alain@unlish.com>
parents: 9377
diff changeset
   321
    """Simple <input type='email'>, will return a unicode string."""
c44224387028 [widget] Addition of EmailInput
Alain Begey <alain@unlish.com>
parents: 9377
diff changeset
   322
    type = 'email'
c44224387028 [widget] Addition of EmailInput
Alain Begey <alain@unlish.com>
parents: 9377
diff changeset
   323
c44224387028 [widget] Addition of EmailInput
Alain Begey <alain@unlish.com>
parents: 9377
diff changeset
   324
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   325
class PasswordSingleInput(Input):
9703
79ad734ca4d3 an utf-8 -> a utf-8
Rémi Cardona <remi.cardona@logilab.fr>
parents: 9701
diff changeset
   326
    """Simple <input type='password'>, will return a utf-8 encoded string.
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   327
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   328
    You may prefer using the :class:`~cubicweb.web.formwidgets.PasswordInput`
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   329
    widget which handles password confirmation.
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   330
    """
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   331
    type = 'password'
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   332
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   333
    def process_field_data(self, form, field):
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   334
        value = super(PasswordSingleInput, self).process_field_data(form, field)
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   335
        if value is not None:
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   336
            return value.encode('utf-8')
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   337
        return value
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   338
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   339
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   340
class PasswordInput(Input):
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   341
    """<input type='password'> and a confirmation input. Form processing will
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   342
    fail if password and confirmation differs, else it will return the password
9703
79ad734ca4d3 an utf-8 -> a utf-8
Rémi Cardona <remi.cardona@logilab.fr>
parents: 9701
diff changeset
   343
    as a utf-8 encoded string.
1330
92343a468e2a add some documentation, backport *CompletionWidget
sylvain.thenault@logilab.fr
parents: 1329
diff changeset
   344
    """
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   345
    type = 'password'
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1425
diff changeset
   346
4372
0c44af150a49 introduce a default render implementation on the base widget, which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4371
diff changeset
   347
    def _render(self, form, field, renderer):
0c44af150a49 introduce a default render implementation on the base widget, which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4371
diff changeset
   348
        assert self.suffix is None, 'suffix not supported'
4163
b2747ed057e6 substitute _render_attrs by values_and_attributes method, keeping bw compat
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   349
        values, attrs = self.values_and_attributes(form, field)
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   350
        assert len(values) == 1
4627
54de0ddd0bf3 minor cleanup: don't use builtin 'id' as variable name
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4597
diff changeset
   351
        domid = attrs.pop('id')
4156
1bbb0ee42c8e drop form_field_name/form_field_id methods from form object, in favor of field.input_name(form) / field.dom_id(form)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4023
diff changeset
   352
        inputs = [tags.input(name=field.input_name(form),
4627
54de0ddd0bf3 minor cleanup: don't use builtin 'id' as variable name
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4597
diff changeset
   353
                             value=values[0], type=self.type, id=domid, **attrs),
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   354
                  '<br/>',
4156
1bbb0ee42c8e drop form_field_name/form_field_id methods from form object, in favor of field.input_name(form) / field.dom_id(form)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4023
diff changeset
   355
                  tags.input(name=field.input_name(form, '-confirm'),
1bbb0ee42c8e drop form_field_name/form_field_id methods from form object, in favor of field.input_name(form) / field.dom_id(form)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4023
diff changeset
   356
                             value=values[0], type=self.type, **attrs),
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3388
diff changeset
   357
                  '&#160;', tags.span(form._cw._('confirm password'),
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   358
                                      **{'class': 'emphasis'})]
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   359
        return u'\n'.join(inputs)
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   360
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2549
diff changeset
   361
    def process_field_data(self, form, field):
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2549
diff changeset
   362
        passwd1 = super(PasswordInput, self).process_field_data(form, field)
4156
1bbb0ee42c8e drop form_field_name/form_field_id methods from form object, in favor of field.input_name(form) / field.dom_id(form)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4023
diff changeset
   363
        passwd2 = form._cw.form.get(field.input_name(form, '-confirm'))
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2549
diff changeset
   364
        if passwd1 == passwd2:
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2549
diff changeset
   365
            if passwd1 is None:
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2549
diff changeset
   366
                return None
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2549
diff changeset
   367
            return passwd1.encode('utf-8')
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3388
diff changeset
   368
        raise ProcessFormError(form._cw._("password and confirmation don't match"))
1096
e1fe98850bf7 cleanup
sylvain.thenault@logilab.fr
parents: 1081
diff changeset
   369
e1fe98850bf7 cleanup
sylvain.thenault@logilab.fr
parents: 1081
diff changeset
   370
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   371
class FileInput(Input):
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   372
    """Simple <input type='file'>, will return a tuple (name, stream) where
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   373
    name is the posted file name and stream a file like object containing the
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   374
    posted file data.
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   375
    """
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   376
    type = 'file'
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1425
diff changeset
   377
5367
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5111
diff changeset
   378
    def values(self, form, field):
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   379
        # ignore value which makes no sense here (XXX even on form validation error?)
5367
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5111
diff changeset
   380
        return ('',)
1096
e1fe98850bf7 cleanup
sylvain.thenault@logilab.fr
parents: 1081
diff changeset
   381
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1425
diff changeset
   382
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   383
class HiddenInput(Input):
9701
46c8d8701240 an unicode string -> a unicode string
Rémi Cardona <remi.cardona@logilab.fr>
parents: 9700
diff changeset
   384
    """Simple <input type='hidden'> for hidden value, will return a unicode
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   385
    string.
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   386
    """
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   387
    type = 'hidden'
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   388
    setdomid = False # by default, don't set id attribute on hidden input
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   389
    settabindex = False
1096
e1fe98850bf7 cleanup
sylvain.thenault@logilab.fr
parents: 1081
diff changeset
   390
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1425
diff changeset
   391
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   392
class ButtonInput(Input):
9701
46c8d8701240 an unicode string -> a unicode string
Rémi Cardona <remi.cardona@logilab.fr>
parents: 9700
diff changeset
   393
    """Simple <input type='button'>, will return a unicode string.
1330
92343a468e2a add some documentation, backport *CompletionWidget
sylvain.thenault@logilab.fr
parents: 1329
diff changeset
   394
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   395
    If you want a global form button, look at the :class:`Button`,
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   396
    :class:`SubmitButton`, :class:`ResetButton` and :class:`ImgButton` below.
1330
92343a468e2a add some documentation, backport *CompletionWidget
sylvain.thenault@logilab.fr
parents: 1329
diff changeset
   397
    """
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   398
    type = 'button'
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   399
1096
e1fe98850bf7 cleanup
sylvain.thenault@logilab.fr
parents: 1081
diff changeset
   400
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   401
class TextArea(FieldWidget):
9701
46c8d8701240 an unicode string -> a unicode string
Rémi Cardona <remi.cardona@logilab.fr>
parents: 9700
diff changeset
   402
    """Simple <textarea>, will return a unicode string."""
2366
e4229723b824 [formwidgets] let the textarea height be dependant on the actual content (up to a limit)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2360
diff changeset
   403
4372
0c44af150a49 introduce a default render implementation on the base widget, which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4371
diff changeset
   404
    def _render(self, form, field, renderer):
4163
b2747ed057e6 substitute _render_attrs by values_and_attributes method, keeping bw compat
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   405
        values, attrs = self.values_and_attributes(form, field)
2131
00e6d1cb18ea [views] call autogrow only once per key event
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2091
diff changeset
   406
        attrs.setdefault('onkeyup', 'autogrow(this)')
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   407
        if not values:
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   408
            value = u''
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   409
        elif len(values) == 1:
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   410
            value = values[0]
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   411
        else:
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   412
            raise ValueError('a textarea is not supposed to be multivalued')
2366
e4229723b824 [formwidgets] let the textarea height be dependant on the actual content (up to a limit)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2360
diff changeset
   413
        lines = value.splitlines()
e4229723b824 [formwidgets] let the textarea height be dependant on the actual content (up to a limit)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2360
diff changeset
   414
        linecount = len(lines)
e4229723b824 [formwidgets] let the textarea height be dependant on the actual content (up to a limit)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2360
diff changeset
   415
        for line in lines:
e4229723b824 [formwidgets] let the textarea height be dependant on the actual content (up to a limit)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2360
diff changeset
   416
            linecount += len(line) / 80
e4229723b824 [formwidgets] let the textarea height be dependant on the actual content (up to a limit)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2360
diff changeset
   417
        attrs.setdefault('cols', 80)
e4229723b824 [formwidgets] let the textarea height be dependant on the actual content (up to a limit)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2360
diff changeset
   418
        attrs.setdefault('rows', min(15, linecount + 2))
4371
0d337feb5374 [forms] new optional suffix attribute on widget objects, used to generage input name / dom id.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4305
diff changeset
   419
        return tags.textarea(value, name=field.input_name(form, self.suffix),
0d337feb5374 [forms] new optional suffix attribute on widget objects, used to generage input name / dom id.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4305
diff changeset
   420
                             **attrs)
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   421
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   422
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   423
class FCKEditor(TextArea):
9701
46c8d8701240 an unicode string -> a unicode string
Rémi Cardona <remi.cardona@logilab.fr>
parents: 9700
diff changeset
   424
    """FCKEditor enabled <textarea>, will return a unicode string containing
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   425
    HTML formated text.
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   426
    """
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   427
    def __init__(self, *args, **kwargs):
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   428
        super(FCKEditor, self).__init__(*args, **kwargs)
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   429
        self.attrs['cubicweb:type'] = 'wysiwyg'
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1425
diff changeset
   430
4372
0c44af150a49 introduce a default render implementation on the base widget, which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4371
diff changeset
   431
    def _render(self, form, field, renderer):
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3388
diff changeset
   432
        form._cw.fckeditor_config()
4372
0c44af150a49 introduce a default render implementation on the base widget, which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4371
diff changeset
   433
        return super(FCKEditor, self)._render(form, field, renderer)
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   434
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   435
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   436
class Select(FieldWidget):
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   437
    """Simple <select>, for field having a specific vocabulary. Will return
9701
46c8d8701240 an unicode string -> a unicode string
Rémi Cardona <remi.cardona@logilab.fr>
parents: 9700
diff changeset
   438
    a unicode string, or a list of unicode strings.
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   439
    """
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: 1989
diff changeset
   440
    vocabulary_widget = True
8193
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   441
    default_size = 10
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: 1989
diff changeset
   442
4975
35b0dd80dc06 [widget] allow kwargs passed to Select widget
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4901
diff changeset
   443
    def __init__(self, attrs=None, multiple=False, **kwargs):
35b0dd80dc06 [widget] allow kwargs passed to Select widget
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4901
diff changeset
   444
        super(Select, self).__init__(attrs, **kwargs)
1541
ddddbb748355 [widgets] an option for Select to show sorted content
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1538
diff changeset
   445
        self._multiple = multiple
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1425
diff changeset
   446
5367
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5111
diff changeset
   447
    def _render(self, form, field, renderer):
4163
b2747ed057e6 substitute _render_attrs by values_and_attributes method, keeping bw compat
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   448
        curvalues, attrs = self.values_and_attributes(form, field)
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   449
        options = []
1771
bb9538d91465 fix <optgroup> tag cannot be empty according to DTD
Florent <florent@secondweb.fr>
parents: 1768
diff changeset
   450
        optgroup_opened = False
7453
84046395d2cd Fix name error introduced in c21d845836e4
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7450
diff changeset
   451
        vocab = field.vocabulary(form)
84046395d2cd Fix name error introduced in c21d845836e4
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7450
diff changeset
   452
        for option in vocab:
2518
38c28ee40138 allow vocabulary functions to return either label/value or label/value/dict (to use as attributes of the tag for this input)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2366
diff changeset
   453
            try:
38c28ee40138 allow vocabulary functions to return either label/value or label/value/dict (to use as attributes of the tag for this input)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2366
diff changeset
   454
                label, value, oattrs = option
38c28ee40138 allow vocabulary functions to return either label/value or label/value/dict (to use as attributes of the tag for this input)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2366
diff changeset
   455
            except ValueError:
38c28ee40138 allow vocabulary functions to return either label/value or label/value/dict (to use as attributes of the tag for this input)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2366
diff changeset
   456
                label, value = option
38c28ee40138 allow vocabulary functions to return either label/value or label/value/dict (to use as attributes of the tag for this input)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2366
diff changeset
   457
                oattrs = {}
1336
2e552353c42a insert an optgroup as separator on None values
sylvain.thenault@logilab.fr
parents: 1330
diff changeset
   458
            if value is None:
2e552353c42a insert an optgroup as separator on None values
sylvain.thenault@logilab.fr
parents: 1330
diff changeset
   459
                # handle separator
1771
bb9538d91465 fix <optgroup> tag cannot be empty according to DTD
Florent <florent@secondweb.fr>
parents: 1768
diff changeset
   460
                if optgroup_opened:
bb9538d91465 fix <optgroup> tag cannot be empty according to DTD
Florent <florent@secondweb.fr>
parents: 1768
diff changeset
   461
                    options.append(u'</optgroup>')
2518
38c28ee40138 allow vocabulary functions to return either label/value or label/value/dict (to use as attributes of the tag for this input)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2366
diff changeset
   462
                oattrs.setdefault('label', label or '')
38c28ee40138 allow vocabulary functions to return either label/value or label/value/dict (to use as attributes of the tag for this input)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2366
diff changeset
   463
                options.append(u'<optgroup %s>' % uilib.sgml_attributes(oattrs))
1771
bb9538d91465 fix <optgroup> tag cannot be empty according to DTD
Florent <florent@secondweb.fr>
parents: 1768
diff changeset
   464
                optgroup_opened = True
8029
805d4e121b65 [ui lib] facet and form widget for Integer used to store binary mask. Closes #2054771
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   465
            elif self.value_selected(value, curvalues):
2518
38c28ee40138 allow vocabulary functions to return either label/value or label/value/dict (to use as attributes of the tag for this input)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2366
diff changeset
   466
                options.append(tags.option(label, value=value,
38c28ee40138 allow vocabulary functions to return either label/value or label/value/dict (to use as attributes of the tag for this input)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2366
diff changeset
   467
                                           selected='selected', **oattrs))
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   468
            else:
2518
38c28ee40138 allow vocabulary functions to return either label/value or label/value/dict (to use as attributes of the tag for this input)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2366
diff changeset
   469
                options.append(tags.option(label, value=value, **oattrs))
1771
bb9538d91465 fix <optgroup> tag cannot be empty according to DTD
Florent <florent@secondweb.fr>
parents: 1768
diff changeset
   470
        if optgroup_opened:
bb9538d91465 fix <optgroup> tag cannot be empty according to DTD
Florent <florent@secondweb.fr>
parents: 1768
diff changeset
   471
            options.append(u'</optgroup>')
7450
c21d845836e4 [formwidgets] make the select size a class attribute (more easily tuned)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7411
diff changeset
   472
        if not 'size' in attrs:
c21d845836e4 [formwidgets] make the select size a class attribute (more easily tuned)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7411
diff changeset
   473
            if self._multiple:
c21d845836e4 [formwidgets] make the select size a class attribute (more easily tuned)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7411
diff changeset
   474
                size = unicode(min(self.default_size, len(vocab) or 1))
c21d845836e4 [formwidgets] make the select size a class attribute (more easily tuned)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7411
diff changeset
   475
            else:
c21d845836e4 [formwidgets] make the select size a class attribute (more easily tuned)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7411
diff changeset
   476
                size = u'1'
c21d845836e4 [formwidgets] make the select size a class attribute (more easily tuned)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7411
diff changeset
   477
            attrs['size'] = size
4371
0d337feb5374 [forms] new optional suffix attribute on widget objects, used to generage input name / dom id.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4305
diff changeset
   478
        return tags.select(name=field.input_name(form, self.suffix),
0d337feb5374 [forms] new optional suffix attribute on widget objects, used to generage input name / dom id.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4305
diff changeset
   479
                           multiple=self._multiple, options=options, **attrs)
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   480
8029
805d4e121b65 [ui lib] facet and form widget for Integer used to store binary mask. Closes #2054771
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   481
    def value_selected(self, value, curvalues):
805d4e121b65 [ui lib] facet and form widget for Integer used to store binary mask. Closes #2054771
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   482
        return value in curvalues
805d4e121b65 [ui lib] facet and form widget for Integer used to store binary mask. Closes #2054771
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   483
805d4e121b65 [ui lib] facet and form widget for Integer used to store binary mask. Closes #2054771
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   484
8193
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   485
class InOutWidget(Select):
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   486
    needs_js = ('cubicweb.widgets.js', )
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   487
    default_size = 10
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   488
    template = """
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   489
<table id="%(widgetid)s">
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   490
  <tr>
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   491
    <td>%(inoutinput)s</td>
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   492
    <td><div style="margin-bottom:3px">%(addinput)s</div>
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   493
        <div>%(removeinput)s</div>
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   494
    </td>
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   495
    <td>%(resinput)s</td>
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   496
  </tr>
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   497
</table>
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   498
"""
8936
010adc548b97 [form] remove hard coded id
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8732
diff changeset
   499
    add_button = ('<input type="button" class="wdgButton cwinoutadd" '
8193
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   500
                  'value="&gt;&gt;" size="10" />')
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   501
    remove_button = ('<input type="button" class="wdgButton cwinoutremove" '
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   502
                     'value="&lt;&lt;" size="10" />')
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   503
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   504
    def __init__(self, *args, **kwargs):
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   505
        super(InOutWidget, self).__init__(*args, **kwargs)
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   506
        self._multiple = True
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   507
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   508
    def render_select(self, form, field, name, selected=False):
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   509
        values, attrs = self.values_and_attributes(form, field)
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   510
        options = []
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   511
        inputs = []
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   512
        for option in field.vocabulary(form):
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   513
            try:
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   514
                label, value, _oattrs = option
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   515
            except ValueError:
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   516
                label, value = option
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   517
            if selected:
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   518
                # add values
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   519
                if value in values:
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   520
                    options.append(tags.option(label, value=value))
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   521
                    # add hidden inputs
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   522
                    inputs.append(tags.input(value=value,
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   523
                                             name=field.dom_id(form),
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   524
                                             type="hidden"))
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   525
            else:
9377
4e0d8f06efbc [js/widgets] fix the InOut widget with modern jQuery versions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9255
diff changeset
   526
                if value not in values:
4e0d8f06efbc [js/widgets] fix the InOut widget with modern jQuery versions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9255
diff changeset
   527
                    options.append(tags.option(label, value=value))
8193
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   528
        if 'size' not in attrs:
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   529
            attrs['size'] = self.default_size
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   530
        if 'id' in attrs :
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   531
            attrs.pop('id')
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   532
        return tags.select(name=name, multiple=self._multiple, id=name,
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   533
                           options=options, **attrs) + '\n'.join(inputs)
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   534
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   535
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   536
    def _render(self, form, field, renderer):
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   537
        domid = field.dom_id(form)
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   538
        jsnodes = {'widgetid': domid,
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   539
                   'from': 'from_' + domid,
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   540
                   'to': 'to_' + domid}
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   541
        form._cw.add_onload(u'$(cw.jqNode("%s")).cwinoutwidget("%s", "%s");'
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   542
                            % (jsnodes['widgetid'], jsnodes['from'], jsnodes['to']))
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   543
        field.required = True
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   544
        return (self.template %
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   545
                {'widgetid': jsnodes['widgetid'],
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   546
                 # helpinfo select tag
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   547
                 'inoutinput' : self.render_select(form, field, jsnodes['from']),
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   548
                 # select tag with resultats
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   549
                 'resinput' : self.render_select(form, field, jsnodes['to'], selected=True),
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   550
                 'addinput' : self.add_button % jsnodes,
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   551
                 'removeinput': self.remove_button % jsnodes
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   552
                 })
0c64d6b75303 [web/formwidgets] make default_size a tunable, fix code layout (closes #2165936)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8029
diff changeset
   553
9222
ec65ca70aac9 [date picker widgets] use bare jquery expression rather than jqNode
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9134
diff changeset
   554
8029
805d4e121b65 [ui lib] facet and form widget for Integer used to store binary mask. Closes #2054771
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   555
class BitSelect(Select):
805d4e121b65 [ui lib] facet and form widget for Integer used to store binary mask. Closes #2054771
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   556
    """Select widget for IntField using a vocabulary with bit masks as values.
805d4e121b65 [ui lib] facet and form widget for Integer used to store binary mask. Closes #2054771
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   557
805d4e121b65 [ui lib] facet and form widget for Integer used to store binary mask. Closes #2054771
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   558
    See also :class:`~cubicweb.web.facet.BitFieldFacet`.
805d4e121b65 [ui lib] facet and form widget for Integer used to store binary mask. Closes #2054771
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   559
    """
805d4e121b65 [ui lib] facet and form widget for Integer used to store binary mask. Closes #2054771
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   560
    def __init__(self, attrs=None, multiple=True, **kwargs):
805d4e121b65 [ui lib] facet and form widget for Integer used to store binary mask. Closes #2054771
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   561
        super(BitSelect, self).__init__(attrs, multiple=multiple, **kwargs)
805d4e121b65 [ui lib] facet and form widget for Integer used to store binary mask. Closes #2054771
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   562
805d4e121b65 [ui lib] facet and form widget for Integer used to store binary mask. Closes #2054771
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   563
    def value_selected(self, value, curvalues):
805d4e121b65 [ui lib] facet and form widget for Integer used to store binary mask. Closes #2054771
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   564
        mask = reduce(lambda x, y: int(x) | int(y), curvalues, 0)
805d4e121b65 [ui lib] facet and form widget for Integer used to store binary mask. Closes #2054771
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   565
        return int(value) & mask
805d4e121b65 [ui lib] facet and form widget for Integer used to store binary mask. Closes #2054771
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   566
805d4e121b65 [ui lib] facet and form widget for Integer used to store binary mask. Closes #2054771
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   567
    def process_field_data(self, form, field):
805d4e121b65 [ui lib] facet and form widget for Integer used to store binary mask. Closes #2054771
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   568
        """Return process posted value(s) for widget and return something
805d4e121b65 [ui lib] facet and form widget for Integer used to store binary mask. Closes #2054771
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   569
        understandable by the associated `field`. That value may be correctly
805d4e121b65 [ui lib] facet and form widget for Integer used to store binary mask. Closes #2054771
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   570
        typed or a string that the field may parse.
805d4e121b65 [ui lib] facet and form widget for Integer used to store binary mask. Closes #2054771
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   571
        """
805d4e121b65 [ui lib] facet and form widget for Integer used to store binary mask. Closes #2054771
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   572
        val = super(BitSelect, self).process_field_data(form, field)
805d4e121b65 [ui lib] facet and form widget for Integer used to store binary mask. Closes #2054771
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   573
        if isinstance(val, list):
805d4e121b65 [ui lib] facet and form widget for Integer used to store binary mask. Closes #2054771
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   574
            val = reduce(lambda x, y: int(x) | int(y), val, 0)
805d4e121b65 [ui lib] facet and form widget for Integer used to store binary mask. Closes #2054771
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   575
        elif val:
805d4e121b65 [ui lib] facet and form widget for Integer used to store binary mask. Closes #2054771
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   576
            val = int(val)
805d4e121b65 [ui lib] facet and form widget for Integer used to store binary mask. Closes #2054771
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   577
        else:
805d4e121b65 [ui lib] facet and form widget for Integer used to store binary mask. Closes #2054771
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   578
            val = 0
805d4e121b65 [ui lib] facet and form widget for Integer used to store binary mask. Closes #2054771
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   579
        return val
805d4e121b65 [ui lib] facet and form widget for Integer used to store binary mask. Closes #2054771
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   580
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   581
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   582
class CheckBox(Input):
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   583
    """Simple <input type='checkbox'>, for field having a specific
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   584
    vocabulary. One input will be generated for each possible value.
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   585
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   586
    You can specify separator using the `separator` constructor argument, by
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   587
    default <br/> is used.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1425
diff changeset
   588
    """
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   589
    type = 'checkbox'
7231
18bcb98d129a [widgets] handle no value label for tristate radios, put default separator on class for easier redefinition - closes #1624839
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7115
diff changeset
   590
    default_separator = u'<br/>\n'
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: 1989
diff changeset
   591
    vocabulary_widget = True
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1425
diff changeset
   592
7231
18bcb98d129a [widgets] handle no value label for tristate radios, put default separator on class for easier redefinition - closes #1624839
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7115
diff changeset
   593
    def __init__(self, attrs=None, separator=None, **kwargs):
5367
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5111
diff changeset
   594
        super(CheckBox, self).__init__(attrs, **kwargs)
7231
18bcb98d129a [widgets] handle no value label for tristate radios, put default separator on class for easier redefinition - closes #1624839
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7115
diff changeset
   595
        self.separator = separator or self.default_separator
5367
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5111
diff changeset
   596
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5111
diff changeset
   597
    def _render(self, form, field, renderer):
4163
b2747ed057e6 substitute _render_attrs by values_and_attributes method, keeping bw compat
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   598
        curvalues, attrs = self.values_and_attributes(form, field)
1367
01bb5b727fe3 set dom id on the first input of radio choices
sylvain.thenault@logilab.fr
parents: 1359
diff changeset
   599
        domid = attrs.pop('id', None)
9255
46f41c3e1443 remove 3.8 bw compat
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9247
diff changeset
   600
        sep = self.separator
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   601
        options = []
2518
38c28ee40138 allow vocabulary functions to return either label/value or label/value/dict (to use as attributes of the tag for this input)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2366
diff changeset
   602
        for i, option in enumerate(field.vocabulary(form)):
38c28ee40138 allow vocabulary functions to return either label/value or label/value/dict (to use as attributes of the tag for this input)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2366
diff changeset
   603
            try:
38c28ee40138 allow vocabulary functions to return either label/value or label/value/dict (to use as attributes of the tag for this input)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2366
diff changeset
   604
                label, value, oattrs = option
38c28ee40138 allow vocabulary functions to return either label/value or label/value/dict (to use as attributes of the tag for this input)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2366
diff changeset
   605
            except ValueError:
38c28ee40138 allow vocabulary functions to return either label/value or label/value/dict (to use as attributes of the tag for this input)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2366
diff changeset
   606
                label, value = option
38c28ee40138 allow vocabulary functions to return either label/value or label/value/dict (to use as attributes of the tag for this input)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2366
diff changeset
   607
                oattrs = {}
1367
01bb5b727fe3 set dom id on the first input of radio choices
sylvain.thenault@logilab.fr
parents: 1359
diff changeset
   608
            iattrs = attrs.copy()
2518
38c28ee40138 allow vocabulary functions to return either label/value or label/value/dict (to use as attributes of the tag for this input)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2366
diff changeset
   609
            iattrs.update(oattrs)
1367
01bb5b727fe3 set dom id on the first input of radio choices
sylvain.thenault@logilab.fr
parents: 1359
diff changeset
   610
            if i == 0 and domid is not None:
2518
38c28ee40138 allow vocabulary functions to return either label/value or label/value/dict (to use as attributes of the tag for this input)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2366
diff changeset
   611
                iattrs.setdefault('id', domid)
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   612
            if value in curvalues:
1367
01bb5b727fe3 set dom id on the first input of radio choices
sylvain.thenault@logilab.fr
parents: 1359
diff changeset
   613
                iattrs['checked'] = u'checked'
4371
0d337feb5374 [forms] new optional suffix attribute on widget objects, used to generage input name / dom id.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4305
diff changeset
   614
            tag = tags.input(name=field.input_name(form, self.suffix),
0d337feb5374 [forms] new optional suffix attribute on widget objects, used to generage input name / dom id.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4305
diff changeset
   615
                             type=self.type, value=value, **iattrs)
4593
d0b5ef72a492 add space between a checkbox and its label
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4583
diff changeset
   616
            options.append(u'%s&#160;%s' % (tag, label))
2519
ac1a869e1e93 nicer checkbox widget implementation, avoid extra <br/> at the end
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2518
diff changeset
   617
        return sep.join(options)
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   618
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   619
1832
3384264d25cc fix CheckBox multiple dom id and refactor with Radio
Florent <florent@secondweb.fr>
parents: 1771
diff changeset
   620
class Radio(CheckBox):
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   621
    """Simle <input type='radio'>, for field having a specific vocabulary. One
1832
3384264d25cc fix CheckBox multiple dom id and refactor with Radio
Florent <florent@secondweb.fr>
parents: 1771
diff changeset
   622
    input will be generated for each possible value.
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   623
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   624
    You can specify separator using the `separator` constructor argument, by
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   625
    default <br/> is used.
1832
3384264d25cc fix CheckBox multiple dom id and refactor with Radio
Florent <florent@secondweb.fr>
parents: 1771
diff changeset
   626
    """
3384264d25cc fix CheckBox multiple dom id and refactor with Radio
Florent <florent@secondweb.fr>
parents: 1771
diff changeset
   627
    type = 'radio'
5384
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
   628
2523
1d245fbbeb90 some new field/widgets classes: CompoundField, IntervalWidget, HorizontalLayoutWidget
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2522
diff changeset
   629
1330
92343a468e2a add some documentation, backport *CompletionWidget
sylvain.thenault@logilab.fr
parents: 1329
diff changeset
   630
# javascript widgets ###########################################################
92343a468e2a add some documentation, backport *CompletionWidget
sylvain.thenault@logilab.fr
parents: 1329
diff changeset
   631
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   632
class DateTimePicker(TextInput):
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   633
    """<input type='text'> + javascript date/time picker for date or datetime
9701
46c8d8701240 an unicode string -> a unicode string
Rémi Cardona <remi.cardona@logilab.fr>
parents: 9700
diff changeset
   634
    fields. Will return the date or datetime as a unicode string.
1330
92343a468e2a add some documentation, backport *CompletionWidget
sylvain.thenault@logilab.fr
parents: 1329
diff changeset
   635
    """
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   636
    monthnames = ('january', 'february', 'march', 'april',
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   637
                  'may', 'june', 'july', 'august',
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   638
                  'september', 'october', 'november', 'december')
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   639
    daynames = ('monday', 'tuesday', 'wednesday', 'thursday',
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   640
                'friday', 'saturday', 'sunday')
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   641
1311
4cc6e2723dc7 move ajax.js to base form class
sylvain.thenault@logilab.fr
parents: 1304
diff changeset
   642
    needs_js = ('cubicweb.calendar.js',)
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   643
    needs_css = ('cubicweb.calendar_popup.css',)
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1425
diff changeset
   644
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   645
    @classmethod
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   646
    def add_localized_infos(cls, req):
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   647
        """inserts JS variables defining localized months and days"""
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   648
        _ = req._
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   649
        monthnames = [_(mname) for mname in cls.monthnames]
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   650
        daynames = [_(dname) for dname in cls.daynames]
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   651
        req.html_headers.define_var('MONTHNAMES', monthnames)
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   652
        req.html_headers.define_var('DAYNAMES', daynames)
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1425
diff changeset
   653
5367
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5111
diff changeset
   654
    def _render(self, form, field, renderer):
5383
fbe7416104c6 [widgets] fix super calls, bug introduced in 5367:4176a50c81c9
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5377
diff changeset
   655
        txtwidget = super(DateTimePicker, self)._render(form, field, renderer)
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3388
diff changeset
   656
        self.add_localized_infos(form._cw)
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   657
        cal_button = self._render_calendar_popup(form, field)
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   658
        return txtwidget + cal_button
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1425
diff changeset
   659
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   660
    def _render_calendar_popup(self, form, field):
4159
6b2b20c73d59 refactor form field value handling, to get a nicer api and an easier algorithm to get field's value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4156
diff changeset
   661
        value = field.typed_value(form)
1392
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1389
diff changeset
   662
        if not value:
d6279efff7b3 refactor the way field value/display value are handled to avoid getting a 'display' value when expected a 'typed' value
sylvain.thenault@logilab.fr
parents: 1389
diff changeset
   663
            value = date.today()
4156
1bbb0ee42c8e drop form_field_name/form_field_id methods from form object, in favor of field.input_name(form) / field.dom_id(form)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4023
diff changeset
   664
        inputid = field.dom_id(form)
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   665
        helperid = '%shelper' % inputid
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   666
        year, month = value.year, value.month
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   667
        return (u"""<a onclick="toggleCalendar('%s', '%s', %s, %s);" class="calhelper">
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   668
<img src="%s" title="%s" alt="" /></a><div class="calpopup hidden" id="%s"></div>"""
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   669
                % (helperid, inputid, year, month,
5467
57372dbfd114 [https] fix resource urls in https version of a site: should use the https version as well to avoid warnings from the nrowser
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5453
diff changeset
   670
                   form._cw.uiprops['CALENDAR_ICON'],
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3388
diff changeset
   671
                   form._cw._('calendar'), helperid) )
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   672
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1425
diff changeset
   673
4373
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   674
class JQueryDatePicker(FieldWidget):
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   675
    """Use jquery.ui.datepicker to define a date picker. Will return the date as
9701
46c8d8701240 an unicode string -> a unicode string
Rémi Cardona <remi.cardona@logilab.fr>
parents: 9700
diff changeset
   676
    a unicode string.
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   677
    """
4373
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   678
    needs_js = ('jquery.ui.js', )
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   679
    needs_css = ('jquery.ui.css',)
8471
05992aa3fc0d [form widgets] fix JQueryDatePicker and JQueryTimePicker so they consider widget custom attributes. Closes #2423720
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8193
diff changeset
   680
    default_size = 10
4373
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   681
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   682
    def __init__(self, datestr=None, **kwargs):
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   683
        super(JQueryDatePicker, self).__init__(**kwargs)
8471
05992aa3fc0d [form widgets] fix JQueryDatePicker and JQueryTimePicker so they consider widget custom attributes. Closes #2423720
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8193
diff changeset
   684
        self.value = datestr
4373
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   685
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   686
    def _render(self, form, field, renderer):
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   687
        req = form._cw
6737
de49060d4be3 add localization files for jquery datepicker
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 6682
diff changeset
   688
        if req.lang != 'en':
de49060d4be3 add localization files for jquery datepicker
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 6682
diff changeset
   689
            req.add_js('jquery.ui.datepicker-%s.js' % req.lang)
4373
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   690
        domid = field.dom_id(form, self.suffix)
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   691
        # XXX find a way to understand every format
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   692
        fmt = req.property_value('ui.date-format')
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   693
        fmt = fmt.replace('%Y', 'yy').replace('%m', 'mm').replace('%d', 'dd')
9247
9785c54e707e [date picker] revert #ec65ca70aac9 which breaks the date picker (closes #3182844)
David Douard <david.douard@logilab.fr>
parents: 9223
diff changeset
   694
        req.add_onload(u'cw.jqNode("%s").datepicker('
4373
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   695
                       '{buttonImage: "%s", dateFormat: "%s", firstDay: 1,'
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   696
                       ' showOn: "button", buttonImageOnly: true})' % (
5467
57372dbfd114 [https] fix resource urls in https version of a site: should use the https version as well to avoid warnings from the nrowser
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5453
diff changeset
   697
                           domid, req.uiprops['CALENDAR_ICON'], fmt))
9223
233e770293a9 [date picker widgets] properly distinguish DOM id and input name. Closes #3096575
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9222
diff changeset
   698
        return self._render_input(form, field)
8471
05992aa3fc0d [form widgets] fix JQueryDatePicker and JQueryTimePicker so they consider widget custom attributes. Closes #2423720
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8193
diff changeset
   699
9223
233e770293a9 [date picker widgets] properly distinguish DOM id and input name. Closes #3096575
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9222
diff changeset
   700
    def _render_input(self, form, field):
8471
05992aa3fc0d [form widgets] fix JQueryDatePicker and JQueryTimePicker so they consider widget custom attributes. Closes #2423720
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8193
diff changeset
   701
        if self.value is None:
4373
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   702
            value = self.values(form, field)[0]
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   703
        else:
8471
05992aa3fc0d [form widgets] fix JQueryDatePicker and JQueryTimePicker so they consider widget custom attributes. Closes #2423720
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8193
diff changeset
   704
            value = self.value
05992aa3fc0d [form widgets] fix JQueryDatePicker and JQueryTimePicker so they consider widget custom attributes. Closes #2423720
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8193
diff changeset
   705
        attrs = self.attributes(form, field)
05992aa3fc0d [form widgets] fix JQueryDatePicker and JQueryTimePicker so they consider widget custom attributes. Closes #2423720
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8193
diff changeset
   706
        attrs.setdefault('size', unicode(self.default_size))
9223
233e770293a9 [date picker widgets] properly distinguish DOM id and input name. Closes #3096575
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9222
diff changeset
   707
        return tags.input(name=field.input_name(form, self.suffix),
233e770293a9 [date picker widgets] properly distinguish DOM id and input name. Closes #3096575
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9222
diff changeset
   708
                          value=value, type='text', **attrs)
4373
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   709
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   710
8471
05992aa3fc0d [form widgets] fix JQueryDatePicker and JQueryTimePicker so they consider widget custom attributes. Closes #2423720
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8193
diff changeset
   711
class JQueryTimePicker(JQueryDatePicker):
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   712
    """Use jquery.timePicker to define a time picker. Will return the time as an
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   713
    unicode string.
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   714
    """
4373
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   715
    needs_js = ('jquery.timePicker.js',)
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   716
    needs_css = ('jquery.timepicker.css',)
8471
05992aa3fc0d [form widgets] fix JQueryDatePicker and JQueryTimePicker so they consider widget custom attributes. Closes #2423720
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8193
diff changeset
   717
    default_size = 5
4373
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   718
4846
a2fb82770fa6 [widget] allow to specify hour/minute separator on the JQueryTimePicker (vgodard patch)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4660
diff changeset
   719
    def __init__(self, timestr=None, timesteps=30, separator=u':', **kwargs):
8471
05992aa3fc0d [form widgets] fix JQueryDatePicker and JQueryTimePicker so they consider widget custom attributes. Closes #2423720
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8193
diff changeset
   720
        super(JQueryTimePicker, self).__init__(timestr, **kwargs)
4373
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   721
        self.timesteps = timesteps
4846
a2fb82770fa6 [widget] allow to specify hour/minute separator on the JQueryTimePicker (vgodard patch)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4660
diff changeset
   722
        self.separator = separator
4373
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   723
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   724
    def _render(self, form, field, renderer):
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   725
        domid = field.dom_id(form, self.suffix)
9247
9785c54e707e [date picker] revert #ec65ca70aac9 which breaks the date picker (closes #3182844)
David Douard <david.douard@logilab.fr>
parents: 9223
diff changeset
   726
        form._cw.add_onload(u'cw.jqNode("%s").timePicker({step: %s, separator: "%s"})' % (
8471
05992aa3fc0d [form widgets] fix JQueryDatePicker and JQueryTimePicker so they consider widget custom attributes. Closes #2423720
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8193
diff changeset
   727
                domid, self.timesteps, self.separator))
9223
233e770293a9 [date picker widgets] properly distinguish DOM id and input name. Closes #3096575
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9222
diff changeset
   728
        return self._render_input(form, field)
4373
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   729
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   730
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   731
class JQueryDateTimePicker(FieldWidget):
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   732
    """Compound widget using :class:`JQueryDatePicker` and
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   733
    :class:`JQueryTimePicker` widgets to define a date and time picker. Will
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   734
    return the date and time as python datetime instance.
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   735
    """
4373
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   736
    def __init__(self, initialtime=None, timesteps=15, **kwargs):
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   737
        super(JQueryDateTimePicker, self).__init__(**kwargs)
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   738
        self.initialtime = initialtime
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   739
        self.timesteps = timesteps
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   740
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   741
    def _render(self, form, field, renderer):
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   742
        """render the widget for the given `field` of `form`.
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   743
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   744
        Generate one <input> tag for each field's value
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   745
        """
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   746
        req = form._cw
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   747
        dateqname = field.input_name(form, 'date')
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   748
        timeqname = field.input_name(form, 'time')
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   749
        if dateqname in form.form_previous_values:
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   750
            datestr = form.form_previous_values[dateqname]
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   751
            timestr = form.form_previous_values[timeqname]
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   752
        else:
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   753
            datestr = timestr = u''
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   754
            if field.name in req.form:
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   755
                value = req.parse_datetime(req.form[field.name])
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   756
            else:
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   757
                value = self.typed_value(form, field)
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   758
            if value:
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   759
                datestr = req.format_date(value)
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   760
                timestr = req.format_time(value)
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   761
            elif self.initialtime:
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   762
                timestr = req.format_time(self.initialtime)
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   763
        datepicker = JQueryDatePicker(datestr=datestr, suffix='date')
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   764
        timepicker = JQueryTimePicker(timestr=timestr, timesteps=self.timesteps,
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   765
                                      suffix='time')
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   766
        return u'<div id="%s">%s%s</div>' % (field.dom_id(form),
5383
fbe7416104c6 [widgets] fix super calls, bug introduced in 5367:4176a50c81c9
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5377
diff changeset
   767
                                            datepicker.render(form, field, renderer),
fbe7416104c6 [widgets] fix super calls, bug introduced in 5367:4176a50c81c9
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5377
diff changeset
   768
                                            timepicker.render(form, field, renderer))
4373
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   769
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   770
    def process_field_data(self, form, field):
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   771
        req = form._cw
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   772
        datestr = req.form.get(field.input_name(form, 'date')).strip() or None
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   773
        timestr = req.form.get(field.input_name(form, 'time')).strip() or None
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   774
        if datestr is None:
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   775
            return None
6260
e06750b556ad raise ProcessFormError when a problem occurs during date / time parsing
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5909
diff changeset
   776
        try:
e06750b556ad raise ProcessFormError when a problem occurs during date / time parsing
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5909
diff changeset
   777
            date = todatetime(req.parse_datetime(datestr, 'Date'))
8695
358d8bed9626 [toward-py3k] rewrite to "except AnException as exc:" (part of #2711624)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8471
diff changeset
   778
        except ValueError as exc:
6260
e06750b556ad raise ProcessFormError when a problem occurs during date / time parsing
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5909
diff changeset
   779
            raise ProcessFormError(unicode(exc))
4373
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   780
        if timestr is None:
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   781
            return date
6260
e06750b556ad raise ProcessFormError when a problem occurs during date / time parsing
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5909
diff changeset
   782
        try:
e06750b556ad raise ProcessFormError when a problem occurs during date / time parsing
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5909
diff changeset
   783
            time = req.parse_datetime(timestr, 'Time')
8695
358d8bed9626 [toward-py3k] rewrite to "except AnException as exc:" (part of #2711624)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8471
diff changeset
   784
        except ValueError as exc:
6260
e06750b556ad raise ProcessFormError when a problem occurs during date / time parsing
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5909
diff changeset
   785
            raise ProcessFormError(unicode(exc))
4373
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   786
        return date.replace(hour=time.hour, minute=time.minute, second=time.second)
972143183ea3 new jquery based widgets for Time/Date/DateTime, backported from crm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4372
diff changeset
   787
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   788
1330
92343a468e2a add some documentation, backport *CompletionWidget
sylvain.thenault@logilab.fr
parents: 1329
diff changeset
   789
# ajax widgets ################################################################
92343a468e2a add some documentation, backport *CompletionWidget
sylvain.thenault@logilab.fr
parents: 1329
diff changeset
   790
1337
828bbf500bcc backport AddComboBoxWidget, ajax widgets refactoring
sylvain.thenault@logilab.fr
parents: 1336
diff changeset
   791
def init_ajax_attributes(attrs, wdgtype, loadtype=u'auto'):
828bbf500bcc backport AddComboBoxWidget, ajax widgets refactoring
sylvain.thenault@logilab.fr
parents: 1336
diff changeset
   792
    try:
4597
e872097f2287 use class, not klass, in widget.attrs
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4593
diff changeset
   793
        attrs['class'] += u' widget'
1337
828bbf500bcc backport AddComboBoxWidget, ajax widgets refactoring
sylvain.thenault@logilab.fr
parents: 1336
diff changeset
   794
    except KeyError:
4597
e872097f2287 use class, not klass, in widget.attrs
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4593
diff changeset
   795
        attrs['class'] = u'widget'
1344
930020cb134b shouldn't use unicode keys in attrs
sylvain.thenault@logilab.fr
parents: 1337
diff changeset
   796
    attrs.setdefault('cubicweb:wdgtype', wdgtype)
930020cb134b shouldn't use unicode keys in attrs
sylvain.thenault@logilab.fr
parents: 1337
diff changeset
   797
    attrs.setdefault('cubicweb:loadtype', loadtype)
1337
828bbf500bcc backport AddComboBoxWidget, ajax widgets refactoring
sylvain.thenault@logilab.fr
parents: 1336
diff changeset
   798
828bbf500bcc backport AddComboBoxWidget, ajax widgets refactoring
sylvain.thenault@logilab.fr
parents: 1336
diff changeset
   799
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   800
class AjaxWidget(FieldWidget):
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   801
    """Simple <div> based ajax widget, requiring a `wdgtype` argument telling
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   802
    which javascript widget should be used.
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   803
    """
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   804
    def __init__(self, wdgtype, inputid=None, **kwargs):
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   805
        super(AjaxWidget, self).__init__(**kwargs)
1337
828bbf500bcc backport AddComboBoxWidget, ajax widgets refactoring
sylvain.thenault@logilab.fr
parents: 1336
diff changeset
   806
        init_ajax_attributes(self.attrs, wdgtype)
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   807
        if inputid is not None:
1344
930020cb134b shouldn't use unicode keys in attrs
sylvain.thenault@logilab.fr
parents: 1337
diff changeset
   808
            self.attrs['cubicweb:inputid'] = inputid
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1425
diff changeset
   809
4372
0c44af150a49 introduce a default render implementation on the base widget, which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4371
diff changeset
   810
    def _render(self, form, field, renderer):
4163
b2747ed057e6 substitute _render_attrs by values_and_attributes method, keeping bw compat
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   811
        attrs = self.values_and_attributes(form, field)[-1]
1081
f2a85f52b9e5 move fields and widgets to their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   812
        return tags.div(**attrs)
1304
8975c8e520a9 refactor button handling
sylvain.thenault@logilab.fr
parents: 1295
diff changeset
   813
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1425
diff changeset
   814
1330
92343a468e2a add some documentation, backport *CompletionWidget
sylvain.thenault@logilab.fr
parents: 1329
diff changeset
   815
class AutoCompletionWidget(TextInput):
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   816
    """<input type='text'> based ajax widget, taking a `autocomplete_initfunc`
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   817
    argument which should specify the name of a method of the json
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   818
    controller. This method is expected to return allowed values for the input,
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   819
    that the widget will use to propose matching values as you type.
1330
92343a468e2a add some documentation, backport *CompletionWidget
sylvain.thenault@logilab.fr
parents: 1329
diff changeset
   820
    """
6448
8590d82e9b1b [javascript] update to jQuery 1.4.2 and jQuery-ui 1.8.5
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6260
diff changeset
   821
    needs_js = ('cubicweb.widgets.js', 'jquery.ui.js')
8590d82e9b1b [javascript] update to jQuery 1.4.2 and jQuery-ui 1.8.5
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6260
diff changeset
   822
    needs_css = ('jquery.ui.css',)
6449
613d83588998 [formwidgets] rewrite autocomplete cw widgets to get rid of div-style declaration API
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6448
diff changeset
   823
    default_settings = {}
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1425
diff changeset
   824
1966
87ce7d336393 stop using autocomplete_initfuncs dict on entity classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1934
diff changeset
   825
    def __init__(self, *args, **kwargs):
6449
613d83588998 [formwidgets] rewrite autocomplete cw widgets to get rid of div-style declaration API
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6448
diff changeset
   826
        self.autocomplete_settings = kwargs.pop('autocomplete_settings',
613d83588998 [formwidgets] rewrite autocomplete cw widgets to get rid of div-style declaration API
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6448
diff changeset
   827
                                                self.default_settings)
7990
a673d1d9a738 [diet] drop pre 3.6 API compatibility (but attempt to keep data cmopatibility). Closes #2017916
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   828
        self.autocomplete_initfunc = kwargs.pop('autocomplete_initfunc')
1966
87ce7d336393 stop using autocomplete_initfuncs dict on entity classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1934
diff changeset
   829
        super(AutoCompletionWidget, self).__init__(*args, **kwargs)
87ce7d336393 stop using autocomplete_initfuncs dict on entity classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1934
diff changeset
   830
5367
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5111
diff changeset
   831
    def values(self, form, field):
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5111
diff changeset
   832
        values = super(AutoCompletionWidget, self).values(form, field)
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5111
diff changeset
   833
        if not values:
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5111
diff changeset
   834
            values = ('',)
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5111
diff changeset
   835
        return values
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5111
diff changeset
   836
6449
613d83588998 [formwidgets] rewrite autocomplete cw widgets to get rid of div-style declaration API
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6448
diff changeset
   837
    def _render(self, form, field, renderer):
613d83588998 [formwidgets] rewrite autocomplete cw widgets to get rid of div-style declaration API
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6448
diff changeset
   838
        entity = form.edited_entity
613d83588998 [formwidgets] rewrite autocomplete cw widgets to get rid of div-style declaration API
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6448
diff changeset
   839
        domid = field.dom_id(form).replace(':', r'\\:')
613d83588998 [formwidgets] rewrite autocomplete cw widgets to get rid of div-style declaration API
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6448
diff changeset
   840
        if callable(self.autocomplete_initfunc):
613d83588998 [formwidgets] rewrite autocomplete cw widgets to get rid of div-style declaration API
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6448
diff changeset
   841
            data = self.autocomplete_initfunc(form, field)
613d83588998 [formwidgets] rewrite autocomplete cw widgets to get rid of div-style declaration API
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6448
diff changeset
   842
        else:
613d83588998 [formwidgets] rewrite autocomplete cw widgets to get rid of div-style declaration API
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6448
diff changeset
   843
            data = xml_escape(self._get_url(entity, field))
613d83588998 [formwidgets] rewrite autocomplete cw widgets to get rid of div-style declaration API
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6448
diff changeset
   844
        form._cw.add_onload(u'$("#%s").cwautocomplete(%s, %s);'
613d83588998 [formwidgets] rewrite autocomplete cw widgets to get rid of div-style declaration API
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6448
diff changeset
   845
                            % (domid, json_dumps(data),
613d83588998 [formwidgets] rewrite autocomplete cw widgets to get rid of div-style declaration API
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6448
diff changeset
   846
                               json_dumps(self.autocomplete_settings)))
613d83588998 [formwidgets] rewrite autocomplete cw widgets to get rid of div-style declaration API
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6448
diff changeset
   847
        return super(AutoCompletionWidget, self)._render(form, field, renderer)
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1425
diff changeset
   848
1875
7bcb02377516 no rschema attribute on widgets
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1874
diff changeset
   849
    def _get_url(self, entity, field):
7990
a673d1d9a738 [diet] drop pre 3.6 API compatibility (but attempt to keep data cmopatibility). Closes #2017916
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   850
        fname = self.autocomplete_initfunc
8728
75be9de9d68e [web] Use the new '/ajax' URL path to access the AjaxController (closes #2758254)
Rémi Cardona <remi.cardona@logilab.fr>
parents: 8471
diff changeset
   851
        return entity._cw.build_url('ajax', fname=fname, mode='remote',
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3388
diff changeset
   852
                                    pageid=entity._cw.pageid)
1330
92343a468e2a add some documentation, backport *CompletionWidget
sylvain.thenault@logilab.fr
parents: 1329
diff changeset
   853
92343a468e2a add some documentation, backport *CompletionWidget
sylvain.thenault@logilab.fr
parents: 1329
diff changeset
   854
6449
613d83588998 [formwidgets] rewrite autocomplete cw widgets to get rid of div-style declaration API
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6448
diff changeset
   855
1330
92343a468e2a add some documentation, backport *CompletionWidget
sylvain.thenault@logilab.fr
parents: 1329
diff changeset
   856
class StaticFileAutoCompletionWidget(AutoCompletionWidget):
92343a468e2a add some documentation, backport *CompletionWidget
sylvain.thenault@logilab.fr
parents: 1329
diff changeset
   857
    """XXX describe me"""
92343a468e2a add some documentation, backport *CompletionWidget
sylvain.thenault@logilab.fr
parents: 1329
diff changeset
   858
    wdgtype = 'StaticFileSuggestField'
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1425
diff changeset
   859
1875
7bcb02377516 no rschema attribute on widgets
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1874
diff changeset
   860
    def _get_url(self, entity, field):
7990
a673d1d9a738 [diet] drop pre 3.6 API compatibility (but attempt to keep data cmopatibility). Closes #2017916
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   861
        return entity._cw.data_url(self.autocomplete_initfunc)
1330
92343a468e2a add some documentation, backport *CompletionWidget
sylvain.thenault@logilab.fr
parents: 1329
diff changeset
   862
92343a468e2a add some documentation, backport *CompletionWidget
sylvain.thenault@logilab.fr
parents: 1329
diff changeset
   863
92343a468e2a add some documentation, backport *CompletionWidget
sylvain.thenault@logilab.fr
parents: 1329
diff changeset
   864
class RestrictedAutoCompletionWidget(AutoCompletionWidget):
92343a468e2a add some documentation, backport *CompletionWidget
sylvain.thenault@logilab.fr
parents: 1329
diff changeset
   865
    """XXX describe me"""
6449
613d83588998 [formwidgets] rewrite autocomplete cw widgets to get rid of div-style declaration API
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6448
diff changeset
   866
    default_settings = {'mustMatch': True}
1330
92343a468e2a add some documentation, backport *CompletionWidget
sylvain.thenault@logilab.fr
parents: 1329
diff changeset
   867
92343a468e2a add some documentation, backport *CompletionWidget
sylvain.thenault@logilab.fr
parents: 1329
diff changeset
   868
4901
19ecbbc4f633 LazySuggestField : remote version of RestrictedSuggestField
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4858
diff changeset
   869
class LazyRestrictedAutoCompletionWidget(RestrictedAutoCompletionWidget):
19ecbbc4f633 LazySuggestField : remote version of RestrictedSuggestField
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4858
diff changeset
   870
    """remote autocomplete """
19ecbbc4f633 LazySuggestField : remote version of RestrictedSuggestField
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4858
diff changeset
   871
19ecbbc4f633 LazySuggestField : remote version of RestrictedSuggestField
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4858
diff changeset
   872
    def values_and_attributes(self, form, field):
19ecbbc4f633 LazySuggestField : remote version of RestrictedSuggestField
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4858
diff changeset
   873
        """override values_and_attributes to handle initial displayed values"""
19ecbbc4f633 LazySuggestField : remote version of RestrictedSuggestField
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4858
diff changeset
   874
        values, attrs = super(LazyRestrictedAutoCompletionWidget, self).values_and_attributes(form, field)
19ecbbc4f633 LazySuggestField : remote version of RestrictedSuggestField
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4858
diff changeset
   875
        assert len(values) == 1, "multiple selection is not supported yet by LazyWidget"
19ecbbc4f633 LazySuggestField : remote version of RestrictedSuggestField
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4858
diff changeset
   876
        if not values[0]:
19ecbbc4f633 LazySuggestField : remote version of RestrictedSuggestField
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4858
diff changeset
   877
            values = form.cw_extra_kwargs.get(field.name,'')
19ecbbc4f633 LazySuggestField : remote version of RestrictedSuggestField
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4858
diff changeset
   878
            if not isinstance(values, (tuple, list)):
19ecbbc4f633 LazySuggestField : remote version of RestrictedSuggestField
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4858
diff changeset
   879
                values = (values,)
19ecbbc4f633 LazySuggestField : remote version of RestrictedSuggestField
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4858
diff changeset
   880
        try:
19ecbbc4f633 LazySuggestField : remote version of RestrictedSuggestField
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4858
diff changeset
   881
            values = list(values)
19ecbbc4f633 LazySuggestField : remote version of RestrictedSuggestField
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4858
diff changeset
   882
            values[0] = int(values[0])
19ecbbc4f633 LazySuggestField : remote version of RestrictedSuggestField
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4858
diff changeset
   883
            attrs['cubicweb:initialvalue'] = values[0]
19ecbbc4f633 LazySuggestField : remote version of RestrictedSuggestField
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4858
diff changeset
   884
            values = (self.display_value_for(form, values[0]),)
19ecbbc4f633 LazySuggestField : remote version of RestrictedSuggestField
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4858
diff changeset
   885
        except (TypeError, ValueError):
19ecbbc4f633 LazySuggestField : remote version of RestrictedSuggestField
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4858
diff changeset
   886
            pass
19ecbbc4f633 LazySuggestField : remote version of RestrictedSuggestField
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4858
diff changeset
   887
        return values, attrs
19ecbbc4f633 LazySuggestField : remote version of RestrictedSuggestField
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4858
diff changeset
   888
19ecbbc4f633 LazySuggestField : remote version of RestrictedSuggestField
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4858
diff changeset
   889
    def display_value_for(self, form, value):
5367
4176a50c81c9 [form] small api cleanup and refactoring before documenting the form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5111
diff changeset
   890
        entity = form._cw.entity_from_eid(value)
4901
19ecbbc4f633 LazySuggestField : remote version of RestrictedSuggestField
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4858
diff changeset
   891
        return entity.view('combobox')
19ecbbc4f633 LazySuggestField : remote version of RestrictedSuggestField
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4858
diff changeset
   892
19ecbbc4f633 LazySuggestField : remote version of RestrictedSuggestField
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4858
diff changeset
   893
4304
0b53e850cdb5 refactor field's value retreiving from the widget (eg 'display value' concept):
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   894
# more widgets #################################################################
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1425
diff changeset
   895
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   896
class IntervalWidget(FieldWidget):
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   897
    """Custom widget to display an interval composed by 2 fields. This widget is
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   898
    expected to be used with a :class:`CompoundField` containing the two actual
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   899
    fields.
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   900
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   901
    Exemple usage::
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   902
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   903
      class MyForm(FieldsForm):
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   904
         price = CompoundField(fields=(IntField(name='minprice'),
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   905
                                       IntField(name='maxprice')),
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   906
                               label=_('price'),
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   907
                               widget=IntervalWidget())
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   908
    """
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   909
    def _render(self, form, field, renderer):
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   910
        actual_fields = field.fields
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   911
        assert len(actual_fields) == 2
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   912
        return u'<div>%s %s %s %s</div>' % (
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   913
            form._cw._('from_interval_start'),
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   914
            actual_fields[0].render(form, renderer),
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   915
            form._cw._('to_interval_end'),
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   916
            actual_fields[1].render(form, renderer),
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   917
            )
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   918
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   919
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   920
class HorizontalLayoutWidget(FieldWidget):
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   921
    """Custom widget to display a set of fields grouped together horizontally in
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   922
    a form. See `IntervalWidget` for example usage.
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   923
    """
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   924
    def _render(self, form, field, renderer):
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   925
        if self.attrs.get('display_label', True):
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   926
            subst = self.attrs.get('label_input_substitution', '%(label)s %(input)s')
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   927
            fields = [subst % {'label': renderer.render_label(form, f),
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   928
                              'input': f.render(form, renderer)}
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   929
                      for f in field.subfields(form)]
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   930
        else:
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   931
            fields = [f.render(form, renderer) for f in field.subfields(form)]
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   932
        return u'<div>%s</div>' % ' '.join(fields)
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   933
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   934
4375
6d34e3cf60a3 cleanup base class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4373
diff changeset
   935
class EditableURLWidget(FieldWidget):
9700
da7d341cca76 an URL -> a URL
Rémi Cardona <remi.cardona@logilab.fr>
parents: 9377
diff changeset
   936
    """Custom widget to edit separatly a URL path / query string (used by
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   937
    default for the `path` attribute of `Bookmark` entities).
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   938
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5367
diff changeset
   939
    It deals with url quoting nicely so that the user edit the unquoted value.
4305
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   940
    """
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   941
4372
0c44af150a49 introduce a default render implementation on the base widget, which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4371
diff changeset
   942
    def _render(self, form, field, renderer):
0c44af150a49 introduce a default render implementation on the base widget, which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4371
diff changeset
   943
        assert self.suffix is None, 'not supported'
4305
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   944
        req = form._cw
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   945
        pathqname = field.input_name(form, 'path')
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   946
        fqsqname = field.input_name(form, 'fqs') # formatted query string
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   947
        if pathqname in form.form_previous_values:
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   948
            path = form.form_previous_values[pathqname]
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   949
            fqs = form.form_previous_values[fqsqname]
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   950
        else:
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   951
            if field.name in req.form:
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   952
                value = req.form[field.name]
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   953
            else:
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   954
                value = self.typed_value(form, field)
4550
d74098d1b69f fix bug when value is None
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4508
diff changeset
   955
            if value:
d74098d1b69f fix bug when value is None
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4508
diff changeset
   956
                try:
d74098d1b69f fix bug when value is None
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4508
diff changeset
   957
                    path, qs = value.split('?', 1)
d74098d1b69f fix bug when value is None
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4508
diff changeset
   958
                except ValueError:
d74098d1b69f fix bug when value is None
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4508
diff changeset
   959
                    path = value
d74098d1b69f fix bug when value is None
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4508
diff changeset
   960
                    qs = ''
d74098d1b69f fix bug when value is None
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4508
diff changeset
   961
            else:
d74098d1b69f fix bug when value is None
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4508
diff changeset
   962
                path = qs = ''
4305
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   963
            fqs = u'\n'.join(u'%s=%s' % (k, v) for k, v in req.url_parse_qsl(qs))
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   964
        attrs = dict(self.attrs)
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   965
        if self.setdomid:
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   966
            attrs['id'] = field.dom_id(form)
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   967
        if self.settabindex and not 'tabindex' in attrs:
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   968
            attrs['tabindex'] = req.next_tabindex()
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   969
        # ensure something is rendered
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   970
        inputs = [u'<table><tr><th>',
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   971
                  req._('i18n_bookmark_url_path'),
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   972
                  u'</th><td>',
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   973
                  tags.input(name=pathqname, type='string', value=path, **attrs),
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   974
                  u'</td></tr><tr><th>',
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   975
                  req._('i18n_bookmark_url_fqs'),
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   976
                  u'</th><td>']
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   977
        if self.setdomid:
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   978
            attrs['id'] = field.dom_id(form, 'fqs')
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   979
        if self.settabindex:
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   980
            attrs['tabindex'] = req.next_tabindex()
5111
9f3ea34f98d1 [widget] more wide textarea on bookmark edition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4975
diff changeset
   981
        attrs.setdefault('cols', 60)
4305
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   982
        attrs.setdefault('onkeyup', 'autogrow(this)')
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   983
        inputs += [tags.textarea(fqs, name=fqsqname, **attrs),
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   984
                   u'</td></tr></table>']
4376
839b28a3652e surrounding div necessary for proper error localization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4375
diff changeset
   985
        # surrounding div necessary for proper error localization
4508
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4481
diff changeset
   986
        return u'<div id="%s">%s</div>' % (
4376
839b28a3652e surrounding div necessary for proper error localization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4375
diff changeset
   987
            field.dom_id(form), u'\n'.join(inputs))
4305
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   988
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   989
    def process_field_data(self, form, field):
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   990
        req = form._cw
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   991
        values = {}
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   992
        path = req.form.get(field.input_name(form, 'path'))
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   993
        if isinstance(path, basestring):
6682
bdf9424b499c test and fix #1232202: [bookmarks] broken link for startupviews
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6449
diff changeset
   994
            path = path.strip()
bdf9424b499c test and fix #1232202: [bookmarks] broken link for startupviews
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6449
diff changeset
   995
        if path is None:
bdf9424b499c test and fix #1232202: [bookmarks] broken link for startupviews
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6449
diff changeset
   996
            path = u''
4305
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   997
        fqs = req.form.get(field.input_name(form, 'fqs'))
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   998
        if isinstance(fqs, basestring):
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
   999
            fqs = fqs.strip() or None
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
  1000
            if fqs:
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
  1001
                for i, line in enumerate(fqs.split('\n')):
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
  1002
                    line = line.strip()
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
  1003
                    if line:
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
  1004
                        try:
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
  1005
                            key, val = line.split('=', 1)
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
  1006
                        except ValueError:
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
  1007
                            raise ProcessFormError(req._("wrong query parameter line %s") % (i+1))
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
  1008
                        # value will be url quoted by build_url_params
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
  1009
                        values.setdefault(key.encode(req.encoding), []).append(val)
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
  1010
        if not values:
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
  1011
            return path
3d731478d9a8 new field's responsibility POC: EditableURLWidget allow to edit Bookmark.path in two separated fields, displaying unquoted values which are requoted on form post processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4304
diff changeset
  1012
        return u'%s?%s' % (path, req.build_url_params(**values))
5384
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1013
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1014
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1015
# form controls ######################################################################
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1016
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1017
class Button(Input):
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1018
    """Simple <input type='button'>, base class for global form buttons.
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1019
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1020
    Note that `label` is a msgid which will be translated at form generation
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1021
    time, you should not give an already translated string.
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1022
    """
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1023
    type = 'button'
9134
a5f53b023132 [css, html] add a css_class attribute on Button, allowing to change easily default CSS class for buttons
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 8936
diff changeset
  1024
    css_class = 'validateButton'
a5f53b023132 [css, html] add a css_class attribute on Button, allowing to change easily default CSS class for buttons
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 8936
diff changeset
  1025
5384
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1026
    def __init__(self, label=stdmsgs.BUTTON_OK, attrs=None,
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1027
                 setdomid=None, settabindex=None,
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1028
                 name='', value='', onclick=None, cwaction=None):
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1029
        super(Button, self).__init__(attrs, setdomid, settabindex)
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1030
        if isinstance(label, tuple):
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1031
            self.label = label[0]
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1032
            self.icon = label[1]
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1033
        else:
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1034
            self.label = label
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1035
            self.icon = None
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1036
        self.name = name
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1037
        self.value = ''
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1038
        self.onclick = onclick
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1039
        self.cwaction = cwaction
9134
a5f53b023132 [css, html] add a css_class attribute on Button, allowing to change easily default CSS class for buttons
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 8936
diff changeset
  1040
        self.attrs.setdefault('class', self.css_class)
5384
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1041
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1042
    def render(self, form, field=None, renderer=None):
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1043
        label = form._cw._(self.label)
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1044
        attrs = self.attrs.copy()
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1045
        if self.cwaction:
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1046
            assert self.onclick is None
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1047
            attrs['onclick'] = "postForm('__action_%s', \'%s\', \'%s\')" % (
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1048
                self.cwaction, self.label, form.domid)
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1049
        elif self.onclick:
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1050
            attrs['onclick'] = self.onclick
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1051
        if self.name:
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1052
            attrs['name'] = self.name
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1053
            if self.setdomid:
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1054
                attrs['id'] = self.name
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1055
        if self.settabindex and not 'tabindex' in attrs:
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1056
            attrs['tabindex'] = form._cw.next_tabindex()
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1057
        if self.icon:
5467
57372dbfd114 [https] fix resource urls in https version of a site: should use the https version as well to avoid warnings from the nrowser
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5453
diff changeset
  1058
            img = tags.img(src=form._cw.uiprops[self.icon], alt=self.icon)
5384
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1059
        else:
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1060
            img = u''
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1061
        return tags.button(img + xml_escape(label), escapecontent=False,
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1062
                           value=label, type=self.type, **attrs)
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1063
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1064
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1065
class SubmitButton(Button):
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1066
    """Simple <input type='submit'>, main button to submit a form"""
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1067
    type = 'submit'
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1068
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1069
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1070
class ResetButton(Button):
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1071
    """Simple <input type='reset'>, main button to reset a form. You usually
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1072
    don't want to use this.
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1073
    """
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1074
    type = 'reset'
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1075
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1076
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1077
class ImgButton(object):
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1078
    """Simple <img> wrapped into a <a> tag with href triggering something (usually a
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1079
    javascript call).
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1080
    """
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1081
    def __init__(self, domid, href, label, imgressource):
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1082
        self.domid = domid
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1083
        self.href = href
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1084
        self.imgressource = imgressource
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1085
        self.label = label
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1086
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1087
    def render(self, form, field=None, renderer=None):
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1088
        label = form._cw._(self.label)
5467
57372dbfd114 [https] fix resource urls in https version of a site: should use the https version as well to avoid warnings from the nrowser
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5453
diff changeset
  1089
        imgsrc = form._cw.uiprops[self.imgressource]
5384
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1090
        return '<a id="%(domid)s" href="%(href)s">'\
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1091
               '<img src="%(imgsrc)s" alt="%(label)s"/>%(label)s</a>' % {
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1092
            'label': label, 'imgsrc': imgsrc,
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1093
            'domid': self.domid, 'href': self.href}
b619531ddbd2 [widgets] move form controls at the end of the file
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5383
diff changeset
  1094