add search on authors, complete with autocomplete and label boxes
This commit is contained in:
parent
21dbad9943
commit
219a0b88e0
|
@ -0,0 +1,6 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:tal="http://xml.zope.org/namespaces/tal"
|
||||
tal:omit-tag="">
|
||||
<input type="hidden" tal:attributes="id view/id; name view/name;"/>
|
||||
<input class="author-autocomplete" type="text" tal:attributes="name string:${view/name}-query"/>
|
||||
</html>
|
|
@ -5,6 +5,7 @@
|
|||
xmlns:i18n="http://namespaces.zope.org/i18n"
|
||||
xmlns:genericsetup="http://namespaces.zope.org/genericsetup"
|
||||
xmlns:browser="http://namespaces.zope.org/browser"
|
||||
xmlns:z3c="http://namespaces.zope.org/z3c"
|
||||
i18n_domain="tabellio.searchform">
|
||||
|
||||
<!-- Include z3c.form as dependency -->
|
||||
|
@ -19,6 +20,12 @@
|
|||
template="docsearch.pt"
|
||||
permission="zope2.View"/>
|
||||
|
||||
<browser:page
|
||||
for=".form.IFolderWithDocuments"
|
||||
name="listAuthors"
|
||||
class=".form.ListAuthorsView"
|
||||
permission="zope2.View"/>
|
||||
|
||||
<browser:page
|
||||
for=".form.IFolderWithPfbDocuments"
|
||||
name="folder_listing"
|
||||
|
@ -39,4 +46,11 @@
|
|||
template="guided-search.pt"
|
||||
permission="zope2.View"/>
|
||||
|
||||
<z3c:widgetTemplate
|
||||
mode="input"
|
||||
widget=".form.IAuthorsWidget"
|
||||
layer="z3c.form.interfaces.IFormLayer"
|
||||
template="authors_input.pt"
|
||||
/>
|
||||
|
||||
</configure>
|
||||
|
|
|
@ -159,6 +159,38 @@
|
|||
|
||||
<div tal:replace="structure provider:plone.belowcontentbody" />
|
||||
|
||||
<script type="text/javascript">
|
||||
function update_authors_input(input) {
|
||||
var s = '';
|
||||
jq(input).nextAll('span.labelbox').each(function() {
|
||||
s = s + ' ' + jq(this).attr('class').split(' ')[1];
|
||||
});
|
||||
jq(input).attr('value', s);
|
||||
}
|
||||
|
||||
function author_autocomplete_ready(event, data, formatted) {
|
||||
(function($) {
|
||||
var input_box = $(event.target);
|
||||
// XXX: don't insert item if it's already present
|
||||
labelbox = $('<span class="labelbox ' + data[1] + '">' + data[0] + '<' + '/span>');
|
||||
$(input_box).before(labelbox);
|
||||
$(labelbox).click(function() {
|
||||
$(this).remove();
|
||||
update_authors_input(jq(input_box).prevAll('input')[0]);
|
||||
});
|
||||
update_authors_input(jq(input_box).prevAll('input')[0]);
|
||||
$(input_box).attr('value', '');
|
||||
}(jQuery));
|
||||
}
|
||||
|
||||
(function($) {
|
||||
$().ready(function() {
|
||||
$('.author-autocomplete').autocomplete('./listAuthors', {
|
||||
}).result(author_autocomplete_ready);
|
||||
});
|
||||
})(jQuery);
|
||||
</script>
|
||||
|
||||
</tal:main-macro>
|
||||
</metal:main>
|
||||
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from five import grok
|
||||
from zope import interface, schema
|
||||
from zope import interface, schema, component
|
||||
from z3c.form import form, field, button
|
||||
from plone.z3cform.layout import wrap_form
|
||||
from Products.CMFCore.utils import getToolByName
|
||||
from zope.interface import implements
|
||||
|
||||
from z3c.form.ptcompat import ViewPageTemplateFile
|
||||
import z3c.form.interfaces
|
||||
from z3c.form.browser import text
|
||||
from z3c.form import widget
|
||||
from z3c.form.interfaces import ITextWidget
|
||||
|
||||
from z3c.relationfield.schema import RelationChoice, RelationList
|
||||
from plone.formwidget.contenttree import ObjPathSourceBinder
|
||||
|
@ -17,9 +23,56 @@ from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
|
|||
from zope.schema.interfaces import IContextSourceBinder
|
||||
from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm
|
||||
|
||||
from plone.registry.interfaces import IRegistry
|
||||
|
||||
from tabellio.config.interfaces import ITabellioSettings
|
||||
import tabellio.config.utils
|
||||
|
||||
|
||||
class ListAuthorsView(BrowserView):
|
||||
def get_folder_at_path(self, path):
|
||||
current = self.portal
|
||||
for part in path.split('/'):
|
||||
if not part:
|
||||
continue
|
||||
current = getattr(current, part)
|
||||
return current
|
||||
|
||||
_deputies_folder = None
|
||||
def deputies_folder(self):
|
||||
if self._deputies_folder:
|
||||
return self._deputies_folder
|
||||
path = self.settings.deputiesPath
|
||||
self._deputies_folder = self.get_folder_at_path(path)
|
||||
return self._deputies_folder
|
||||
deputies_folder = property(deputies_folder)
|
||||
|
||||
def __call__(self):
|
||||
self.portal = getToolByName(self.context, 'portal_url').getPortalObject()
|
||||
self.settings = component.getUtility(IRegistry).forInterface(ITabellioSettings, False)
|
||||
|
||||
self.request.response.setHeader('Content-type', 'text/plain')
|
||||
s = []
|
||||
q = self.request.form.get('q').lower()
|
||||
for object in self.deputies_folder.objectValues():
|
||||
if object.portal_type != 'themis.datatypes.deputy':
|
||||
continue
|
||||
if q in object.id or q in object.Title().lower():
|
||||
s.append(object)
|
||||
return '\n'.join(['%s|%s' % (x.Title(), x.id) for x in s])
|
||||
|
||||
class IAuthorsWidget(ITextWidget):
|
||||
pass
|
||||
|
||||
class AuthorsWidget(text.TextWidget):
|
||||
implements(IAuthorsWidget)
|
||||
klass = u'authors'
|
||||
|
||||
|
||||
def FieldAuthorsWidget(field, request):
|
||||
return widget.FieldWidget(field, AuthorsWidget(request))
|
||||
|
||||
|
||||
class IFolderWithDocuments(interface.Interface):
|
||||
pass
|
||||
|
||||
|
@ -80,10 +133,8 @@ class IDocumentSearch(interface.Interface):
|
|||
#subjects =
|
||||
ttitle = schema.TextLine(title=_(u'Title'), required=False)
|
||||
text = schema.TextLine(title=_(u'Text'), required=False)
|
||||
authors = RelationList(title=_(u'Authors'), default=[], required=False,
|
||||
value_type=RelationChoice(title=_(u'Author'),
|
||||
source=ObjPathSourceBinder(
|
||||
portal_type=['themis.datatypes.deputy'])))
|
||||
authors = schema.TextLine(title=_(u'Authors'), required=False)
|
||||
|
||||
# polgroups
|
||||
session = schema.Choice(title=_(u'Legislature / Session'), required=False,
|
||||
source=possible_sessions)
|
||||
|
@ -93,7 +144,9 @@ class IDocumentSearch(interface.Interface):
|
|||
|
||||
class DocumentSearchForm(form.Form):
|
||||
method = 'get'
|
||||
prefix = 'document'
|
||||
fields = field.Fields(IDocumentSearch)
|
||||
fields['authors'].widgetFactory = FieldAuthorsWidget
|
||||
ignoreContext = True
|
||||
template = ViewPageTemplateFile('form_templates/view_effectivesearch.pt')
|
||||
|
||||
|
@ -119,10 +172,7 @@ class IDossierSearch(interface.Interface):
|
|||
source=possible_dossier_types)
|
||||
#subjects =
|
||||
ttitle = schema.TextLine(title=_(u'Title'), required=False)
|
||||
authors = RelationList(title=_(u'Authors'), default=[], required=False,
|
||||
value_type=RelationChoice(title=_(u'Author'),
|
||||
source=ObjPathSourceBinder(
|
||||
portal_type=['themis.datatypes.deputy'])))
|
||||
authors = schema.TextLine(title=_(u'Authors'), required=False)
|
||||
# polgroups
|
||||
session = schema.Choice(title=_(u'Legislature / Session'), required=False,
|
||||
source=possible_sessions)
|
||||
|
@ -131,8 +181,10 @@ class IDossierSearch(interface.Interface):
|
|||
|
||||
|
||||
class DossierSearchForm(form.Form):
|
||||
prefix = 'dossier'
|
||||
method = 'get'
|
||||
fields = field.Fields(IDossierSearch)
|
||||
fields['authors'].widgetFactory = FieldAuthorsWidget
|
||||
ignoreContext = True
|
||||
template = ViewPageTemplateFile('form_templates/view_dossier_search.pt')
|
||||
|
||||
|
@ -157,10 +209,7 @@ class IQuestionSearch(interface.Interface):
|
|||
source=possible_question_types)
|
||||
#subjects =
|
||||
ttitle = schema.TextLine(title=_(u'Title'), required=False)
|
||||
authors = RelationList(title=_(u'Authors'), default=[], required=False,
|
||||
value_type=RelationChoice(title=_(u'Author'),
|
||||
source=ObjPathSourceBinder(
|
||||
portal_type=['themis.datatypes.deputy'])))
|
||||
authors = schema.TextLine(title=_(u'Authors'), required=False)
|
||||
# polgroups
|
||||
session = schema.Choice(title=_(u'Legislature / Session'), required=False,
|
||||
source=possible_sessions)
|
||||
|
@ -169,7 +218,9 @@ class IQuestionSearch(interface.Interface):
|
|||
|
||||
|
||||
class QuestionSearchForm(form.Form):
|
||||
prefix = 'question'
|
||||
fields = field.Fields(IQuestionSearch)
|
||||
fields['authors'].widgetFactory = FieldAuthorsWidget
|
||||
ignoreContext = True
|
||||
template = ViewPageTemplateFile('form_templates/view_question_search.pt')
|
||||
|
||||
|
@ -196,10 +247,7 @@ class IDocumentPfbSearch(interface.Interface):
|
|||
#subjects =
|
||||
ttitle = schema.TextLine(title=_(u'Title'), required=False)
|
||||
text = schema.TextLine(title=_(u'Text'), required=False)
|
||||
authors = RelationList(title=_(u'Authors'), default=[], required=False,
|
||||
value_type=RelationChoice(title=_(u'Author'),
|
||||
source=ObjPathSourceBinder(
|
||||
portal_type=['themis.datatypes.deputy'])))
|
||||
authors = schema.TextLine(title=_(u'Authors'), required=False)
|
||||
# polgroups
|
||||
session = schema.Choice(title=_(u'Legislature / Session'), required=False,
|
||||
source=possible_sessions)
|
||||
|
@ -213,6 +261,7 @@ class IDocumentPfbSearch(interface.Interface):
|
|||
class DocumentPfbSearchForm(form.Form):
|
||||
method = 'get'
|
||||
fields = field.Fields(IDocumentPfbSearch)
|
||||
fields['authors'].widgetFactory = FieldAuthorsWidget
|
||||
ignoreContext = True
|
||||
template = ViewPageTemplateFile('form_templates/view_pfbdocsearch.pt')
|
||||
|
||||
|
@ -250,10 +299,7 @@ class IGlobalSearchForm(interface.Interface):
|
|||
#subjects =
|
||||
ttitle = schema.TextLine(title=_(u'Title'), required=False)
|
||||
text = schema.TextLine(title=_(u'Text'), required=False)
|
||||
authors = RelationList(title=_(u'Authors'), default=[], required=False,
|
||||
value_type=RelationChoice(title=_(u'Author'),
|
||||
source=ObjPathSourceBinder(
|
||||
portal_type=['themis.datatypes.deputy'])))
|
||||
authors = schema.TextLine(title=_(u'Authors'), required=False)
|
||||
# polgroups
|
||||
session = schema.Choice(title=_(u'Legislature / Session'), required=False,
|
||||
source=possible_sessions)
|
||||
|
@ -267,8 +313,17 @@ class GlobalSearchForm(form.Form):
|
|||
|
||||
class SearchView(BrowserView):
|
||||
def search_results(self, search_type):
|
||||
|
||||
if self.request.form.get('document.widgets.search_type_is_document'):
|
||||
GlobalSearchForm.prefix = 'document'
|
||||
elif self.request.form.get('dossier.widgets.search_type_is_dossier'):
|
||||
GlobalSearchForm.prefix = 'dossier'
|
||||
elif self.request.form.get('question.widgets.search_type_is_question'):
|
||||
GlobalSearchForm.prefix = 'question'
|
||||
|
||||
f = GlobalSearchForm(self.context, self.request)
|
||||
f.update()
|
||||
|
||||
data, errors = f.extractData()
|
||||
|
||||
kw = {}
|
||||
|
@ -276,16 +331,8 @@ class SearchView(BrowserView):
|
|||
print 'data:', data
|
||||
|
||||
if not data.get('search_type_is_%s' % search_type):
|
||||
print 'not the right pane'
|
||||
return None
|
||||
|
||||
if data.get('search_type_is_document'):
|
||||
kw['portal_type'] = 'tabellio.documents.document'
|
||||
elif data.get('search_type_is_dossier'):
|
||||
kw['portal_type'] = 'tabellio.documents.dossier'
|
||||
elif data.get('search_type_is_question'):
|
||||
kw['portal_type'] = 'tabellio.documents.question'
|
||||
|
||||
if data.get('ttitle'):
|
||||
kw['Title'] = data.get('ttitle')
|
||||
|
||||
|
@ -313,6 +360,10 @@ class SearchView(BrowserView):
|
|||
if data.get('session'):
|
||||
kw['session'] = tabellio.config.utils.get_list_of_sessions(data.get('session'))
|
||||
|
||||
if data.get('authors'):
|
||||
kw['authorsDoc'] = {'query': data.get('authors').strip().split(),
|
||||
'operator': 'and'}
|
||||
|
||||
if data.get('polgroups'):
|
||||
pass # XXX : kw['polgroupsDoc'] = {'query': ['ps', 'ecolo'], 'operator': 'and'}
|
||||
|
||||
|
@ -326,6 +377,13 @@ class SearchView(BrowserView):
|
|||
if not kw:
|
||||
return []
|
||||
|
||||
if data.get('search_type_is_document'):
|
||||
kw['portal_type'] = 'tabellio.documents.document'
|
||||
elif data.get('search_type_is_dossier'):
|
||||
kw['portal_type'] = 'tabellio.documents.dossier'
|
||||
elif data.get('search_type_is_question'):
|
||||
kw['portal_type'] = 'tabellio.documents.question'
|
||||
|
||||
if not kw.get('sort_on') and data.get('search_type_is_document'):
|
||||
kw['sort_on'] = 'dateDoc'
|
||||
kw['sort_order'] = 'descending'
|
||||
|
|
Reference in New Issue