def extract(self): value = self.request.form.get(self.identifier, NO_VALUE) if value is not NO_VALUE: try: value = int(value) except ValueError: return (None, u"Invalid internal input") collectedValues = [] collectedErrors = Errors(identifier=self.identifier) for position in range(0, value): value_present = '%s.present.%d' % ( self.identifier, position) in self.request.form if not value_present: # This value have been removed continue field = self.valueField.clone(new_identifier=str(position)) form = cloneFormData(self.form, prefix=self.identifier) data, errors = form.extractData(Fields(field)) if errors: collectedErrors.extend(errors) else: collectedValues.append(data[field.identifier]) if collectedErrors: return (None, collectedErrors) value = self.component.collectionType(collectedValues) return (value, None)
def validateData(self, fields, data): errors = Errors() for factory in self.dataValidators: validator = factory(self, fields) for error in validator.validate(data): if not IError.providedBy(error): error = Error(error, self.prefix) errors.append(error) return errors
def __init__(self, context, request, content=_marker): super(FormData, self).__init__(context, request) self.context = context self.request = request self.errors = Errors() self.__extracted = {} self.__content = None if content is _marker: content = context self.setContentData(content)
class FormData(Object): """This represent a submission of a form. It can be used to update widgets and run actions. """ grok.baseclass() prefix = 'form' parent = None mode = INPUT dataManager = ObjectDataManager dataValidators = [] widgetFactoryFactory = WidgetFactory methods = frozenset(('POST', 'GET')) ignoreRequest = False ignoreContent = True status = u'' def __init__(self, context, request, content=_marker): super(FormData, self).__init__(context, request) self.context = context self.request = request self.errors = Errors() self.__extracted = {} self.__content = None if content is _marker: content = context self.setContentData(content) @Lazy def widgetFactory(self): return self.widgetFactoryFactory(self, self.request) @property def formErrors(self): error = self.errors.get(self.prefix, None) if error is None: return [] if ICollection.providedBy(error): return error return [error] def htmlId(self): return self.prefix.replace('.', '-') def getContent(self): # Shortcut for actions. You should not reimplement that method # but getContentData. return self.getContentData().getContent() def getContentData(self): return self.__content def setContentData(self, content): if not interfaces.IDataManager.providedBy(content): content = self.dataManager(content) self.__content = content def validateData(self, fields, data): errors = Errors() for factory in self.dataValidators: validator = factory(self, fields) for error in validator.validate(data): if not IError.providedBy(error): error = Error(error, self.prefix) errors.append(error) return errors def extractData(self, fields): # XXX to review this cached = self.__extracted.get(fields) if cached is not None: return cached data = FieldsValues(self, fields) self.errors = errors = Errors() self.__extracted[fields] = (data, errors) for field in fields: if not field.available(self): continue # Widget extraction and validation extractor = self.widgetFactory.extractor(field) if extractor is not None: value, error = extractor.extract() if error is None: error = field.validate(value, self) if error is not None: if not IError.providedBy(error): error = Error(error, extractor.identifier) errors.append(error) data[field.identifier] = value # Generic form validation errors.extend(self.validateData(fields, data)) if len(errors): # Add a form level error if not already present if self.prefix not in errors: errors.append(Error(_(u"There were errors."), self.prefix)) self.errors = errors return (data, errors)