Module plone.formwidget.autocomplete.widget, line 63, in __call__ AttributeError: 'SimpleVocabulary' object has no attribute 'search'

We have a DX content-type in Plone 5 with a Autocomplete multi field widget with named vocabulary (instance of SimpleVocabulary):

    directives.widget('dn_entries', AutocompleteMultiFieldWidget)
    dn_entries = schema.List(
        title=_(u'Person entries'),
        required=True,
        value_type=schema.Choice(
            title=u'Persons',
            vocabulary='unimr.staff.persons',
            required=True),
    )

Traceback (innermost last):
  Module ZPublisher.Publish, line 138, in publish
  Module ZPublisher.mapply, line 77, in mapply
  Module ZPublisher.Publish, line 48, in call_object
  Module plone.formwidget.autocomplete.widget, line 63, in __call__
AttributeError: 'SimpleVocabulary' object has no attribute 'search'

According to the documentation the code should be fine.

-aj

Some weeks ago I faced the same issue, and found in a github issue (sorry I did not save the URL, and I couldn't find it again), that the documentation there is wrong and the recommended way is to use the AjaxSelectWidget.

I rewrote our code like this:

    from plone.app.z3cform.widget import AjaxSelectFieldWidget
    ...        
        cycle = Tuple(
            title=_(u'The name of the cycle this event is part of'),
            description=_(u'Enter a text, and an autocomplete attempt will be made'),
            required=False,
            value_type=TextLine(),
            missing_value=(),
        )
        directives.widget(
            'cycle',
            AjaxSelectFieldWidget,
            vocabulary='auditorio.types.vocabularies.cycles'
2 Likes

Would be good to have it files here:

Sorry, I have just realised that the github issue I found was related to the use of ObjPathSourceBinder with a catalog search, which anyway was documented wrongly for Plone 5: https://github.com/collective/collective.behavior.banner/issues/5#issuecomment-160574812
and https://github.com/plone/plone.app.dexterity/issues/200#issuecomment-160549415

Anyway, the AutocompleteWidget issue can be solved using the AjaxSelectFieldWidget as above.

Even the AjaxSelectFieldWidget is not working, at least not as announced.

    idm_link = schema.Tuple(
        title=_(u'Person IDM Link'),
        vocabulary='unimr.staff.persons.idmlink',
        value_type=schema.TextLine(),
        missing_value=(),
#        required=True
    )
    directives.widget('idm_link', AjaxSelectFieldWidget, vocabulary='unimr.staff.persons.idmlink')

gives another error

name
    return get_provider(package_or_requirement).get_resource_filename(
  File "/home/ajung/sandboxes/unimr.staff/eggs/setuptools-21.0.0-py2.7.egg/pkg_resources/__init__.py", line 419, in get_provider
    __import__(moduleOrReq)
  File "/home/ajung/sandboxes/unimr.staff/src/unimr/staff/__init__.py", line 4, in <module>
    import staffinfo  # flake8: noqa
  File "/home/ajung/sandboxes/unimr.staff/src/unimr/staff/staffinfo.py", line 19, in <module>
    class IStaffInfo(Interface):
  File "/home/ajung/sandboxes/unimr.staff/src/unimr/staff/staffinfo.py", line 32, in IStaffInfo
    missing_value=(),
  File "/home/ajung/sandboxes/unimr.staff/eggs/zope.schema-4.4.2-py2.7.egg/zope/schema/_field.py", line 509, in __init__
    super(AbstractCollection, self).__init__(**kw)
  File "/home/ajung/sandboxes/unimr.staff/eggs/zope.schema-4.4.2-py2.7.egg/zope/schema/_bootstrapfields.py", line 307, in __init__
    super(MinMaxLen, self).__init__(**kw)
zope.configuration.xmlconfig.ZopeXMLConfigurationError: File "/home/ajung/sandboxes/unimr.staff/parts/instance/etc/site.zcml", line 12.2-12.39
    ZopeXMLConfigurationError: File "/home/ajung/sandboxes/unimr.staff/eggs/Products.CMFPlone-5.1a2-py2.7.egg/Products/CMFPlone/meta.zcml", line 47.4-51.10
    TypeError: __init__() got an unexpected keyword argument 'vocabulary'

However the same code is used here in Dexterity

http://pydoc.net/Python/plone.app.dexterity/2.1.19/plone.app.dexterity.behaviors.metadata/

Am I missing something?

-aj

In order to complement the widget mess under Plone 5: I tried gocept.autocomplete, a z3c.form widget...which also fails badly

Traceback (innermost last):
  Module ZPublisher.Publish, line 138, in publish
  Module ZPublisher.mapply, line 77, in mapply
  Module ZPublisher.Publish, line 48, in call_object
  Module plone.z3cform.layout, line 63, in __call__
  Module plone.z3cform.layout, line 47, in update
  Module plone.dexterity.browser.add, line 130, in update
  Module plone.z3cform.fieldsets.extensible, line 65, in update
  Module plone.z3cform.patch, line 30, in GroupForm_update
  Module z3c.form.group, line 132, in update
  Module z3c.form.form, line 136, in updateWidgets
  Module z3c.form.field, line 254, in update
  Module plone.autoform.widgets, line 65, in __call__
TypeError: AutocompleteFieldWidget() takes exactly 3 arguments (2 given)

Is there actually no auto complete widget working on Plone 5? It can not be possible that everything broken? Quality control? Sorry but I am pi**ed again by the lack of quality assurance.

-aj

Try removing the "vocabulary" parameter from the Tuple definition.

according to GitHub - plone/plone.formwidget.autocomplete: z3c.form widget for Plone using jQuery Autocomplete "When using this widget, the vocabulary/source has to provide the IQuerySource interface from z3c.formwidget.query and have a search() method."... not that I've been able to figure out how to do that. I have a vocabulary that implements IVocabularyFactory. Might be as simple as adding a search method... but @erral's AjaxSelectFieldWidget worked for me. OK I spoke a bit too soon... trying to figure out some issues saving values.

Ok, I think I've found that there are at least two other threads that seem to be attempting to achieve the same goal as I was, to use the autocomplete widget to use work with dynamic vocabularies. Similar to Andreas, I became rather distraught over the various failures using the any of the autocomplete widgets listed in the documentation.

Using the directives every time (AutocompleteFieldWidget, AutocompleteMultiFieldWidget) things would just blow up like the examples above. Very, very annoying, but hey free software, right?

Being OCD I ripped things apart to just try to understand what was happening or not. Basically (as Kim says) your source must implement the IQuerySource interface from z3c.formwidget.query somehow and that too will lead you on a wild goose chase. The documentation is very skimpy, incorrect, or non-existent about what and how to implement this widget properly.

Autocomplete widget based on jQuery Autocomplete. Requires a Choice field with a query source.

Reading the documentation on vocabularies again, led me to look at the list of common ones.

Since my content type is DX I was immediately excited that plone.principalsource which is oh so casually mentioned there says that it: provides several vocabularies that are useful for selecting users and groups in a Dexterity context...

However, the Plone Vocab Doc's method of adding this package to your addon I believe is either incorrect or out of date. After doing a few hours of google-fu I found an addon in the collective that seemed to have implemented widgets within a DX content type. I then sorta did a reverse search from there to get to the collective repo and find it there where I could examine things more carefully. After a look at the code, I did the following:

  • edited my setup.py and added plone.principalsource to install_requires=
  • added a line in my package's configure.zcml include package="plone.principalsource"
  • added directives.widget ( empid=AjaxSelectFieldWidget ) to my schema.Choice field
  • added from plone.app.z3cform.widget import AjaxSelectFieldWidget
  • re-ran buildout to install.

It worked!

After I made principlesource a named utility, was I finally able to get the field widget working as advertised.

However, the supposed autocomplete version did not work. I could only get the Ajax versions to load correctly.

Now, just because it works doesn't mean its right. What do you guys think? Is this correct or at least a starting point?

3 Likes