跳转到主要内容

z3cform的chosen小部件(chosen和ajax版本)

项目描述

https://secure.travis-ci.org/collective/collective.z3cform.chosen.png

致谢

公司

makinacom

作者

贡献者

描述

此软件包包含4个部件,用于z3cform,并使用chosenajaxchosen库。

  • 单个值部件

  • 多值部件

  • 单个值部件

  • 多值部件

仓库:github

选择的部件

collective.chosen.widget提供了一个基于jQuery Autocomplete小部件的自动完成小部件。

>>> from collective.z3cform.chosen import AjaxChosenFieldWidget
>>> from collective.z3cform.chosen import AjaxChosenMultiFieldWidget
>>> from collective.z3cform.chosen import ChosenFieldWidget
>>> from collective.z3cform.chosen import ChosenMultiFieldWidget

首先,我们需要一个用于搜索的词汇表。这是从z3c.formwidget.query中无耻地借用的,我们扩展了它。

>>> from zope.interface import implements
>>> from z3c.formwidget.query.interfaces import IQuerySource
>>> from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm
>>> class ItalianCities(object):
...     implements(IQuerySource)
...
...     vocabulary = SimpleVocabulary((
...         SimpleTerm(u'bologna',  'bologna', u'Bologna'),
...         SimpleTerm(u'palermo',  'palermo', u'Palermo'),
...         SimpleTerm(u'sorrento', 'sorrento', u'Sorrento'),
...         SimpleTerm(u'torino', 'torino', u'Torino')))
...
...     def __init__(self, context):
...         self.context = context
...
...     __contains__ = vocabulary.__contains__
...     __iter__ = vocabulary.__iter__
...     getTerm = vocabulary.getTerm
...     getTermByToken = vocabulary.getTermByToken
...
...     def search(self, query_string):
...         return [v
...                 for v in self
...          if query_string.lower() in v.value.lower()]
>>> from zope.schema.interfaces import IContextSourceBinder
>>> class ItalianCitiesSourceBinder(object):
...     implements(IContextSourceBinder)
...
...     def __call__(self, context):
...         return ItalianCities(context)

然后,我们将设置一个简单的测试表单和上下文。

>>> from zope.interface import alsoProvides
>>> from OFS.SimpleItem import SimpleItem
>>> from Testing.makerequest import makerequest
>>> from zope.annotation.interfaces import IAttributeAnnotatable
>>> from z3c.form.interfaces import IFormLayer
>>> def make_request(path, form={}):
...     app = SimpleItem('')
...     request = makerequest(app).REQUEST
...     request.form.update(form)
...     alsoProvides(request, IFormLayer)
...     alsoProvides(request, IAttributeAnnotatable)
...     request._script = path.split('/')
...     request._steps = []
...     request._resetURLS()
...     return request
>>> from zope.interface import Interface
>>> from zope import schema
>>> from z3c.form import form, field, button
>>> from plone.z3cform.layout import wrap_form
>>> class ICities(Interface):
...     afavourite_city = schema.Choice(title=u"Favourite city",
...                                    source=ItalianCitiesSourceBinder(), required=False)
...     avisited_cities = schema.List(title=u"Visited cities",
...                                  value_type=schema.Choice(title=u"Selection",
...                                                           source=ItalianCitiesSourceBinder()))
...     favourite_city = schema.Choice(title=u"Favourite city",
...                                    source=ItalianCitiesSourceBinder())
...     visited_cities = schema.List(title=u"Visited cities",
...                                  value_type=schema.Choice(title=u"Selection",
...                                                           source=ItalianCitiesSourceBinder()))
>>> from z3c.form.interfaces import IFieldsForm
>>> from zope.interface import implements
>>> class CitiesForm(form.Form):
...     implements(ICities)
...     fields = field.Fields(ICities)
...     fields['afavourite_city'].widgetFactory = AjaxChosenFieldWidget
...     fields['avisited_cities'].widgetFactory = AjaxChosenMultiFieldWidget
...     fields['favourite_city'].widgetFactory = ChosenFieldWidget
...     fields['visited_cities'].widgetFactory = ChosenMultiFieldWidget
...
...     @button.buttonAndHandler(u'Apply')
...     def handleApply(self, action):
...         data, errors = self.extractData()
...         print "Submitted data:", data
>>> form_view = wrap_form(CitiesForm)
>>> from zope.component import provideAdapter
>>> from zope.publisher.interfaces.browser import IBrowserRequest
>>> from zope.interface import Interface
>>> provideAdapter(adapts=(ICities, IBrowserRequest),
...                provides=Interface,
...                factory=form_view,
...                name=u"cities-form")
>>> from OFS.SimpleItem import SimpleItem
>>> class Bar(SimpleItem):
...     implements(ICities)
...
...     def __init__(self, id):
...         self.id = id
...         self.favourite_city = None
...         self.visited_cities = []
...         self.afavourite_city = None
...         self.avisited_cities = []
...     def absolute_url(self):
...         return 'http://foo/bar'

现在,让我们查找表单并尝试渲染小部件。

>>> from zope.component import getMultiAdapter
>>> context = Bar('bar')

模拟遍历

>>> request = make_request('bar/@@cities-form')
>>> from Testing.makerequest import makerequest
>>> context = makerequest(context)
>>> form_view = getMultiAdapter((context, request), name=u"cities-form")
>>> form_view.__name__ = 'cities-form'

模拟部分渲染

>>> form = form_view.form_instance
>>> form.__name__ = 'cities-form'
>>> form.update()
>>> print form.widgets['favourite_city'].render().replace("...", "") # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE +REPORT_UDIFF
<BLANKLINE>
<script type="text/javascript">    (function($) {
        $().ready(function() {
            $('#form-widgets-favourite_city-select').data('klass','chosen-selection-widget required choice-field').data('title','None');
            $('#form-widgets-favourite_city-select').chosen({
                allow_single_deselect: false,
                no_results_text: 'No results found',
                width: '280px'
            });
<BLANKLINE>
            $('#formfield-form-widgets-favourite_city').find('.chzn-container, .chzn-results, .chzn-drop').css({'min-width': '180px'});
        });
    })(jQuery);
    </script>
<div id="form-widgets-favourite_city-chosen" class="chosen-selection-widget required choice-field">
  <select data-placeholder="Select a value" id="form-widgets-favourite_city-select" name="form.widgets.favourite_city:list" onselect="" style="" >
<BLANKLINE>
      <option id="form-widgets-favourite_city-novalue" value="(nothing)" selected="selected">Select a value</option>
<BLANKLINE>
<BLANKLINE>
<BLANKLINE>
      <option id="form-widgets-favourite_city-0" value="bologna">Bologna</option>
<BLANKLINE>
<BLANKLINE>
      <option id="form-widgets-favourite_city-1" value="palermo">Palermo</option>
<BLANKLINE>
<BLANKLINE>
      <option id="form-widgets-favourite_city-2" value="sorrento">Sorrento</option>
<BLANKLINE>
<BLANKLINE>
      <option id="form-widgets-favourite_city-3" value="torino">Torino</option>
<BLANKLINE>
  </select>
  <input name="form.widgets.favourite_city-empty-marker" type="hidden" value="1" />
</div>
<BLANKLINE>

我们可以看到渲染的JavaScript期望调用如下ajax小部件的视图

>>> widget = form.widgets['afavourite_city']
>>> context.REQUEST._script = 'bar/@@cities-form/++widget++form.widgets.avisited_cities/@@chosen-autocomplete-search'.split('/')
>>> context.REQUEST._resetURLS()
>>> context.REQUEST.form['term'] = 'or'
>>> search_view = getMultiAdapter((widget, context.REQUEST), name=u'chosen-autocomplete-search')

结果是包含标记的json元组列表

>>> print search_view()
[["sorrento","Sorrento"],["torino","Torino"]]

最初我们没有在请求中设置任何内容,我们缺少字段

>>> form.update()
>>> data, errors = form.extractData()
>>> len(errors)
3
>>> form.request.form.update({
...  "form.buttons.apply" : "Apply",
...  "form.widgets.visited_cities" : ["palermo", "bologna"],
...  "form.widgets.avisited_cities" : ["palermo", "bologna"],
...  "form.widgets.afavourite_city" :"bologna",
...  "form.widgets.favourite_city" : "palermo",
... })
>>> form.update() # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
Submitted data:...
>>> data, errors = form.extractData()
>>> items = data.items()
>>> items.sort(key=lambda x:x[0])
>>> pprint(items)
[('afavourite_city', u'bologna'),
 ('avisited_cities', [u'palermo', u'bologna']),
 ('favourite_city', u'palermo'),
 ('visited_cities', [u'palermo', u'bologna'])]

我们的值被标记为已选择

>>> results = form.render().replace('...', '')
>>> False not in [
... (it in results)
... for it in ['id="form-widgets-visited_cities-0" value="bologna" selected="selected">Bologna',
...            'id="form-widgets-visited_cities-1" value="palermo" selected="selected">Palermo']]
True

我们的部件也处理显示模式

>>> form.widgets['favourite_city'].mode = 'display'
>>> print form.widgets['favourite_city'].render().strip()
 <span id="form-widgets-favourite_city" class="chosen-selection-widget required choice-field" style=""><span class="selected-option">Palermo</span></span>
>>> form.widgets['visited_cities'].mode = 'display'
>>> print form.widgets['visited_cities'].render().strip()
<span id="form-widgets-visited_cities" class="chosen-multiselection-widget required list-field" style=""><span class="selected-option">Palermo</span>, <span class="selected-option">Bologna</span></span>

我们的部件也处理隐藏模式

>>> form.widgets['favourite_city'].mode = 'hidden'
>>> print form.widgets['favourite_city'].render().strip()
<input id="form-widgets-favourite_city-1" name="form.widgets.favourite_city:list" value="palermo" class="hidden-widget" type="hidden" />
<BLANKLINE>
<BLANKLINE>
<BLANKLINE>
<BLANKLINE>
<BLANKLINE>
<BLANKLINE>
<BLANKLINE>
<input name="form.widgets.favourite_city-empty-marker" type="hidden" value="1" />
>>> form.widgets['visited_cities'].mode = 'hidden'
>>> print form.widgets['visited_cities'].render().strip()
<input id="form-widgets-visited_cities-0" name="form.widgets.visited_cities:list" value="bologna" class="hidden-widget" type="hidden" />
<BLANKLINE>
<BLANKLINE>
  <input id="form-widgets-visited_cities-1" name="form.widgets.visited_cities:list" value="palermo" class="hidden-widget" type="hidden" />
<BLANKLINE>
<BLANKLINE>
<BLANKLINE>
<BLANKLINE>
<BLANKLINE>
<BLANKLINE>
<BLANKLINE>
<input name="form.widgets.visited_cities-empty-marker" type="hidden" value="1" />

collective.z3cform.chosen 安装

要安装collective.z3cform.chosen,请遵循此文档

变更日志

1.2.2 (2021-04-20)

  • 不要翻译无值标记,以避免在翻译时出错。[mpeeters]

  • 添加了需要的ajax参数,对应于collective.js.chosen。[cedricmessiant, sgeulette]

1.2.1 (2014-09-25)

  • 当字段最初隐藏时(例如在覆盖层中),部件可以正常工作。[thomasdesvenain]

  • Pyflakes,pep8,删除未使用代码等。[thomasdesvenain]

1.2 (2014-06-03)

  • 设置宽度,并将其作为chosen参数应用,而不是使用特定宽度样式小部件;这样做可以确保chosen在初始化离屏或应用到的元素不可见时设置一个有效的宽度。[damilgra]

  • 更新了法语翻译。[cedricmessiant]

1.1 (2013-06-04)

  • buildout,测试和travis。[kiorky]

  • 更改提示消息并更新法语翻译。修复列表字段中无值的问题。[cedricmessiant]

1.0 (2012-06-06)

  • 初始发布。[kiorky]

项目详情


下载文件

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

源分发

collective.z3cform.chosen-1.2.2.tar.gz (35.7 kB 查看哈希值)

上传时间:

支持者