This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
themis.fields/themis/fields/widgets.py

270 lines
9.4 KiB
Python

from Acquisition import ImplicitAcquisitionWrapper
from zope.interface import implements, implementsOnly, implementer
from zope.component import adapts, adapter
from Products.CMFCore.utils import getToolByName
from z3c.form.interfaces import IFormLayer, IFieldWidget
from z3c.form.widget import FieldWidget
from collective.z3cform.datetimewidget import DateWidget
from themis.fields.interfaces import ICommission, ICommissions
from zope.schema.interfaces import IDate, IContextSourceBinder, ISource
from themis.fields.interfaces import IDateOnly
from themis.fields.interfaces import IRadioChoice
from themis.fields.interfaces import ISubjects
from themis.fields.interfaces import ILegisSession
from themis.fields.interfaces import IContact, IContacts
from themis.fields.interfaces import IDeputy, IDeputies
from themis.fields.interfaces import IMinistry, IMinistries
from themis.fields.interfaces import IDeputyOrMinistry, IDeputiesOrMinistries
from themis.fields.interfaces import IOrderedSelectAndAddWidget
from themis.fields.interfaces import IRelatedDoc
from themis.fields.interfaces import IRelatedDocs
from themis.fields.interfaces import IMailId, IMailIdWidget
from themis.fields.interfaces import IMailRefId, IMailRefIdWidget
from plone.formwidget.autocomplete.interfaces import IAutocompleteWidget
from plone.formwidget.autocomplete.widget import AutocompleteSelectionWidget
from plone.formwidget.autocomplete import AutocompleteFieldWidget
from z3c.form.browser.orderedselect import OrderedSelectWidget
from z3c.form.browser.checkbox import CheckBoxWidget
from z3c.form.browser.select import SelectWidget
from z3c.form.browser.text import TextWidget
from z3c.form.browser.radio import RadioWidget
from plone.formwidget.contenttree.widget import ContentTreeWidget, MultiContentTreeWidget
@adapter(ICommission, IFormLayer)
@implementer(IFieldWidget)
def CommissionFieldWidget(field, request):
"""IFieldWidget factory for CommissionWidget."""
return FieldWidget(field, SelectWidget(request))
@adapter(ISubjects, IFormLayer)
@implementer(IFieldWidget)
def SubjectsFieldWidget(field, request):
"""IFieldWidget factory for SelectWidget."""
return FieldWidget(field, CheckBoxWidget(request))
@adapter(ICommissions, IFormLayer)
@implementer(IFieldWidget)
def CommissionsFieldWidget(field, request):
"""IFieldWidget factory for SelectWidget."""
return FieldWidget(field, CheckBoxWidget(request))
@adapter(IDeputy, IFormLayer)
@implementer(IFieldWidget)
def DeputyFieldWidget(field, request):
"""IFieldWidget factory for DeputyWidget."""
return FieldWidget(field, SelectWidget(request))
#return FieldWidget(field, AutocompleteSelectionWidget(request))
@adapter(IMinistry, IFormLayer)
@implementer(IFieldWidget)
def MinistryFieldWidget(field, request):
"""IFieldWidget factory for MinistryWidget."""
return FieldWidget(field, SelectWidget(request))
@adapter(IDeputyOrMinistry, IFormLayer)
@implementer(IFieldWidget)
def DeputyOrMinistryFieldWidget(field, request):
"""IFieldWidget factory for DeputyOrMinistryWidget."""
return FieldWidget(field, SelectWidget(request))
@adapter(IContact, IFormLayer)
@implementer(IFieldWidget)
def ContactFieldWidget(field, request):
"""IFieldWidget factory for ContactWidget."""
return FieldWidget(field, AutocompleteSelectionWidget(request))
@adapter(IDeputies, IFormLayer)
@implementer(IFieldWidget)
def DeputiesFieldWidget(field, request):
"""IFieldWidget factory for DeputiesWidget."""
return FieldWidget(field, OrderedSelectWidget(request))
@adapter(IMinistries, IFormLayer)
@implementer(IFieldWidget)
def MinistriesFieldWidget(field, request):
"""IFieldWidget factory for MinistriesWidget."""
return FieldWidget(field, OrderedSelectWidget(request))
@adapter(IDeputiesOrMinistries, IFormLayer)
@implementer(IFieldWidget)
def DeputiesOrMinistriesFieldWidget(field, request):
"""IFieldWidget factory for DeputiesOrMinistriesWidget."""
return FieldWidget(field, OrderedSelectWidget(request))
@adapter(IContacts, IFormLayer)
@implementer(IFieldWidget)
def ContactsFieldWidget(field, request):
"""IFieldWidget factory for ContactsWidget."""
return FieldWidget(field, OrderedSelectAndAddWidget(request))
@adapter(ILegisSession, IFormLayer)
@implementer(IFieldWidget)
def LegisSessionFieldWidget(field, request):
"""IFieldWidget factory for LegisSessionWidget."""
return FieldWidget(field, SelectWidget(request))
@adapter(IDateOnly, IFormLayer)
@implementer(IFieldWidget)
def DateOnlyFieldWidget(field, request):
'''IFieldWidget factory for DateOnlyWidget.'''
return FieldWidget(field, DateWidget(request))
@adapter(IDate, IFormLayer)
@implementer(IFieldWidget)
def DateFieldWidget(field, request):
'''IFieldWidget factory for DateOnlyWidget.'''
return FieldWidget(field, DateWidget(request))
@adapter(IRadioChoice, IFormLayer)
@implementer(IFieldWidget)
def RadioChoiceFieldWidget(field, request):
'''IFieldWidget factory for RadioChoiceWidget'''
return FieldWidget(field, RadioWidget(request))
class OrderedSelectAndAddWidget(OrderedSelectWidget):
implementsOnly(IOrderedSelectAndAddWidget)
formatItem = '''function(row, idx, count, value) { console.log(row, idx,
count, value); return row[1]; }'''
formatResult = '''function(row, idx, count) { console.log("t2", row, idx,
count); return ""; }'''
js_template = """\
(function($) {
$().ready(function() {
$('#%(id)s-iadd').autocomplete('%(url)s', {
autoFill: false,
minChars: 2,
max: 10,
mustMatch: true,
matchContains: true,
formatItem: %(formatItem)s,
formatResult: %(formatResult)s
}).result(%(js_callback)s);
});
})(jQuery);
"""
def autocomplete_url(self):
"""Generate the URL that returns autocomplete results for this form
"""
form_url = self.request.getURL()
return "%s/++widget++%s/@@autocomplete-search" % (
form_url, self.name )
def js(self):
# Use a template if it exists, in case anything overrode this interface
js_callback = 'formwidgetadd_autocomplete_ready'
return self.js_template % dict(id=self.id, url=self.autocomplete_url(),
formatItem=self.formatItem, formatResult=self.formatResult,
klass=self.klass, title=self.title,
js_callback=js_callback)
@property
def source(self):
"""We need to bind the field to the context so that vocabularies
appear as sources"""
return self.field.bind(self.context).value_type.source
_bound_source = None
@property
def bound_source(self):
if self._bound_source is None:
source = self.source
if IContextSourceBinder.providedBy(source):
source = source(self.context)
assert ISource.providedBy(source)
self._bound_source = source
return self._bound_source
def deselect(self):
selecteditems = []
notselecteditems = []
for selecteditem in self.selectedItems:
selecteditems.append(selecteditem['content'])
for item in self.items:
if not item['content'] in selecteditems:
if item['value'].startswith('contact:'):
# skip simple contacts, to avoid the list growing too large
# ideally we would have something like "favourite" contacts
# populated automatically on usage frequence...
continue
notselecteditems.append(item)
return notselecteditems
@adapter(IRelatedDoc, IFormLayer)
@implementer(IFieldWidget)
def RelatedDocFieldWidget(field, request):
'''IFieldWidget factory for RadioChoiceWidget'''
return FieldWidget(field, ContentTreeWidget(request))
@adapter(IRelatedDocs, IFormLayer)
@implementer(IFieldWidget)
def RelatedDocsFieldWidget(field, request):
'''IFieldWidget factory for RelatedDocsWidget'''
return FieldWidget(field, MultiContentTreeWidget(request))
class MailIdWidget(TextWidget):
implements(IMailIdWidget)
def get_matching_object(self):
catalog = getToolByName(self.context, 'portal_catalog')
results = catalog(themis_mail_ref=self.value)
objects = [x.getObject() for x in results]
if len(objects) == 0:
return None
if len(objects) > 1:
pass # should we display a warning?
return objects[0]
def href(self):
object = self.get_matching_object()
if object:
return object.absolute_url()
return None
@adapter(IMailId, IFormLayer)
@implementer(IFieldWidget)
def MailIdFieldWidget(field, request):
"""IFieldWidget factory for MailId"""
return FieldWidget(field, MailIdWidget(request))
class MailRefIdWidget(TextWidget):
implements(IMailRefIdWidget)
def href(self):
catalog = getToolByName(self.context, 'portal_catalog')
results = catalog(themis_mail_number=self.value)
objects = [x.getObject() for x in results]
if len(objects) == 0:
return ''
if len(objects) > 1:
pass # should we display a warning?
return objects[0].absolute_url()
@adapter(IMailRefId, IFormLayer)
@implementer(IFieldWidget)
def MailRefIdFieldWidget(field, request):
"""IFieldWidget factory for MailRefId"""
return FieldWidget(field, MailRefIdWidget(request))