Back to index

plone3  3.1.7
uberselectionwidget.py
Go to the documentation of this file.
00001 from zope.schema.interfaces import ValidationError
00002 from zope.component import getMultiAdapter
00003 
00004 from zope.app.form.interfaces import WidgetInputError
00005 from zope.app.form.browser.interfaces import \
00006     ISourceQueryView, ITerms, IWidgetInputErrorView
00007 from zope.app.form.browser.widget import SimpleInputWidget
00008 from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
00009 
00010 from plone.app.vocabularies.interfaces import IBrowsableTerm
00011 
00012 
00013 class UberSelectionWidget(SimpleInputWidget):
00014     _error = None
00015 
00016     template = ViewPageTemplateFile('uberselectionwidget.pt')
00017 
00018     def __init__(self, field, request):
00019         SimpleInputWidget.__init__(self, field, request)
00020         self.source = field.source
00021         self.terms = getMultiAdapter((self.source, self.request), ITerms)
00022         self.queryview = getMultiAdapter((self.source, self.request), ISourceQueryView)
00023 
00024     def _value(self):
00025         if self._renderedValueSet():
00026             value = self._data
00027         else:
00028             token = self.request.form.get(self.name)
00029 
00030             if token is not None and token != '':
00031                 if not isinstance(token, basestring):
00032                     token = token[-1]
00033                 try:
00034                     value = self.terms.getValue(str(token))
00035                 except LookupError:
00036                     value = self.context.missing_value
00037             else:
00038                 value = self.context.missing_value
00039 
00040         return value
00041 
00042     def _getRenderValue(self):
00043         value = self._value()
00044         if value is not None:
00045             value = self.terms.getTerm(value)
00046         return value
00047 
00048     def hidden(self):
00049         value = self._value()
00050         if value == self.context.missing_value:
00051             return '' # Nothing to hide ;)
00052 
00053         try:
00054             term = self.terms.getTerm(value)
00055         except LookupError:
00056             # A value was set, but it's not valid.  Treat
00057             # it as if it was missing and return nothing.
00058             return ''
00059 
00060         return '<input type="hidden" name="%s" value="%s" />' % (self.name, term.token)
00061 
00062     def error(self):
00063         if self._error:
00064             return getMultiAdapter((self._error, self.request),
00065                                    IWidgetInputErrorView).snippet()
00066         return ""
00067 
00068     def __call__(self):
00069         value = self._getRenderValue()
00070         field = self.context
00071         results = []
00072         results_truncated = False
00073         qresults = self.queryview.results(self.name)
00074         if qresults is not None:
00075             for index, item in enumerate(qresults):
00076                 if index >= 20:
00077                     results_truncated = True
00078                     break
00079                 results.append(self.terms.getTerm(item))
00080         return self.template(field=field,
00081                              results=results,
00082                              results_truncated=results_truncated,
00083                              name=self.name,
00084                              value=value)
00085 
00086     def getInputValue(self):
00087         value = self._value()
00088 
00089         field = self.context
00090 
00091         # Remaining code copied from SimpleInputWidget
00092 
00093         # value must be valid per the field constraints
00094         try:
00095             field.validate(value)
00096         except ValidationError, err:
00097             self._error = WidgetInputError(field.__name__, self.label, err)
00098             raise self._error
00099 
00100         return value
00101 
00102     def hasInput(self):
00103         if self.name in self.request or self.name+'.displayed' in self.request:
00104             return True
00105 
00106         token = self.request.form.get(self.name)
00107         if token is not None:
00108             return True
00109 
00110         return False
00111 
00112 class UberMultiSelectionWidget(UberSelectionWidget):
00113     template = ViewPageTemplateFile('ubermultiselectionwidget.pt')
00114 
00115     def __init__(self, field, request):
00116         SimpleInputWidget.__init__(self, field, request)
00117         self.source = field.value_type.source
00118         self.terms = getMultiAdapter((self.source, self.request), ITerms)
00119         self.queryview = getMultiAdapter((self.source, self.request), ISourceQueryView)
00120 
00121     def _value(self):
00122         if self._renderedValueSet():
00123             value = self._data
00124         else:
00125             tokens = self.request.form.get(self.name)
00126 
00127             if tokens is not None:
00128                 value = []
00129                 for token in tokens:
00130                     try:
00131                         v = self.terms.getValue(str(token))
00132                     except LookupError:
00133                         pass # skip invalid values
00134                     else:
00135                         value.append(v)
00136                 # only keep unique items
00137                 r = []
00138                 seen = {}
00139                 for s in value:
00140                     if s not in seen:
00141                         r.append(s)
00142                         seen[s] = 1
00143                 value = r
00144             else:
00145                 if self.name+'.displayed' in self.request:
00146                     value = []
00147                 else:
00148                     value = self.context.missing_value
00149 
00150         return value
00151 
00152     def _getRenderValue(self):
00153         value = self._value()
00154         if value is not None:
00155             value = [self.terms.getTerm(x) for x in value]
00156         return value