src/pyams_form/form.py
changeset 68 397c6a042106
parent 57 cb847dfb3e11
child 79 028af0bbc5f4
equal deleted inserted replaced
67:9c2648bc7076 68:397c6a042106
    28 from pyams_template.interfaces import IContentTemplate, ILayoutTemplate
    28 from pyams_template.interfaces import IContentTemplate, ILayoutTemplate
    29 from pyams_utils.interfaces import FORBIDDEN_PERMISSION
    29 from pyams_utils.interfaces import FORBIDDEN_PERMISSION
    30 from pyramid_chameleon.interfaces import IChameleonTranslate
    30 from pyramid_chameleon.interfaces import IChameleonTranslate
    31 from z3c.form.interfaces import DISPLAY_MODE, IErrorViewSnippet, IMultipleErrors
    31 from z3c.form.interfaces import DISPLAY_MODE, IErrorViewSnippet, IMultipleErrors
    32 from zope.publisher.interfaces.browser import IBrowserRequest
    32 from zope.publisher.interfaces.browser import IBrowserRequest
       
    33 from zope.schema.interfaces import ValidationError
    33 
    34 
    34 # import packages
    35 # import packages
    35 from pyams_form.group import GroupsBasedForm
    36 from pyams_form.group import GroupsBasedForm
    36 from pyams_pagelet.interfaces import PageletCreatedEvent
    37 from pyams_pagelet.interfaces import PageletCreatedEvent
    37 from pyams_skin.skin import apply_skin
    38 from pyams_skin.skin import apply_skin
   245         return json.dumps(self.form_options) if self.form_options else None
   246         return json.dumps(self.form_options) if self.form_options else None
   246 
   247 
   247     def get_ajax_handler(self):
   248     def get_ajax_handler(self):
   248         return absolute_url(self.context, self.request, self.ajax_handler)
   249         return absolute_url(self.context, self.request, self.ajax_handler)
   249 
   250 
   250     def get_ajax_errors(self):
   251     def get_ajax_errors(self, ajax_errors=None):
   251         """Extract form errors in AJAX format"""
   252         """Extract form errors in AJAX format"""
   252         translate = self.request.localizer.translate
   253         translate = self.request.localizer.translate
   253         errors = {'status': u'error',
   254         errors = {'status': u'error',
   254                   'error_message': translate(self.status)}
   255                   'error_message': translate(self.status)}
   255         registry = self.request.registry
   256         registry = self.request.registry
   256         for error in self.errors:
   257         for error in (ajax_errors or self.errors):
   257             if isinstance(error, Exception):
   258             if isinstance(error, Exception):
   258                 error = registry.getMultiAdapter((error, self.request, None, None, self, self.request),
   259                 error = registry.getMultiAdapter((error, self.request, None, None, self, self.request),
   259                                                  IErrorViewSnippet)
   260                                                  IErrorViewSnippet)
   260             error.update()
   261             error.update()
   261             if IMultipleErrors.providedBy(error.error):
   262             if IMultipleErrors.providedBy(error.error):
   350             form_data, form_errors = form.extractData()
   351             form_data, form_errors = form.extractData()
   351             data.update(form_data)
   352             data.update(form_data)
   352             errors = errors + form_errors
   353             errors = errors + form_errors
   353         if errors or self.errors:
   354         if errors or self.errors:
   354             return self.get_ajax_errors()
   355             return self.get_ajax_errors()
   355         result = self.createAndAdd(data)
   356         try:
   356         return self.get_ajax_output(result)
   357             result = self.createAndAdd(data)
       
   358         except ValidationError as error:
       
   359             # This error can occur with file-type inputs
       
   360             registry = self.request.registry
       
   361             widget = self.widgets[error.args[-1]]
       
   362             view = registry.getMultiAdapter((error, self.request, widget, widget.field, self, self.context),
       
   363                                             IErrorViewSnippet)
       
   364             view.update()
       
   365             widget.error = view
       
   366             errors = (view,)
       
   367             return self.get_ajax_errors(errors)
       
   368         else:
       
   369             return self.get_ajax_output(result)
   357 
   370 
   358     def get_ajax_output(self, changes):
   371     def get_ajax_output(self, changes):
   359         output = {}
   372         output = {}
   360         for form in self.subforms + self.tabforms:
   373         for form in self.subforms + self.tabforms:
   361             try:
   374             try:
   446             data[form] = form_data
   459             data[form] = form_data
   447             errors = errors + form_errors
   460             errors = errors + form_errors
   448         if errors or self.errors:
   461         if errors or self.errors:
   449             return self.get_ajax_errors()
   462             return self.get_ajax_errors()
   450         # update form content
   463         # update form content
   451         changes = {}
   464         try:
   452         for form in self.forms:
   465             changes = {}
   453             if form.mode == DISPLAY_MODE:
   466             for form in self.forms:
   454                 continue
   467                 if form.mode == DISPLAY_MODE:
   455             changes.update(form.applyChanges(data) or {})
   468                     continue
   456         # check JSON output
   469                 changes.update(form.applyChanges(data) or {})
   457         output = self.get_ajax_output(changes)
   470         except ValidationError as error:
   458         translate = self.request.localizer.translate
   471             # This error can occur with file-type inputs
   459         status = output.get('status')
   472             registry = self.request.registry
   460         message = output.get('message')
   473             widget = self.widgets[error.args[-1]]
   461         if not changes:
   474             view = registry.getMultiAdapter((error, self.request, widget, widget.field, self, self.context),
   462             if not status:
   475                                             IErrorViewSnippet)
   463                 output['status'] = 'info'
   476             view.update()
   464             if not message:
   477             widget.error = view
   465                 output['message'] = translate(self.noChangesMessage)
   478             errors = (view,)
       
   479             return self.get_ajax_errors(errors)
   466         else:
   480         else:
   467             if not status:
   481             # check JSON output
   468                 output['status'] = status = 'success'
   482             output = self.get_ajax_output(changes)
   469             if not message:
   483             translate = self.request.localizer.translate
   470                 if status == 'success':
   484             status = output.get('status')
   471                     output['message'] = translate(self.successMessage)
   485             message = output.get('message')
   472         return output
   486             if not changes:
       
   487                 if not status:
       
   488                     output['status'] = 'info'
       
   489                 if not message:
       
   490                     output['message'] = translate(self.noChangesMessage)
       
   491             else:
       
   492                 if not status:
       
   493                     output['status'] = status = 'success'
       
   494                 if not message:
       
   495                     if status == 'success':
       
   496                         output['message'] = translate(self.successMessage)
       
   497             return output
   473 
   498 
   474     def get_ajax_output(self, changes):
   499     def get_ajax_output(self, changes):
   475         output = {}
   500         output = {}
   476         for form in self.subforms + self.tabforms:
   501         for form in self.subforms + self.tabforms:
   477             if form.mode == DISPLAY_MODE:
   502             if form.mode == DISPLAY_MODE: