Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
cubicweb
cubicweb
Commits
92343a468e2a
Commit
af06cf2d
authored
Apr 09, 2009
by
sylvain.thenault@logilab.fr
Browse files
add some documentation, backport *CompletionWidget
--HG-- branch : tls-sprint
parent
9c7cc717bb17
Changes
1
Hide whitespace changes
Inline
Side-by-side
web/formwidgets.py
View file @
92343a46
...
...
@@ -11,14 +11,20 @@ from datetime import date
from
cubicweb.common
import
tags
from
cubicweb.web
import
stdmsgs
class
FieldWidget
(
object
):
"""abstract widget class"""
# javascript / css files required by the widget
needs_js
=
()
needs_css
=
()
# automatically set id and tabindex attributes ?
setdomid
=
True
settabindex
=
True
def
__init__
(
self
,
attrs
=
None
,
setdomid
=
None
,
settabindex
=
None
):
self
.
attrs
=
attrs
or
{}
if
attrs
is
None
:
attrs
=
{}
self
.
attrs
=
attrs
if
setdomid
is
not
None
:
# override class's default value
self
.
setdomid
=
setdomid
...
...
@@ -34,9 +40,14 @@ class FieldWidget(object):
form
.
req
.
add_css
(
self
.
needs_css
)
def
render
(
self
,
form
,
field
):
"""render the widget for the given `field` of `form`.
To override in concrete class
"""
raise
NotImplementedError
def
_render_attrs
(
self
,
form
,
field
):
"""return html tag name, attributes and a list of values for the field
"""
name
=
form
.
context
[
field
][
'name'
]
values
=
form
.
context
[
field
][
'value'
]
if
not
isinstance
(
values
,
(
tuple
,
list
)):
...
...
@@ -50,9 +61,14 @@ class FieldWidget(object):
class
Input
(
FieldWidget
):
"""abstract widget class for <input> tag based widgets"""
type
=
None
def
render
(
self
,
form
,
field
):
"""render the widget for the given `field` of `form`.
Generate one <input> tag for each field's value
"""
self
.
add_media
(
form
)
name
,
values
,
attrs
=
self
.
_render_attrs
(
form
,
field
)
inputs
=
[
tags
.
input
(
name
=
name
,
value
=
value
,
type
=
self
.
type
,
**
attrs
)
...
...
@@ -60,11 +76,17 @@ class Input(FieldWidget):
return
u
'
\n
'
.
join
(
inputs
)
# basic html widgets ###########################################################
class
TextInput
(
Input
):
"""<input type='text'>"""
type
=
'text'
class
PasswordInput
(
Input
):
"""<input type='password'> and its confirmation field (using
<field's name>-confirm as name)
"""
type
=
'password'
def
render
(
self
,
form
,
field
):
...
...
@@ -85,6 +107,7 @@ class PasswordInput(Input):
class
FileInput
(
Input
):
"""<input type='file'>"""
type
=
'file'
def
_render_attrs
(
self
,
form
,
field
):
...
...
@@ -94,16 +117,23 @@ class FileInput(Input):
class
HiddenInput
(
Input
):
"""<input type='hidden'>"""
type
=
'hidden'
setdomid
=
False
# by default, don't set id attribute on hidden input
settabindex
=
False
class
ButtonInput
(
Input
):
"""<input type='button'>
if you want a global form button, look at the Button, SubmitButton,
ResetButton and ImgButton classes below.
"""
type
=
'button'
class
TextArea
(
FieldWidget
):
"""<textarea>"""
def
render
(
self
,
form
,
field
):
name
,
values
,
attrs
=
self
.
_render_attrs
(
form
,
field
)
attrs
.
setdefault
(
'onkeypress'
,
'autogrow(this)'
)
...
...
@@ -117,6 +147,7 @@ class TextArea(FieldWidget):
class
FCKEditor
(
TextArea
):
"""FCKEditor enabled <textarea>"""
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
FCKEditor
,
self
).
__init__
(
*
args
,
**
kwargs
)
self
.
attrs
[
'cubicweb:type'
]
=
'wysiwyg'
...
...
@@ -127,6 +158,7 @@ class FCKEditor(TextArea):
class
Select
(
FieldWidget
):
"""<select>, for field having a specific vocabulary"""
def
__init__
(
self
,
attrs
=
None
,
multiple
=
False
):
super
(
Select
,
self
).
__init__
(
attrs
)
self
.
multiple
=
multiple
...
...
@@ -144,6 +176,9 @@ class Select(FieldWidget):
class
CheckBox
(
Input
):
"""<input type='checkbox'>, for field having a specific vocabulary. One
input will be generated for each possible value.
"""
type
=
'checkbox'
def
render
(
self
,
form
,
field
):
...
...
@@ -161,8 +196,11 @@ class CheckBox(Input):
class
Radio
(
Input
):
"""<input type='radio'>, for field having a specific vocabulary. One
input will be generated for each possible value.
"""
type
=
'radio'
setdomid
=
False
setdomid
=
False
# by default, don't set id attribute on radio input
def
render
(
self
,
form
,
field
):
name
,
curvalues
,
attrs
=
self
.
_render_attrs
(
form
,
field
)
...
...
@@ -178,7 +216,12 @@ class Radio(Input):
return
'
\n
'
.
join
(
options
)
# javascript widgets ###########################################################
class
DateTimePicker
(
TextInput
):
"""<input type='text' + javascript date/time picker for date or datetime
fields
"""
monthnames
=
(
'january'
,
'february'
,
'march'
,
'april'
,
'may'
,
'june'
,
'july'
,
'august'
,
'september'
,
'october'
,
'november'
,
'december'
)
...
...
@@ -219,7 +262,10 @@ class DateTimePicker(TextInput):
req
.
_
(
'calendar'
),
helperid
)
)
# ajax widgets ################################################################
class
AjaxWidget
(
FieldWidget
):
"""simple <div> based ajax widget"""
def
__init__
(
self
,
wdgtype
,
inputid
=
None
,
**
kwargs
):
super
(
AjaxWidget
,
self
).
__init__
(
**
kwargs
)
self
.
attrs
.
setdefault
(
'class'
,
'widget'
)
...
...
@@ -233,8 +279,52 @@ class AjaxWidget(FieldWidget):
attrs
=
self
.
_render_attrs
(
form
,
field
)[
-
1
]
return
tags
.
div
(
**
attrs
)
class
AutoCompletionWidget
(
TextInput
):
"""ajax widget for StringField, proposing matching existing values as you
type.
"""
needs_js
=
(
'cubicweb.widgets.js'
,
'jquery.autocomplete.js'
)
needs_css
=
(
'jquery.autocomplete.css'
,)
wdgtype
=
'SuggestField'
loadtype
=
'auto'
def
_render_attrs
(
self
,
form
,
field
):
name
,
values
,
attrs
=
super
(
AutoCompletionWidget
,
self
).
_render_attrs
(
form
,
field
)
if
not
values
[
0
]:
values
=
(
INTERNAL_FIELD_VALUE
,)
try
:
attrs
[
'klass'
]
+=
' widget'
except
KeyError
:
attrs
[
'klass'
]
=
'widget'
attrs
.
setdefault
(
'cubicweb:wdgtype'
,
self
.
wdgtype
)
attrs
.
setdefault
(
'cubicweb:loadtype'
,
self
.
loadtype
)
# XXX entity form specific
attrs
[
'cubicweb:dataurl'
]
=
self
.
_get_url
(
form
.
edited_entity
)
return
name
,
values
,
attrs
def
_get_url
(
self
,
entity
):
return
entity
.
req
.
build_url
(
'json'
,
fname
=
entity
.
autocomplete_initfuncs
[
self
.
rschema
],
pageid
=
entity
.
req
.
pageid
,
mode
=
'remote'
)
class
StaticFileAutoCompletionWidget
(
AutoCompletionWidget
):
"""XXX describe me"""
wdgtype
=
'StaticFileSuggestField'
def
_get_url
(
self
,
entity
):
return
entity
.
req
.
datadir_url
+
entity
.
autocomplete_initfuncs
[
self
.
rschema
]
class
RestrictedAutoCompletionWidget
(
AutoCompletionWidget
):
"""XXX describe me"""
wdgtype
=
'RestrictedSuggestField'
# buttons ######################################################################
class
Button
(
Input
):
"""<input type='button'>, base class for global form buttons"""
type
=
'button'
def
__init__
(
self
,
label
=
stdmsgs
.
BUTTON_OK
,
attrs
=
None
,
setdomid
=
None
,
settabindex
=
None
,
...
...
@@ -266,12 +356,21 @@ class Button(Input):
class
SubmitButton
(
Button
):
"""<input type='submit'>, main button to submit a form"""
type
=
'submit'
class
ResetButton
(
Button
):
"""<input type='reset'>, main button to reset a form.
You usually don't want this.
"""
type
=
'reset'
class
ImgButton
(
object
):
"""<img> wrapped into a <a> tag with href triggering something (usually a
javascript call)
"""
def
__init__
(
self
,
domid
,
href
,
label
,
imgressource
):
self
.
domid
=
domid
self
.
href
=
href
...
...
@@ -283,5 +382,4 @@ class ImgButton(object):
return
'<a id="%(domid)s" href="%(href)s"><img src="%(imgsrc)s" alt="%(label)s"/>%(label)s</a>'
%
self
.
__dict__
# XXX EntityLinkComboBoxWidget, AddComboBoxWidget, AutoCompletionWidget,
# StaticFileAutoCompletionWidget, RestrictedAutoCompletionWidget...
# XXX EntityLinkComboBoxWidget, AddComboBoxWidget, RawDynamicComboBoxWidget
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment