--- a/src/pyams_form/form.py Fri Oct 13 09:02:41 2017 +0200
+++ b/src/pyams_form/form.py Fri Oct 13 09:05:26 2017 +0200
@@ -30,6 +30,7 @@
from pyramid_chameleon.interfaces import IChameleonTranslate
from z3c.form.interfaces import DISPLAY_MODE, IErrorViewSnippet, IMultipleErrors
from zope.publisher.interfaces.browser import IBrowserRequest
+from zope.schema.interfaces import ValidationError
# import packages
from pyams_form.group import GroupsBasedForm
@@ -247,13 +248,13 @@
def get_ajax_handler(self):
return absolute_url(self.context, self.request, self.ajax_handler)
- def get_ajax_errors(self):
+ def get_ajax_errors(self, ajax_errors=None):
"""Extract form errors in AJAX format"""
translate = self.request.localizer.translate
errors = {'status': u'error',
'error_message': translate(self.status)}
registry = self.request.registry
- for error in self.errors:
+ for error in (ajax_errors or self.errors):
if isinstance(error, Exception):
error = registry.getMultiAdapter((error, self.request, None, None, self, self.request),
IErrorViewSnippet)
@@ -352,8 +353,20 @@
errors = errors + form_errors
if errors or self.errors:
return self.get_ajax_errors()
- result = self.createAndAdd(data)
- return self.get_ajax_output(result)
+ try:
+ result = self.createAndAdd(data)
+ except ValidationError as error:
+ # This error can occur with file-type inputs
+ registry = self.request.registry
+ widget = self.widgets[error.args[-1]]
+ view = registry.getMultiAdapter((error, self.request, widget, widget.field, self, self.context),
+ IErrorViewSnippet)
+ view.update()
+ widget.error = view
+ errors = (view,)
+ return self.get_ajax_errors(errors)
+ else:
+ return self.get_ajax_output(result)
def get_ajax_output(self, changes):
output = {}
@@ -448,28 +461,40 @@
if errors or self.errors:
return self.get_ajax_errors()
# update form content
- changes = {}
- for form in self.forms:
- if form.mode == DISPLAY_MODE:
- continue
- changes.update(form.applyChanges(data) or {})
- # check JSON output
- output = self.get_ajax_output(changes)
- translate = self.request.localizer.translate
- status = output.get('status')
- message = output.get('message')
- if not changes:
- if not status:
- output['status'] = 'info'
- if not message:
- output['message'] = translate(self.noChangesMessage)
+ try:
+ changes = {}
+ for form in self.forms:
+ if form.mode == DISPLAY_MODE:
+ continue
+ changes.update(form.applyChanges(data) or {})
+ except ValidationError as error:
+ # This error can occur with file-type inputs
+ registry = self.request.registry
+ widget = self.widgets[error.args[-1]]
+ view = registry.getMultiAdapter((error, self.request, widget, widget.field, self, self.context),
+ IErrorViewSnippet)
+ view.update()
+ widget.error = view
+ errors = (view,)
+ return self.get_ajax_errors(errors)
else:
- if not status:
- output['status'] = status = 'success'
- if not message:
- if status == 'success':
- output['message'] = translate(self.successMessage)
- return output
+ # check JSON output
+ output = self.get_ajax_output(changes)
+ translate = self.request.localizer.translate
+ status = output.get('status')
+ message = output.get('message')
+ if not changes:
+ if not status:
+ output['status'] = 'info'
+ if not message:
+ output['message'] = translate(self.noChangesMessage)
+ else:
+ if not status:
+ output['status'] = status = 'success'
+ if not message:
+ if status == 'success':
+ output['message'] = translate(self.successMessage)
+ return output
def get_ajax_output(self, changes):
output = {}