def applyValue(self, widget, value=interfaces.NO_VALUE): """Validate and apply value to given widget. This method gets called on any multi widget value change and is responsible for validating the given value and setup an error message. This is internal apply value and validation process is needed because nothing outside this multi widget does know something about our internal sub widgets. """ if value is not interfaces.NO_VALUE: try: # convert widget value to field value converter = interfaces.IDataConverter(widget) fvalue = converter.toFieldValue(value) # validate field value zope.component.getMultiAdapter( (self.context, self.request, self.form, getattr(widget, 'field', None), widget), interfaces.IValidator).validate(fvalue) # convert field value to widget value widget.value = converter.toWidgetValue(fvalue) except (zope.schema.ValidationError, ValueError) as error: # on exception, setup the widget error message view = zope.component.getMultiAdapter( (error, self.request, widget, widget.field, self.form, self.context), interfaces.IErrorViewSnippet) view.update() widget.error = view # set the wrong value as value widget.value = value
def extract(self): """See interfaces.IWidgets""" data = {} self.errors = () for name, widget in self.items(): if widget.mode == interfaces.DISPLAY_MODE: continue raw = widget.extract() value = widget.field.missing_value try: if raw is not interfaces.NOVALUE: value = interfaces.IDataConverter(widget).toFieldValue(raw) zope.component.getMultiAdapter( (self.content, self.request, self.form, getattr(widget, 'field', None), widget), interfaces.IValidator).validate(value) except (zope.schema.ValidationError, ValueError), error: view = zope.component.getMultiAdapter( (error, self.request, widget, widget.field, self.form, self.content), interfaces.IErrorViewSnippet) view.update() widget.error = view self.errors += (view, ) else: name = widget.__name__ data[name] = value
def update(self): """See z3c.form.interfaces.IWidget.""" # Step 1: Determine the value. value = interfaces.NOVALUE lookForDefault = False # Step 1.1: If possible, get a value from the request if not self.ignoreRequest: widget_value = self.extract() if widget_value is not interfaces.NOVALUE: # Once we found the value in the request, it takes precendence # over everything and nothing else has to be done. self.value = widget_value value = PLACEHOLDER # Step 1.2: If we have a widget with a field and we have no value yet, # we have some more possible locations to get the value if (interfaces.IFieldWidget.providedBy(self) and value is interfaces.NOVALUE and value is not PLACEHOLDER): # Step 1.2.1: If the widget knows about its context and the # context is to be used to extract a value, get # it now via a data manager. if (interfaces.IContextAware.providedBy(self) and not self.ignoreContext and self.context is not None): value = zope.component.getMultiAdapter( (self.context, self.field), interfaces.IDataManager).get() # Step 1.2.2: If we still do not have a value, we can always use # the default value of the field, id set # NOTE: It should check field.default is not missing_value, but # that requires fixing zope.schema first if ((value is self.field.missing_value or value is interfaces.NOVALUE) and self.field.default is not None): value = self.field.default lookForDefault = True # Step 1.3: If we still have not found a value, then we try to get it # from an attribute value if value is interfaces.NOVALUE or lookForDefault: adapter = zope.component.queryMultiAdapter( (self.context, self.request, self.form, self.field, self), interfaces.IValue, name='default') if adapter: value = adapter.get() # Step 1.4: Convert the value to one that the widget can understand if value not in (interfaces.NOVALUE, PLACEHOLDER): converter = interfaces.IDataConverter(self) self.value = converter.toWidgetValue(value) # Step 2: Update selected attributes for attrName in self._adapterValueAttributes: value = zope.component.queryMultiAdapter( (self.context, self.request, self.form, self.field, self), interfaces.IValue, name=attrName) if value is not None: setattr(self, attrName, value.get())
def _extract(self, returnRaw=False): data = {} errors = () for name, widget in self.items(): if widget.mode == interfaces.DISPLAY_MODE: continue value = widget.field.missing_value try: widget.setErrors = self.setErrors raw = widget.extract() if raw is not interfaces.NO_VALUE: value = interfaces.IDataConverter(widget).toFieldValue(raw) widget.ignoreRequiredOnValidation = self.ignoreRequiredOnExtract zope.component.getMultiAdapter( (self.content, self.request, self.form, getattr(widget, 'field', None), widget), interfaces.IValidator).validate(value) except (zope.interface.Invalid, ValueError, MultipleErrors) as error: view = zope.component.getMultiAdapter( (error, self.request, widget, widget.field, self.form, self.content), interfaces.IErrorViewSnippet) view.update() if self.setErrors: widget.error = view errors += (view,) else: name = widget.__name__ if returnRaw: data[name] = raw else: data[name] = value for error in self.validate(data): view = zope.component.getMultiAdapter( (error, self.request, None, None, self.form, self.content), interfaces.IErrorViewSnippet) view.update() errors += (view,) if self.setErrors: self.errors = errors return data, errors
def get(self): # value (get) cannot raise an exception, then we return # insane values try: return self.extract() except MultipleErrors: value = {} active_names = self.subform.fields.keys() for name in getFieldNames(self.field.schema): if name in active_names: widget = self.subform.widgets[name] widget_value = widget.value try: converter = interfaces.IDataConverter(widget) value[name] = converter.toFieldValue(widget_value) except (FormatterValidationError, zope.schema.interfaces.ValidationError, ValueError): value[name] = widget_value return value