跳转到主要内容

额外的zope.formlib小部件

项目描述

z3c.widget更改

0.3.0 (2010-11-16)

  • 添加法语翻译。

  • 更新测试以使用 zope.formlib 4.0 和 zope.schema 3.6。

  • 使用Python的 doctest 模块而不是已弃用的 zope.testing.doctest[unit]

  • 将doctests添加到 long_description 以在PyPI上可见。

2008/01/29 0.2.1

  • 为匈牙利语和罗马尼亚语添加翻译

2007/09/21 0.2.0

  • 功能:添加了日期选择小部件。

  • 功能:添加了社会保障号小部件。

  • 功能:添加了美国电话号码小部件。

2007/09/19 0.1.7

  • 为英文添加了翻译,以便在某些浏览器中启用 i18n 功能

2007/09/19 0.1.6

  • 添加 cheesehop 分类,并在那里注册

  • 修复了拼写错误

2007/09/05 0.1.5

  • 错误修复:在打开文件对话框中点击取消后,浏览按钮现在将被启用

  • 在上传开始之前不要将进度条设置为 100%

  • 错误修复:如果没有设置限制,则不会上传文件

2007/09/05 0.1.4

  • 处理上传过程中的文件大小。如果一个或多个文件的大小超过传递的大小,则在上传工作文件完成后,每个文件都将被忽略,但将在进度条下方列出。

  • 显示最大允许的文件大小(如果包含在配置文件中)

2007/09/03 0.1.3

  • 错误修复:过多的引号。

2007/09/03 0.1.2

  • 使用传递的配置 URL 而不是硬编码的 flashuploadvars.xml

2007/08/06 0.1.1

  • flashupload:为 upload.swf 提供更好的可定制性。清理 Flash 内容的文件夹结构。

2007/06/14 0.1.0:

  • z3c.widget.image:为 es 添加了翻译

  • 更新到最新的 bootstrap.py 版本

自动完成小部件

自动完成小部件是普通选择小部件的替代品。

>>> from z3c.widget.autocomplete.widget import AutoCompleteWidget

让我们创建一个词汇表。

>>> from zope.schema.vocabulary import SimpleVocabulary
>>> from zope.publisher.browser import TestRequest
>>> from zope import schema, component, interface
>>> items = ((u'value1',1,u'Title1'),
...          (u'value2',2,u'Title2'),
...          (u'value3',3,u'Title3'))
>>> terms = map(lambda i: SimpleVocabulary.createTerm(*i),items)
>>> voc = SimpleVocabulary(terms)
>>> [term.title for term in voc]
[u'Title1', u'Title2', u'Title3']
>>> field = schema.Choice(__name__='foo',
...     missing_value=None,
...     vocabulary=voc)
>>> request = TestRequest()
 >>> widget =  AutoCompleteWidget(field, request)
>>> widget
<z3c.widget.autocomplete.widget.AutoCompleteWidget object at ...>
>>> print widget()
<input class="textType" id="field.foo" name="field.foo" type="text" value=""  />
<div id="field.foo.target" class="autoComplete"></div>
<script type="text/javascript">
new Ajax.Autocompleter('field.foo','field.foo.target',
'http://127.0.0.1/++widget++field.foo/suggestions'
,options={
paramName: 'value'
});
</script>

让我们添加一些输入。请注意,输入必须与词汇表术语的标题匹配。

>>> request.form['field.foo']=u'Title1'
>>> widget.getInputValue()
u'value1'

如果没有匹配的标题,将引发 ConversionError。

>>> request.form['field.foo']=u'Unknown'
>>> widget.getInputValue()
Traceback (most recent call last):
...
ConversionError: ('Invalid value', u'Unknown')

此外,表单值是具有给定值的术语的标题。

>>> widget._toFormValue('value1')
u'Title1'
>>> suggestions = widget.getSuggestions('Title')
>>> [title for title in suggestions]
[u'Title1', u'Title2', u'Title3']
>>> suggestions = widget.getSuggestions('Title1')
>>> [title for title in suggestions]
[u'Title1']
>>> suggestions = widget.getSuggestions('ABC')
>>> [title for title in suggestions]
[]
>>> suggestions = widget.getSuggestions('title')
>>> [title for title in suggestions]
[u'Title1', u'Title2', u'Title3']

自动完成小部件演示

此演示包提供了一个简单的内容类,它使用 z3c 自动完成小部件。

>>> from zope.testbrowser.testing import Browser
>>> browser = Browser()
>>> browser.handleErrors = False
>>> browser.addHeader('Authorization', 'Basic mgr:mgrpw')
>>> browser.open('https://127.0.0.1/@@contents.html')

可以通过点击添加菜单中的“自动完成小部件演示”链接来添加它。并给它一个名字。

>>> link = browser.getLink('Autocomplete Widget Demo')
>>> link.click()
>>> nameCtrl = browser.getControl(name='new_value')
>>> nameCtrl.value = 'mydemo'
>>> applyCtrl = browser.getControl('Apply')
>>> applyCtrl.click()
>>> link = browser.getLink('mydemo')
>>> link.click()
>>> browser.url
'https://127.0.0.1/mydemo/@@edit.html'

让我们通过直接访问来测试小部件的渲染。

>>> browser.open('https://127.0.0.1/mydemo/@@edit.html/++widget++country')
>>> print browser.contents
<input class="textType" ...
</script>

建议由其自己的视图提供。

>>> browser.open('https://127.0.0.1/mydemo/@@edit.html/++widget++country/suggestions')
>>> print browser.contents
>>> browser.open('https://127.0.0.1/++lang++en/mydemo/@@edit.html/++widget++country/suggestions?value=a')
>>> print browser.contents
<BLANKLINE>
 <ul>
  <li>Algeria</li>
  <li>Andorra</li>
  <li>Antigua and Barbuda</li>
  <li>Afghanistan</li>
  <li>Anguilla</li>
  <li>Armenia</li>
  <li>Albania</li>
  <li>Angola</li>
  <li>Antarctica</li>
  <li>American Samoa</li>
  <li>Argentina</li>
  <li>Australia</li>
  <li>Austria</li>
  <li>Aruba</li>
  <li>Azerbaijan</li>
 </ul>
<BLANKLINE>
<BLANKLINE>

建议被翻译。

>>> browser.open('https://127.0.0.1/++lang++de/mydemo/@@edit.html/++widget++country/suggestions?value=a')
>>> print browser.contents
<BLANKLINE>
 <ul>
  <li>Amerikanische Jungferninseln</li>
  <li>Amerikanisch-Ozeanien</li>
  <li>Algerien</li>
  <li>Andorra</li>
  <li>Antigua und Barbuda</li>
  <li>Afghanistan</li>
  <li>Anguilla</li>
  <li>Armenien</li>
  <li>Albanien</li>
  <li>Angola</li>
  <li>Antarktis</li>
  <li>Amerikanisch-Samoa</li>
  <li>Argentinien</li>
  <li>Australien</li>
  <li>Aruba</li>
  <li>Aserbaidschan</li>
 </ul>
<BLANKLINE>
<BLANKLINE>

国家选择小部件

此包提供了选择国家的控件。下拉类型被注册为 Country 架构的默认值。

在翻译后对选项进行排序是件麻烦事。

在我们开始之前,我们必须做一些小小的设置

>>> import zope.component
>>> import zope.schema
>>> import zope.app.form.browser
>>> from z3c.widget.country.widget import CountryInputDropdown
>>> from z3c.widget.country import ICountry
>>> from z3c.i18n.iso import territoryVocabularyFactory
>>> from zope.publisher.interfaces.browser import IBrowserRequest

首先,我们必须创建一个字段和一个请求

>>> from z3c.widget.country import Country
>>> countryFld = Country(
...     __name__='country',
...     title=u'Country',
...     description=u'Select a Country')
>>> from zope.publisher.browser import TestRequest
>>> request = TestRequest()

现在我们可以初始化小部件。

>>> class Content(object):
...     country = None
>>> content = Content()
>>> boundCountry = countryFld.bind(content)
>>> widget = CountryInputDropdown(boundCountry,
...   territoryVocabularyFactory(None), request)

让我们确保所有字段都有正确的值

>>> widget.name
'field.country'
>>> widget.label
u'Country'
>>> widget.hint
u'Select a Country'
>>> widget.visible
True

让我们看看小部件是如何渲染的

>>> print widget()
<div>
<div class="value">
<select id="field.country" name="field.country" size="1" >
<option value="AF">Afghanistan</option>
<option value="AL">Albania</option>
<option value="DZ">Algeria</option>
...
<option value="HU">Hungary</option>
<option value="IS">Iceland</option>
<option value="IN">India</option>
...
<option value="ZM">Zambia</option>
<option value="ZW">Zimbabwe</option>
</select>
...

#让我们看看德语翻译:#z3c.i18n 注册所需!!! # # >>> request = TestRequest(HTTP_ACCEPT_LANGUAGE=’de’) # # >>> widget = CountryInputDropdown(boundCountry, # … territoryVocabularyFactory(None), request) # # >>> print widget() # <div> # <div class=”value”> # <select id=”field.country” name=”field.country” size=”1” > # <option value=”AF”>阿富汗斯坦</option> # <option value=”AL”>阿尔巴尼亚</option> # <option value=”DZ”>阿尔及利亚</option> # … # <option value=”HU”>匈牙利</option> # <option value=”IS”>冰岛</option> # <option value=”IN”>印度</option> # … # <option value=”ZM”>赞比亚</option> # <option value=”ZW”>津巴布韦</option> # </select> # …

日期选择小部件

“DateSelectWidget”小部件提供了三个选择框,分别表示日期、月份和年份。

首先,我们必须创建一个字段和一个请求。请注意,我们可以在该小部件中设置年份范围

>>> import datetime
>>> from z3c.schema.dateselect import DateSelect
>>> from z3c.widget.dateselect.browser import DateSelectWidget
>>> field = DateSelect(
...     title=u'Birthday',
...     description=u'Somebodys birthday',
...     yearRange=range(1930, 2007),
...     required=True)
>>> field.__name__ = 'field'
>>> from zope.publisher.browser import TestRequest
>>> request = TestRequest()

现在我们可以初始化小部件。

>>> widget = DateSelectWidget(field, request)

让我们确保所有字段都有正确的值

>>> widget.name
'field.field'
>>> widget.label
u'Birthday'
>>> widget.hint
u'Somebodys birthday'
>>> widget.visible
True
>>> widget.required
True

构造函数还应该创建了 3 个小部件

>>> widget.widgets['year']
<z3c.widget.dateselect.browser.DropdownWidget object at ...>
>>> widget.widgets['month']
<z3c.widget.dateselect.browser.DropdownWidget object at ...>
>>> widget.widgets['day']
<z3c.widget.dateselect.browser.DropdownWidget object at ...>

让我们也测试一下年份范围

>>> '1929' in widget.widgets['year'].vocabulary.by_token.keys()
False
>>> '1930' in widget.widgets['year'].vocabulary.by_token.keys()
True
>>> '2006' in widget.widgets['year'].vocabulary.by_token.keys()
True
>>> '2007' in widget.widgets['year'].vocabulary.by_token.keys()
False

测试另一个年份范围

>>> field2 = DateSelect(
...     title=u'Another Birthday',
...     yearRange=range(2000, 2010))
>>> field2.__name__ = 'field'
>>> widget2 = DateSelectWidget(field2, request)
>>> '1930' in widget2.widgets['year'].vocabulary.by_token.keys()
False
>>> '2000' in widget2.widgets['year'].vocabulary.by_token.keys()
True
>>> '2009' in widget2.widgets['year'].vocabulary.by_token.keys()
True
>>> '2010' in widget2.widgets['year'].vocabulary.by_token.keys()
False

setRenderedValue(value) 方法

第一个方法是 setRenderedValue()。根据值的类型,小部件有两个用途。如果值是自定义评分系统,它将信息发送到自定义、最小和最大小部件

>>> widget = DateSelectWidget(field, request)
>>> year = 2000
>>> month = 12
>>> day = 31
>>> data = datetime.date(year, month, day)
>>> widget.setRenderedValue(data)
>>> 'value="2000"' in widget()
True
>>> 'value="12"' in widget()
True
>>> 'value="31"' in widget()
True

setPrefix(prefix) 方法

前缀确定小部件及其所有子小部件的名称。

>>> widget.name
'field.field'
>>> widget.widgets['year'].name
'field.field.year'
>>> widget.widgets['month'].name
'field.field.month'
>>> widget.widgets['day'].name
'field.field.day'
>>> widget.setPrefix('test.')
>>> widget.name
'test.field'
>>> widget.widgets['year'].name
'test.field.year'
>>> widget.widgets['month'].name
'test.field.month'
>>> widget.widgets['day'].name
'test.field.day'

如果前缀不以点结尾,则添加一个点

>>> widget.setPrefix('test')
>>> widget.name
'test.field'
>>> widget.widgets['year'].name
'test.field.year'
>>> widget.widgets['month'].name
'test.field.month'
>>> widget.widgets['day'].name
'test.field.day'

getInputValue() 方法

此方法返回一个日期对象

>>> request = TestRequest(form={
...     'field.field.year': '2006',
...     'field.field.month': '2',
...     'field.field.day': '24'})
>>> widget = DateSelectWidget(field, request)
>>> value = widget.getInputValue()
>>> value.year
2006
>>> value.month
2
>>> value.day
24

如果一组值无法生成有效的日期对象,则会引发一个值错误

>>> request = TestRequest(form={
...     'field.field.year': '2006',
...     'field.field.month': '2',
...     'field.field.day': '29'})
>>> widget = DateSelectWidget(field, request)
>>> widget.getInputValue()
Traceback (most recent call last):
...
WidgetInputError: ('field', u'Birthday', u'day is out of range for month')
>>> widget._error.__class__
<class 'zope.formlib.interfaces.WidgetInputError'>

applyChanges(content) 方法

此方法将新日期应用于传入的内容。但是,它必须足够智能,以检测值是否真正发生了变化。

>>> class Content(object):
...     field = None
>>> content = Content()
>>> request = TestRequest(form={
...     'field.field.year': '2006',
...     'field.field.month': '2',
...     'field.field.day': '24'})
>>> widget = DateSelectWidget(field, request)
>>> widget.applyChanges(content)
True
>>> content.field
datetime.date(2006, 2, 24)
>>> widget.applyChanges(content)
False

hasInput() 方法

此方法检查任何输入,但不对其进行验证。

>>> request = TestRequest()
>>> widget = DateSelectWidget(field, request)
>>> widget.hasInput()
False
>>> request = TestRequest(form={
...     'field.field.year': '2006'})
>>> widget = DateSelectWidget(field, request)
>>> widget.hasInput()
False
>>> request = TestRequest(form={
...     'field.field.month': '2'})
>>> widget = DateSelectWidget(field, request)
>>> widget.hasInput()
False
>>> request = TestRequest(form={
...     'field.field.day': '24'})
>>> widget = DateSelectWidget(field, request)
>>> widget.hasInput()
False
>>> request = TestRequest(form={
...     'field.field.year': '2006',
...     'field.field.month': '2',
...     'field.field.day': '24'})
>>> widget = DateSelectWidget(field, request)
>>> widget.hasInput()
True

hasValidInput() 方法

除了检查任何输入外,此方法还检查输入是否有效

>>> request = TestRequest()
>>> widget = DateSelectWidget(field, request)
>>> widget.hasValidInput()
False
>>> request = TestRequest(form={
...     'field.field.year': '2006'})
>>> widget = DateSelectWidget(field, request)
>>> widget.hasValidInput()
False
>>> request = TestRequest(form={
...     'field.field.month': '2'})
>>> widget = DateSelectWidget(field, request)
>>> widget.hasValidInput()
False
>>> request = TestRequest(form={
...     'field.field.day': '24'})
>>> widget = DateSelectWidget(field, request)
>>> widget.hasValidInput()
False
>>> request = TestRequest(form={
...     'field.field.year': '2006',
...     'field.field.month': '2',
...     'field.field.day': '24'})
>>> widget = DateSelectWidget(field, request)
>>> widget.hasValidInput()
True

hidden() 方法

此方法将输出渲染为隐藏字段

>>> request = TestRequest(form={
...     'field.field.year': '2006',
...     'field.field.month': '2',
...     'field.field.day': '24'})
>>> widget = DateSelectWidget(field, request)
>>> print widget.hidden()
<input class="hiddenType" id="field.field.year" name="field.field.year"
       type="hidden" value="2006" />
<input class="hiddenType" id="field.field.month" name="field.field.month"
       type="hidden" value="2"  />
<input class="hiddenType" id="field.field.day" name="field.field.day"
       type="hidden" value="24"  />

error() 方法

让我们测试一些不良数据并检查错误处理。

日期字段包含无效值

>>> request = TestRequest(form={
...     'field.field.year': '2006',
...     'field.field.month': '2',
...     'field.field.day': '99'})
>>> widget = DateSelectWidget(field, request)
>>> widget.getInputValue()
Traceback (most recent call last):
...
ConversionError: (u'Invalid value', InvalidValue("token '99' not found in vocabulary"))
>>> print widget.error()
<span class="error">Invalid value</span>

月份字段包含无效值

>>> request = TestRequest(form={
...     'field.field.year': '2006',
...     'field.field.month': '0',
...     'field.field.day': '31'})
>>> widget = DateSelectWidget(field, request)
>>> widget.getInputValue()
Traceback (most recent call last):
...
ConversionError: (u'Invalid value', InvalidValue("token '0' not found in vocabulary"))
>>> print widget.error()
<span class="error">Invalid value</span>

年份字段包含无效值

>>> request = TestRequest(form={
...     'field.field.year': '1900',
...     'field.field.month': '1',
...     'field.field.day': '31'})
>>> widget = DateSelectWidget(field, request)
>>> widget.getInputValue()
Traceback (most recent call last):
...
ConversionError: (u'Invalid value', InvalidValue("token '1900' not found in vocabulary"))
>>> print widget.error()
<span class="error">Invalid value</span>

单个输入是正确的,但没有创建一个有效的日期。

>>> request = TestRequest(form={
...     'field.field.year': '1980',
...     'field.field.month': '2',
...     'field.field.day': '31'})
>>> widget = DateSelectWidget(field, request)
>>> widget.getInputValue()
Traceback (most recent call last):
...
WidgetInputError: ('field', u'Birthday', u'day is out of range for month')
>>> print widget.error()
<span class="error">day is out of range for month</span>

没有发生错误

>>> request = TestRequest(form={
...     'field.field.year': '1980',
...     'field.field.month': '1',
...     'field.field.day': '31'})
>>> widget = DateSelectWidget(field, request)
>>> widget.getInputValue()
datetime.date(1980, 1, 31)
>>> widget.error()
''

__call__() 方法

此方法使用子部件渲染小部件。让我们看看输出

>>> request = TestRequest(form={
...     'field.field.year': '2006',
...     'field.field.month': '2',
...     'field.field.day': '24'})
>>> widget = DateSelectWidget(field, request)
>>> print widget()
<select id="field.field.day" name="field.field.day" size="1" >
<option value="1">1</option>
...
<option value="23">23</option>
<option selected="selected" value="24">24</option>
<option value="25">25</option>
...
<option value="31">31</option>
</select><input name="field.field.day-empty-marker" type="hidden"
                value="1" />&nbsp;
<select id="field.field.month" name="field.field.month" size="1" >
<option value="1">1</option>
<option selected="selected" value="2">2</option>
<option value="3">3</option>
...
<option value="12">12</option>
</select><input name="field.field.month-empty-marker" type="hidden"
                value="1" />&nbsp;
<select id="field.field.year" name="field.field.year" size="1" >
<option value="1930">1930</option>
...
<option value="2005">2005</option>
<option selected="selected" value="2006">2006</option>
</select><input
    name="field.field.year-empty-marker" type="hidden" value="1" />
<BLANKLINE>

FLASH上传小部件

flashupload vars页面配置了flash前端

>>> from z3c.widget.flashupload import upload
>>> from zope.publisher.browser import TestRequest
>>> from zope.app.pagetemplate import ViewPageTemplateFile
>>> from zope.app.pagetemplate.simpleviewclass import SimpleViewClass
>>> request = TestRequest()
>>> context = object()
>>> viewClass = SimpleViewClass(
...     'flashuploadvars.pt', bases=(upload.FlashUploadVars,))
>>> view = viewClass(context, request)
>>> print view()
<?xml version="1.0" ?>
<var>
    <var name="file_progress">File Progress</var>
    <var name="overall_progress">Overall Progress</var>
    <var name="error">Error on uploading files</var>
    <var name="uploadcomplete">all files uploaded</var>
    <var name="uploadpartial">files uploaded</var>
    <var name="notuploaded">files were not uploaded because
       they're too big</var>
    <var name="maxfilesize">maximum file size is</var>
</var>
>>> view.allowedFileTypes = ('.jpg', '.gif')
>>> print view()
<?xml version="1.0" ?>
<var>
...
    <var name="allowedFileType">.jpg</var>
    <var name="allowedFileType">.gif</var>
 </var>

图像小部件

此图像小部件应作为图像字段的自定义小部件使用。与zope3中的默认小部件相比,如果没有明确选择“删除”复选框,它不会删除字段中的数据。

添加图像

>>> import zope.schema
>>> from zope.publisher.browser import TestRequest
>>> from zope import interface
>>> from zope.schema.fieldproperty import FieldProperty
>>> from zope.app.file.interfaces import IImage
>>> from z3c.widget.image.widget import ImageWidget
>>> from zope.app.file.image import Image

创建一个具有图像字段的文档类型。

>>> class ITestObject(interface.Interface):
...     image = zope.schema.Object(
...     title=u'Image',
...     schema=IImage)
>>> class TestObject(object):
...     interface.implements(ITestObject)
...     image = FieldProperty(ITestObject['image'])
>>> obj = TestObject()
>>> field = ITestObject['image'].bind(obj)

发送不带任何图像信息的请求。空字段不应该被更改...

>>> request = TestRequest(form={'field.image' : u''})
>>> widget = ImageWidget(field, request)
>>> widget._getFormInput() is None
True

向字段发送一些图像信息。图像信息应作为图像对象存储在字段中

>>> request = TestRequest(form={'field.image' : u'PNG123Test'})
>>> widget = ImageWidget(field, request)
>>> widget._getFormInput()
<zope.app.file.image.Image object at ...>

现在我们再次保存字段,但不带任何新的图像数据。旧的图像信息不应丢失

>>> obj.image = Image(u'PNG123Test')
>>> request = TestRequest(form={'field.image' : u''})
>>> widget = ImageWidget(field, request)
>>> widget._getFormInput() is obj.image
True

现在我们想要删除图像。表单输入现在应该是None。

>>> request = TestRequest(form={'field.image' : u'',
...     'field.image.delete': u'true'})
>>> widget = ImageWidget(field, request)
>>> widget._getFormInput() is None
True
>>> print widget()
<div class="z3cImageWidget">
  <input type="file" name="field.image" id="field.image" /><br/>
  <input type="checkbox" name="field.image.delete" value="true" />delete image
</div>

小部件命名空间

小部件命名空间提供了一种遍历表单库小部件的方法。

>>> from z3c.widget.namespace.namespace import WidgetHandler

让我们定义一个表单来测试此行为。

>>> from zope.formlib import form
>>> from zope import interface, schema
>>> class IMyContent(interface.Interface):
...     title = schema.TextLine(title=u'Title')
>>> class MyContent(object):
...     interface.implements(IMyContent)
...     title=None
>>> content = MyContent()
>>> from zope.publisher.browser import TestRequest
>>> request = TestRequest()
>>> class MyForm(form.EditForm):
...     form_fields = form.Fields(IMyContent)
>>> view = MyForm(content,request)
>>> handler = WidgetHandler(view,request)
>>> handler.traverse('title',None)
<zope.formlib.textwidgets.TextWidget object at ...>

可选下拉小部件

可选下拉小部件模拟了常见的桌面组合框小部件,它还可以接收自定义条目。

在我们开始之前,我们必须做一些小小的设置

>>> import zope.component
>>> import zope.schema
>>> import zope.app.form.browser
>>> from zope.publisher.interfaces.browser import IBrowserRequest
>>> zope.component.provideAdapter(
...     zope.app.form.browser.TextWidget,
...     (zope.schema.interfaces.ITextLine, IBrowserRequest),
...     zope.app.form.interfaces.IInputWidget)

首先,我们必须创建一个字段和一个请求

>>> from z3c.schema.optchoice import OptionalChoice
>>> optchoice = OptionalChoice(
...     __name__='occupation',
...     title=u'Occupation',
...     description=u'The Occupation',
...     values=(u'Programmer', u'Designer', u'Project Manager'),
...     value_type=zope.schema.TextLine())
>>> from zope.publisher.browser import TestRequest
>>> request = TestRequest()

现在我们可以初始化小部件。

>>> class Content(object):
...     occupation = None
>>> content = Content()
>>> boundOptChoice = optchoice.bind(content)
>>> from z3c.widget.optdropdown import OptionalDropdownWidget
>>> widget = OptionalDropdownWidget(boundOptChoice, request)

让我们确保所有字段都有正确的值

>>> widget.name
'field.occupation'
>>> widget.label
u'Occupation'
>>> widget.hint
u'The Occupation'
>>> widget.visible
True
>>> widget.required
True

构造函数还应创建了2个小部件

>>> widget.customWidget
<zope.formlib.textwidgets.TextWidget object at ...>
>>> widget.dropdownWidget
<zope.formlib.itemswidgets.DropdownWidget object at ...>

setRenderedValue(value) 方法

第一个方法是setRenderedValue()。根据值的类型,小部件有两个用途。如果值是自定义值,它将信息发送到自定义小部件

>>> print widget.customWidget()
<... value="" />
>>> 'selected=""' in widget.dropdownWidget()
False
>>> widget.setRenderedValue(u'Scientist')
>>> print widget.customWidget()
<... value="Scientist" />
>>> 'selected=""' in widget.dropdownWidget()
False

在重置小部件并传入词汇表中的其中一个选项后,值应在下拉列表中显示

>>> widget.setRenderedValue(u'Designer')
>>> print widget.customWidget()
<... value="" />
>>> print widget.dropdownWidget()
<div>
...
<option selected="selected" value="Designer">Designer</option>
...
</div>

setPrefix(prefix) 方法

前缀决定了小部件和子小部件的名称。

>>> widget.name
'field.occupation'
>>> widget.dropdownWidget.name
'field.occupation.occupation'
>>> widget.customWidget.name
'field.occupation.custom'
>>> widget.setPrefix('test.')
>>> widget.name
'test.occupation'
>>> widget.dropdownWidget.name
'test.occupation.occupation'
>>> widget.customWidget.name
'test.occupation.custom'

getInputValue() 方法

此方法根据输入返回一个值;假定数据是有效的。在我们的情况下,这意味着如果我们输入了一个自定义值,它将被返回

>>> request = TestRequest(form={
...     'field.occupation.custom': u'Teacher'})
>>> widget = OptionalDropdownWidget(boundOptChoice, request)
>>> widget.getInputValue()
u'Teacher'

另一方面,如果我们从词汇表中选择了选项,它应该被返回

>>> request = TestRequest(form={
...     'field.occupation.occupation': u'Designer'})
>>> widget = OptionalDropdownWidget(boundOptChoice, request)
>>> widget.getInputValue()
u'Designer'

applyChanges(content) 方法

此方法将新值应用于传入的内容。但是,它必须足够智能,以检测值是否真正发生了变化。

>>> request = TestRequest(form={
...     'field.occupation.custom': u'Teacher'})
>>> widget = OptionalDropdownWidget(boundOptChoice, request)
>>> widget.applyChanges(content)
True
>>> content.occupation
u'Teacher'
>>> widget.applyChanges(content)
False
>>> request = TestRequest(form={
...     'field.occupation.occupation': u'Designer'})
>>> widget = OptionalDropdownWidget(boundOptChoice, request)
>>> widget.applyChanges(content)
True
>>> content.occupation
u'Designer'
>>> widget.applyChanges(content)
False

hasInput() 方法

此方法检查任何输入,但不进行验证。在我们的情况下,这意味着已经选择了一个选项或输入了自定义值。

>>> request = TestRequest()
>>> widget = OptionalDropdownWidget(boundOptChoice, request)
>>> widget.hasInput()
False
>>> request = TestRequest(form={
...     'field.occupation.custom': u'Teacher\nBad Stuff'})
>>> widget = OptionalDropdownWidget(boundOptChoice, request)
>>> widget.hasInput()
True
>>> request = TestRequest(form={
...     'field.occupation.occupation': u'Waitress'})
>>> widget = OptionalDropdownWidget(boundOptChoice, request)
>>> widget.hasInput()
True

hasValidInput() 方法

除了检查任何输入外,此方法还检查输入是否有效

>>> request = TestRequest()
>>> widget = OptionalDropdownWidget(boundOptChoice, request)
>>> widget.hasValidInput()
False
>>> request = TestRequest(form={
...     'field.occupation.occupation': u'Waitress'})
>>> widget = OptionalDropdownWidget(boundOptChoice, request)
>>> widget.hasValidInput()
False
>>> request = TestRequest(form={
...     'field.occupation.occupation': u'Designer'})
>>> widget = OptionalDropdownWidget(boundOptChoice, request)
>>> widget.hasValidInput()
True
>>> request = TestRequest(form={
...     'field.occupation.custom': u'Teacher\nBad Stuff'})
>>> widget = OptionalDropdownWidget(boundOptChoice, request)
>>> widget.hasValidInput()
False
>>> request = TestRequest(form={
...     'field.occupation.custom': u'Teacher'})
>>> widget = OptionalDropdownWidget(boundOptChoice, request)
>>> widget.hasValidInput()
True

hidden() 方法

此方法通过简单地将两个小部件的隐藏输出连接起来实现

>>> request = TestRequest()
>>> widget = OptionalDropdownWidget(boundOptChoice, request)
>>> widget.setRenderedValue(u'Designer')
>>> print widget.hidden()
<input class="hiddenType" id="field.occupation.occupation"
       name="field.occupation.occupation" type="hidden" value="Designer"  />
<input class="hiddenType" id="field.occupation.custom"
       name="field.occupation.custom" type="hidden" value=""  />
>>> widget.setRenderedValue(u'Teacher')
>>> print widget.hidden()
<input class="hiddenType" id="field.occupation.occupation"
       name="field.occupation.occupation" type="hidden" value=""  />
<input class="hiddenType" id="field.occupation.custom"
       name="field.occupation.custom" type="hidden" value="Teacher"  />

error() 方法

再次,我们有两种情况。如果下拉列表中发生错误,将报告错误

>>> from zope.app.form.interfaces import IWidgetInputError
>>> from zope.app.form.browser.exception import WidgetInputErrorView
>>> from zope.app.form.browser.interfaces import IWidgetInputErrorView
>>> zope.component.provideAdapter(
...     WidgetInputErrorView,
...     (IWidgetInputError, IBrowserRequest), IWidgetInputErrorView)
>>> request = TestRequest(form={
...     'field.occupation.occupation': u'Designer'})
>>> widget = OptionalDropdownWidget(boundOptChoice, request)
>>> widget.getInputValue()
u'Designer'
>>> widget.error()
''
>>> request = TestRequest(form={
...     'field.occupation.occupation': u'Waitress'})
>>> widget = OptionalDropdownWidget(boundOptChoice, request)
>>> widget.getInputValue()
Traceback (most recent call last):
...
ConversionError: (u'Invalid value', InvalidValue("token u'Waitress' not found in vocabulary"))
>>> widget.error()
u'<span class="error">Invalid value</span>'

否则将报告自定义小部件的错误

>>> request = TestRequest(form={
...     'field.occupation.custom': u'Teacher'})
>>> widget = OptionalDropdownWidget(boundOptChoice, request)
>>> widget.getInputValue()
u'Teacher'
>>> widget.error()
''
>>> request = TestRequest(form={
...     'field.occupation.custom': u'Teacher\nBad Stuff'})
>>> widget = OptionalDropdownWidget(boundOptChoice, request)
>>> widget.getInputValue()
Traceback (most recent call last):
...
WidgetInputError: ('custom', u'', ConstraintNotSatisfied(u'Teacher\nBad Stuff'))
>>> widget.error()
u'<span class="error">Constraint not satisfied</span>'

__call__() 方法

此方法使用子小部件渲染小部件。它简单地将两个小部件的输出添加在一起,在它们之间放置连接符

>>> request = TestRequest(form={
...     'field.occupation.custom': u'Teacher'})
>>> widget = OptionalDropdownWidget(boundOptChoice, request)
>>> widget.connector
u'<br />\n'
>>> print widget()
<div>
<div class="value">
<select id="field.occupation.occupation"
        name="field.occupation.occupation" size="1" >
<option selected="selected" value="">(nothing selected)</option>
<option value="Programmer">Programmer</option>
<option value="Designer">Designer</option>
<option value="Project Manager">Project Manager</option>
</select>
</div>
<input name="field.occupation.occupation-empty-marker" type="hidden"
       value="1" />
</div><br />
<input class="textType" id="field.occupation.custom"
       name="field.occupation.custom" size="20" type="text" value="Teacher" />

序列表小部件

此包提供了一个序列小部件,就像zope.app.form.browser.sequencewidget。主要区别在于它将子对象的字段水平放置在表格中。这意味着类似收据项目表单的工作变得非常容易。

还有一个小部件(SequenceTableJSWidget),它使用javascript在浏览器中执行添加/删除项目。诀窍是在HTML中嵌入一个不可见的空行模板,每次需要新行时都添加它。

JS的缺点
  • 验证仅在将整个表单提交到服务器时进行。

  • 提交表单和使用浏览器后退按钮不起作用。

警告!

子对象必须具有子部件。如果子对象基于zope.schema.Object,则通常如此。

待办事项

测试。有些已经有了,有些是从z.a.form.browser复制的,需要修复。

SSN小部件

社会保险号码部件可以用作文本行字段的自定义部件,强制执行特定的布局。

首先,我们必须创建一个字段和一个请求

>>> import datetime
>>> import zope.schema
>>> field = zope.schema.TextLine(
...     title=u'SSN',
...     description=u'Social Security Number',
...     required=True)
>>> field.__name__ = 'field'
>>> from zope.publisher.browser import TestRequest
>>> request = TestRequest()

现在我们可以初始化小部件。

>>> from z3c.widget.ssn.browser import SSNWidget
>>> widget = SSNWidget(field, request)

让我们确保所有字段都有正确的值

>>> widget.name
'field.field'
>>> widget.label
u'SSN'
>>> widget.hint
u'Social Security Number'
>>> widget.visible
True
>>> widget.required
True

构造函数还应创建3个子部件

>>> widget.widgets['first']
<zope.formlib.textwidgets.TextWidget object at ...>
>>> widget.widgets['second']
<zope.formlib.textwidgets.TextWidget object at ...>
>>> widget.widgets['third']
<zope.formlib.textwidgets.TextWidget object at ...>

setRenderedValue(value) 方法

第一种方法是setRenderedValue()。根据值的类型,部件有两个用例

>>> widget = SSNWidget(field, request)
>>> widget.setRenderedValue(u'123-45-6789')
>>> print widget()
<input class="textType" id="field.field.first" name="field.field.first"
       size="3" type="text" value="123"  />&nbsp;&mdash;&nbsp;
<input class="textType" id="field.field.second" name="field.field.second"
       size="2" type="text" value="45"  />&nbsp;&mdash;&nbsp;
<input class="textType" id="field.field.third" name="field.field.third"
       size="4" type="text" value="6789"  />

setPrefix(prefix) 方法

前缀确定小部件及其所有子小部件的名称。

>>> widget.name
'field.field'
>>> widget.widgets['first'].name
'field.field.first'
>>> widget.widgets['second'].name
'field.field.second'
>>> widget.widgets['third'].name
'field.field.third'
>>> widget.setPrefix('test.')
>>> widget.name
'test.field'
>>> widget.widgets['first'].name
'test.field.first'
>>> widget.widgets['second'].name
'test.field.second'
>>> widget.widgets['third'].name
'test.field.third'

如果前缀不以点结尾,则添加一个点

>>> widget.setPrefix('test')
>>> widget.name
'test.field'
>>> widget.widgets['first'].name
'test.field.first'
>>> widget.widgets['second'].name
'test.field.second'
>>> widget.widgets['third'].name
'test.field.third'

getInputValue() 方法

此方法返回完整的SSN字符串

>>> request = TestRequest(form={
...     'field.field.first': '123',
...     'field.field.second': '45',
...     'field.field.third': '6789'})
>>> widget = SSNWidget(field, request)
>>> value = widget.getInputValue()
>>> value
u'123-45-6789'

如果一组值不产生有效的字符串,则会引发值错误

>>> request = TestRequest(form={
...     'field.field.first': '1234',
...     'field.field.second': '56',
...     'field.field.third': '7890'})
>>> widget = SSNWidget(field, request)
>>> widget.getInputValue()
Traceback (most recent call last):
...
WidgetInputError: ('first', u'Frst three digits', ConstraintNotSatisfied(u'1234'))
>>> widget._error.__class__
<class 'zope.formlib.interfaces.WidgetInputError'>

applyChanges(content) 方法

此方法将新的SSN应用于传递的内容。但是,它必须足够智能,能够检测值是否真的已更改。

>>> class Content(object):
...     field = None
>>> content = Content()
>>> request = TestRequest(form={
...     'field.field.first': '123',
...     'field.field.second': '45',
...     'field.field.third': '6789'})
>>> widget = SSNWidget(field, request)
>>> widget.applyChanges(content)
True
>>> content.field
u'123-45-6789'
>>> widget.applyChanges(content)
False

hasInput() 方法

此方法检查任何输入,但不对其进行验证。

>>> request = TestRequest()
>>> widget = SSNWidget(field, request)
>>> widget.hasInput()
False
>>> request = TestRequest(form={
...     'field.field.first': '123'})
>>> widget = SSNWidget(field, request)
>>> widget.hasInput()
False
>>> request = TestRequest(form={
...     'field.field.second': '45'})
>>> widget = SSNWidget(field, request)
>>> widget.hasInput()
False
>>> request = TestRequest(form={
...     'field.field.third': '6789'})
>>> widget = SSNWidget(field, request)
>>> widget.hasInput()
False
>>> request = TestRequest(form={
...     'field.field.first': '123',
...     'field.field.second': '45',
...     'field.field.third': '6789'})
>>> widget = SSNWidget(field, request)
>>> widget.hasInput()
True

