main view: use autocomplete on a text field, not the whole widget machinery

This commit is contained in:
Frédéric Péters 2013-04-13 13:40:37 +02:00
parent ef1a9676ce
commit 6d55eb0bb4
4 changed files with 82 additions and 17 deletions

View File

@ -37,6 +37,12 @@
permission="zope2.View" permission="zope2.View"
/> />
<browser:page
for="collective.dms.thesaurus.dmsthesaurus.IDmsThesaurus"
name="listKeywords"
class=".thesaurusview.ListKeywordsView"
permission="zope2.View"/>
<browser:page <browser:page
for="collective.dms.thesaurus.dmsthesaurus.IDmsThesaurus" for="collective.dms.thesaurus.dmsthesaurus.IDmsThesaurus"
name="autocomplete-search-form" name="autocomplete-search-form"

View File

@ -12,9 +12,8 @@
<h1 class="documentFirstHeading" tal:content="context/Title" /> <h1 class="documentFirstHeading" tal:content="context/Title" />
<div tal:replace="structure provider:plone.belowcontenttitle" /> <div tal:replace="structure provider:plone.belowcontenttitle" />
<form id="thesaurus-search-form" <form id="thesaurus-search-form" tal:content="structure view/renderForm">
tal:content="structure view/renderForm" </form>
onsubmit="window.location=window.location+'/'+document.forms['thesaurus-search-form']['form-widgets-keyword_search'].value; return false" />
<div id="dmsthesaurus-entry-points-field" <div id="dmsthesaurus-entry-points-field"
class="field" class="field"
@ -24,6 +23,17 @@
<div tal:content="structure widget/render" /> <div tal:content="structure widget/render" />
</div> </div>
<script type="text/javascript">
function autocomplete_ready(event, data, formatted) {
window.location=window.location+'/'+data[1];
}
$(document).ready(function() {
$('.keyword-search').autocomplete('listKeywords', {
'cacheLength': 0, 'matchContains': true, 'scroll': true, 'max': 30}).result(autocomplete_ready);
});
</script>
</metal:main> </metal:main>
</body> </body>

View File

@ -1,8 +1,6 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" <div xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"
xmlns:tal="http://xml.zope.org/namespaces/tal" xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal"> xmlns:metal="http://xml.zope.org/namespaces/metal">
<body>
<metal:use use-macro="context/@@ploneform-macros/fields" /> <metal:use use-macro="context/@@ploneform-macros/fields" />
<metal:use use-macro="context/@@ploneform-macros/actions" /> <metal:use use-macro="context/@@ploneform-macros/actions" />
</body> </div>
</html>

View File

@ -8,10 +8,11 @@ from zope.schema.interfaces import IChoice
from zope.browserpage.viewpagetemplatefile import ViewPageTemplateFile from zope.browserpage.viewpagetemplatefile import ViewPageTemplateFile
from z3c.form.interfaces import IFormLayer, IFieldWidget from z3c.form.interfaces import IFormLayer, IFieldWidget, ITextWidget
from z3c.form.widget import FieldWidget from z3c.form.widget import FieldWidget
from z3c.form import form, button, field from z3c.form import form, button, field
from plone.z3cform import layout from plone.z3cform import layout
from z3c.form.browser import text
#from plone.formwidget.autocomplete.widget import AutocompleteFieldWidget #from plone.formwidget.autocomplete.widget import AutocompleteFieldWidget
@ -25,6 +26,11 @@ from plone.dexterity.browser.view import DefaultView
#from plone.dexterity.interfaces import IDexterityFTI #from plone.dexterity.interfaces import IDexterityFTI
#from plone.dexterity.utils import getAdditionalSchemata #from plone.dexterity.utils import getAdditionalSchemata
from Products.Five import BrowserView
from Products.CMFCore.utils import getToolByName
from zope.schema.vocabulary import SimpleVocabulary
from collective.dms.thesaurus import _ from collective.dms.thesaurus import _
from collective.dms.thesaurus.vocabulary import InternalThesaurusSource from collective.dms.thesaurus.vocabulary import InternalThesaurusSource
@ -48,26 +54,31 @@ def AutocompleteSearchFieldWidget(field, request):
return FieldWidget(field, AutocompleteSearchWidget(request)) return FieldWidget(field, AutocompleteSearchWidget(request))
class IKeywordSearchWidget(ITextWidget):
pass
class KeywordSearchWidget(text.TextWidget):
implements(IKeywordSearchWidget)
klass = u'keyword-search'
def KeywordSearchFieldWidget(field, request):
return FieldWidget(field, KeywordSearchWidget(request))
class IThesaurusForm(Interface): class IThesaurusForm(Interface):
keyword_search = schema.Choice( keyword_search = schema.TextLine(
title=_(u"Quick Search"), title=_(u"Quick Search"),
description=_(u"Search for a keyword in this Thesaurus"), description=_(u"Search for a keyword in this Thesaurus"),
source=InternalThesaurusSource(), required=False) required=False)
class DmsThesaurusForm(form.Form): class DmsThesaurusForm(form.Form):
implements(IThesaurusForm) implements(IThesaurusForm)
fields = field.Fields(IThesaurusForm) fields = field.Fields(IThesaurusForm)
fields['keyword_search'].widgetFactory = AutocompleteSearchFieldWidget fields['keyword_search'].widgetFactory = KeywordSearchFieldWidget
ignoreContext = True ignoreContext = True
template = ViewPageTemplateFile('thesaurus_form.pt') template = ViewPageTemplateFile('thesaurus_form.pt')
@button.buttonAndHandler(u'Ok')
def handle_ok(self, action):
data, errors = self.extractData()
print data, errors
#from .searchform import SearchForm #from .searchform import SearchForm
class DmsThesaurusView(DefaultView): class DmsThesaurusView(DefaultView):
@ -77,4 +88,44 @@ class DmsThesaurusView(DefaultView):
#form = SearchForm(self.context, self.request) #form = SearchForm(self.context, self.request)
form.update() form.update()
return form.render() return form.render()
class ListKeywordsView(BrowserView):
_vocabulary = None
def get_vocabulary(self):
context = self
if self._vocabulary is not None:
return self._vocabulary
catalog = getToolByName(context, 'portal_catalog')
# XXX
# path = '/'.join(context.getPhysicalPath())
# print 'path:', path
results = catalog(portal_type='dmskeyword',
) # path={'query': path,'depth': 1})
keywords = [x.getObject() for x in results]
def cmp_keyword(x, y):
return cmp(x.title, y.title)
keywords.sort(cmp_keyword)
#keyword_ids = [x.id for x in keywords]
_c = SimpleVocabulary.createTerm
keyword_terms = [ _c(x.id, x.id, x.title) for x in keywords ]
self._vocabulary = SimpleVocabulary(keyword_terms)
return self._vocabulary
def __call__(self):
from plone.i18n.normalizer.fr import normalizer
self.request.response.setHeader('Content-type', 'text/plain')
query_terms = [normalizer.normalize(x).lower() for x in unicode(self.request.form.get('q'), 'utf-8').split()]
r = []
for value in self.get_vocabulary().by_token.values():
for term in query_terms:
if not term in value.title.lower():
break
else:
r.append('%s|%s' % (value.title, value.value))
if len(r) > 30:
break
return '\n'.join(r)