hasValidInput() 方法

除了检查任何输入外,此方法还检查输入是否有效

>>> request = TestRequest()
>>> widget = SSNWidget(field, request)
>>> widget.hasValidInput()
False
>>> request = TestRequest(form={
...     'field.field.first': '123'})
>>> widget = SSNWidget(field, request)
>>> widget.hasValidInput()
False
>>> request = TestRequest(form={
...     'field.field.second': '45'})
>>> widget = SSNWidget(field, request)
>>> widget.hasValidInput()
False
>>> request = TestRequest(form={
...     'field.field.third': '6789'})
>>> widget = SSNWidget(field, request)
>>> widget.hasValidInput()
False
>>> request = TestRequest(form={
...     'field.field.first': '123',
...     'field.field.second': '45',
...     'field.field.third': '6789'})
>>> widget = SSNWidget(field, request)
>>> widget.hasValidInput()
True

hidden() 方法

此方法将输出渲染为隐藏字段

>>> request = TestRequest(form={
...     'field.field.first': '123',
...     'field.field.second': '45',
...     'field.field.third': '6789'})
>>> widget = SSNWidget(field, request)
>>> print widget.hidden()
<input class="hiddenType" id="field.field.first" name="field.field.first"
       type="hidden" value="123" />
<input class="hiddenType" id="field.field.second" name="field.field.second"
       type="hidden" value="45"  />
<input class="hiddenType" id="field.field.third" name="field.field.third"
       type="hidden" value="6789"  />

error() 方法

让我们测试一些不良数据并检查错误处理。

第三个字段包含无效值

>>> request = TestRequest(form={
...     'field.field.first': '123',
...     'field.field.second': '45',
...     'field.field.third': '678'})
>>> widget = SSNWidget(field, request)
>>> widget.getInputValue()
Traceback (most recent call last):
...
WidgetInputError: ('third', u'Third four digits', ConstraintNotSatisfied(u'678'))
>>> print widget.error()
<span class="error">Constraint not satisfied</span>

第二个字段包含无效值

>>> request = TestRequest(form={
...     'field.field.first': '123',
...     'field.field.second': '4-',
...     'field.field.third': '6789'})
>>> widget = SSNWidget(field, request)
>>> widget.getInputValue()
Traceback (most recent call last):
...
WidgetInputError: ('second', u'Second two digits', ConstraintNotSatisfied(u'4-'))
>>> print widget.error()
<span class="error">Constraint not satisfied</span>

第一个字段包含无效值

>>> request = TestRequest(form={
...     'field.field.first': 'xxx',
...     'field.field.second': '45',
...     'field.field.third': '6789'})
>>> widget = SSNWidget(field, request)
>>> widget.getInputValue()
Traceback (most recent call last):
...
WidgetInputError: ('first', u'Frst three digits', ConstraintNotSatisfied(u'xxx'))
>>> print widget.error()
<span class="error">Constraint not satisfied</span>

没有发生错误

>>> request = TestRequest(form={
...     'field.field.first': '123',
...     'field.field.second': '45',
...     'field.field.third': '6789'})
>>> widget = SSNWidget(field, request)
>>> widget.getInputValue()
u'123-45-6789'
>>> widget.error()
''

__call__() 方法

此方法使用子部件渲染小部件。让我们看看输出

>>> request = TestRequest(form={
...     'field.field.first': '123',
...     'field.field.second': '45',
...     'field.field.third': '6789'})
>>> widget = SSNWidget(field, request)
>>> print widget()
<input class="textType" id="field.field.first" name="field.field.first"
       size="3" type="text" value="123"  />&nbsp;&mdash;&nbsp;
<input class="textType" id="field.field.second" name="field.field.second"
       size="2" type="text" value="45"  />&nbsp;&mdash;&nbsp;
<input class="textType" id="field.field.third" name="field.field.third"
       size="4" type="text" value="6789"  />

HTML-Editor小部件 TinyMCE

此包通过使用优秀的TinyMCE编辑器(见:http://tinymce.moxiecode.com/)提供HTML内容的WYSIWYG-Editor-Widget。

美国电话小部件

美国电话号码部件可以用作文本行字段的自定义部件,强制执行特定的布局。

首先,我们必须创建一个字段和一个请求

>>> import datetime
>>> import zope.schema
>>> field = zope.schema.TextLine(
...     title=u'Phone',
...     description=u'Phone Number',
...     required=True)
>>> field.__name__ = 'field'
>>> from zope.publisher.browser import TestRequest
>>> request = TestRequest()

现在我们可以初始化小部件。

>>> from z3c.widget.usphone.browser import PhoneWidget
>>> widget = PhoneWidget(field, request)

让我们确保所有字段都有正确的值

>>> widget.name
'field.field'
>>> widget.label
u'Phone'
>>> widget.hint
u'Phone Number'
>>> widget.visible
True
>>> widget.required
True

构造函数还应创建3个子部件

>>> widget.widgets['first']
<zope.formlib.textwidgets.TextWidget object at ...>
>>> widget.widgets['second']
<zope.formlib.textwidgets.TextWidget object at ...>
>>> widget.widgets['third']
<zope.formlib.textwidgets.TextWidget object at ...>

setRenderedValue(value) 方法

第一种方法是setRenderedValue()。根据值的类型,部件有两个用例

>>> widget = PhoneWidget(field, request)
>>> widget.setRenderedValue(u'123-456-7890')
>>> print widget()
(<input class="textType" id="field.field.first" name="field.field.first"
        size="3" type="text" value="123"  />)&nbsp;
<input class="textType" id="field.field.second" name="field.field.second"
       size="3" type="text" value="456"  />&nbsp;&mdash;&nbsp;
<input class="textType" id="field.field.third" name="field.field.third"
       size="4" type="text" value="7890"  />

setPrefix(prefix) 方法

前缀确定小部件及其所有子小部件的名称。

>>> widget.name
'field.field'
>>> widget.widgets['first'].name
'field.field.first'
>>> widget.widgets['second'].name
'field.field.second'
>>> widget.widgets['third'].name
'field.field.third'
>>> widget.setPrefix('test.')
>>> widget.name
'test.field'
>>> widget.widgets['first'].name
'test.field.first'
>>> widget.widgets['second'].name
'test.field.second'
>>> widget.widgets['third'].name
'test.field.third'

如果前缀不以点结尾,则添加一个点

>>> widget.setPrefix('test')
>>> widget.name
'test.field'
>>> widget.widgets['first'].name
'test.field.first'
>>> widget.widgets['second'].name
'test.field.second'
>>> widget.widgets['third'].name
'test.field.third'

getInputValue() 方法

此方法返回完整的电话字符串

>>> request = TestRequest(form={
...     'field.field.first': '123',
...     'field.field.second': '456',
...     'field.field.third': '7890'})
>>> widget = PhoneWidget(field, request)
>>> value = widget.getInputValue()
>>> value
u'123-456-7890'

如果一组值不产生有效的字符串,则会引发值错误

>>> request = TestRequest(form={
...     'field.field.first': '1234',
...     'field.field.second': '56',
...     'field.field.third': '7890'})
>>> widget = PhoneWidget(field, request)
>>> widget.getInputValue()
Traceback (most recent call last):
...
WidgetInputError: ('first', u'Area Code', ConstraintNotSatisfied(u'1234'))
>>> widget._error.__class__
<class 'zope.formlib.interfaces.WidgetInputError'>

applyChanges(content) 方法

此方法将新的电话号码应用于传递的内容。但是,它必须足够智能,能够检测值是否真的已更改。

>>> class Content(object):
...     field = None
>>> content = Content()
>>> request = TestRequest(form={
...     'field.field.first': '123',
...     'field.field.second': '456',
...     'field.field.third': '7890'})
>>> widget = PhoneWidget(field, request)
>>> widget.applyChanges(content)
True
>>> content.field
u'123-456-7890'
>>> widget.applyChanges(content)
False

hasInput() 方法

此方法检查任何输入,但不对其进行验证。

>>> request = TestRequest()
>>> widget = PhoneWidget(field, request)
>>> widget.hasInput()
False
>>> request = TestRequest(form={
...     'field.field.first': '123'})
>>> widget = PhoneWidget(field, request)
>>> widget.hasInput()
False
>>> request = TestRequest(form={
...     'field.field.second': '456'})
>>> widget = PhoneWidget(field, request)
>>> widget.hasInput()
False
>>> request = TestRequest(form={
...     'field.field.third': '7890'})
>>> widget = PhoneWidget(field, request)
>>> widget.hasInput()
False
>>> request = TestRequest(form={
...     'field.field.first': '123',
...     'field.field.second': '456',
...     'field.field.third': '7890'})
>>> widget = PhoneWidget(field, request)
>>> widget.hasInput()
True

hasValidInput() 方法

除了检查任何输入外,此方法还检查输入是否有效

>>> request = TestRequest()
>>> widget = PhoneWidget(field, request)
>>> widget.hasValidInput()
False
>>> request = TestRequest(form={
...     'field.field.first': '123'})
>>> widget = PhoneWidget(field, request)
>>> widget.hasValidInput()
False
>>> request = TestRequest(form={
...     'field.field.second': '456'})
>>> widget = PhoneWidget(field, request)
>>> widget.hasValidInput()
False
>>> request = TestRequest(form={
...     'field.field.third': '7890'})
>>> widget = PhoneWidget(field, request)
>>> widget.hasValidInput()
False
>>> request = TestRequest(form={
...     'field.field.first': '123',
...     'field.field.second': '456',
...     'field.field.third': '7890'})
>>> widget = PhoneWidget(field, request)
>>> widget.hasValidInput()
True

hidden() 方法

此方法将输出渲染为隐藏字段

>>> request = TestRequest(form={
...     'field.field.first': '123',
...     'field.field.second': '456',
...     'field.field.third': '7890'})
>>> widget = PhoneWidget(field, request)
>>> print widget.hidden()
<input class="hiddenType" id="field.field.first" name="field.field.first"
       type="hidden" value="123" />
<input class="hiddenType" id="field.field.second" name="field.field.second"
       type="hidden" value="456"  />
<input class="hiddenType" id="field.field.third" name="field.field.third"
       type="hidden" value="7890"  />

error() 方法

让我们测试一些不良数据并检查错误处理。

第三个字段包含无效值

>>> request = TestRequest(form={
...     'field.field.first': '123',
...     'field.field.second': '456',
...     'field.field.third': '78901'})
>>> widget = PhoneWidget(field, request)
>>> widget.getInputValue()
Traceback (most recent call last):
...
WidgetInputError: ('third', u'Four Digits', ConstraintNotSatisfied(u'78901'))
>>> print widget.error()
<span class="error">Constraint not satisfied</span>

第二个字段包含无效值

>>> request = TestRequest(form={
...     'field.field.first': '123',
...     'field.field.second': '45-',
...     'field.field.third': '7890'})
>>> widget = PhoneWidget(field, request)
>>> widget.getInputValue()
Traceback (most recent call last):
...
WidgetInputError: ('second', u'Three Digits', ConstraintNotSatisfied(u'45-'))
>>> print widget.error()
<span class="error">Constraint not satisfied</span>

第一个字段包含无效值

>>> request = TestRequest(form={
...     'field.field.first': 'xxx',
...     'field.field.second': '456',
...     'field.field.third': '7890'})
>>> widget = PhoneWidget(field, request)
>>> widget.getInputValue()
Traceback (most recent call last):
...
WidgetInputError: ('first', u'Area Code', ConstraintNotSatisfied(u'xxx'))
>>> print widget.error()
<span class="error">Constraint not satisfied</span>

没有发生错误

>>> request = TestRequest(form={
...     'field.field.first': '123',
...     'field.field.second': '456',
...     'field.field.third': '7890'})
>>> widget = PhoneWidget(field, request)
>>> widget.getInputValue()
u'123-456-7890'
>>> widget.error()
''

__call__() 方法

此方法使用子部件渲染小部件。让我们看看输出

>>> request = TestRequest(form={
...     'field.field.first': '123',
...     'field.field.second': '456',
...     'field.field.third': '7890'})
>>> widget = PhoneWidget(field, request)
>>> print widget()
(<input class="textType" id="field.field.first" name="field.field.first"
        size="3" type="text" value="123"  />)&nbsp;
<input class="textType" id="field.field.second" name="field.field.second"
       size="3" type="text" value="456"  />&nbsp;&mdash;&nbsp;
<input class="textType" id="field.field.third" name="field.field.third"
       size="4" type="text" value="7890"  />

项目详情


下载文件

下载适用于您的平台的文件。如果您不确定要选择哪个,请了解更多关于安装包的信息。

源分发

z3c.widget-0.3.0.tar.gz (1.3 MB 查看哈希值)

上传时间

由以下机构支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误记录 StatusPage StatusPage 状态页面