From 18aa78648204e2f08a94e2905a6ae0df1bbd4b19 Mon Sep 17 00:00:00 2001 From: Bob Leers Date: Sat, 21 Nov 2020 15:52:21 +0100 Subject: [PATCH] [IMP] formio: Translatable (multilingual) public Forms and Form Builder. - Translatable (multilingual) public Forms, with language-switcher buttons. - Translatable (multilingual) Form Builder, with language-switcher buttons. Closes #47, #58 --- formio/__manifest__.py | 2 +- formio/controllers/main.py | 65 +++------- formio/controllers/public.py | 112 +++++------------- formio/models/formio_builder.py | 72 +++++++++-- formio/models/formio_form.py | 38 +++--- formio/static/description/index.html | 13 +- .../static/src/css/formio_builder_embed.css | 11 ++ formio/static/src/js/builder/app.js | 49 +++++--- formio/static/src/js/form/backend_app.js | 6 +- formio/static/src/js/form/formio_form.js | 4 +- .../static/src/js/form/public_create_app.js | 6 +- formio/static/src/js/formio_form_container.js | 4 +- formio/views/formio_builder_templates.xml | 7 ++ formio/views/formio_menu.xml | 13 +- formio_data_api/models/formio_form.py | 5 +- 15 files changed, 215 insertions(+), 192 deletions(-) diff --git a/formio/__manifest__.py b/formio/__manifest__.py index a2151db3..cf78d303 100644 --- a/formio/__manifest__.py +++ b/formio/__manifest__.py @@ -4,7 +4,7 @@ { 'name': 'Form.io', 'summary': 'Build, deploy and store web forms with the "Form.io" Form Builder', - 'version': '7.6', + 'version': '7.7', 'license': 'LGPL-3', 'author': 'Nova Code', 'website': 'https://www.novacode.nl', diff --git a/formio/controllers/main.py b/formio/controllers/main.py index 7bac8da7..5bb83462 100644 --- a/formio/controllers/main.py +++ b/formio/controllers/main.py @@ -27,6 +27,7 @@ def builder_root(self, builder_id, **kwargs): # TODO Render template with message? return request.redirect("/") + # TODO REMOVE (still needed or obsolete legacy?) # Needed to update language context = request.env.context.copy() context.update({'lang': request.env.user.lang}) @@ -34,6 +35,7 @@ def builder_root(self, builder_id, **kwargs): builder = request.env['formio.builder'].browse(builder_id) values = { + 'languages': builder.languages, 'builder': builder, 'formio_css_assets': builder.formio_css_assets, 'formio_js_assets': builder.formio_js_assets, @@ -50,8 +52,8 @@ def builder_config(self, builder_id, **kwargs): if builder: if builder.schema: res['schema'] = json.loads(builder.schema) - res['options'] = builder.get_js_options() - res['mode'] = builder.get_js_mode() + res['options'] = builder._get_js_options() + res['params'] = builder._get_js_params() return res @@ -77,39 +79,18 @@ def form_root(self, uuid, **kwargs): msg = 'Form UUID %s' % uuid return request.not_found(msg) + # TODO REMOVE (still needed or obsolete legacy?) # Needed to update language context = request.env.context.copy() context.update({'lang': request.env.user.lang}) request.env.context = context - # Get active languages used in Builder translations. - query = """ - SELECT - DISTINCT(fbt.lang_id) AS lang_id - FROM - formio_builder_translation AS fbt - INNER JOIN res_lang AS l ON l.id = fbt.lang_id - WHERE - fbt.builder_id = {builder_id} - AND l.active = True - """.format(builder_id=form.builder_id.id) - - request.env.cr.execute(query) - builder_lang_ids = [r[0] for r in request.env.cr.fetchall()] - - # Always include english (en_US). - domain = ['|', ('id', 'in', builder_lang_ids), ('code', 'in', [request.env.user.lang, 'en_US'])] - languages = request.env['res.lang'].with_context(active_test=False).search(domain, order='name asc') - languages = languages.filtered(lambda r: r.id in builder_lang_ids or r.code == 'en_US') - values = { - 'languages': [], # initialize, otherwise template/view crashes. + 'languages': form.builder_id.languages, 'form': form, 'formio_css_assets': form.builder_id.formio_css_assets, 'formio_js_assets': form.builder_id.formio_js_assets, } - if len(languages) > 1: - values['languages'] = languages return request.render('formio.formio_form_embed', values) @http.route('/formio/form//config', type='json', auth='user', website=True) @@ -119,8 +100,8 @@ def form_config(self, form_uuid, **kwargs): if form and form.builder_id.schema: res['schema'] = json.loads(form.builder_id.schema) - res['options'] = self._prepare_form_options(form) - res['config'] = self._prepare_form_config(form) + res['options'] = self._get_form_js_options(form) + res['params'] = self._get_form_js_params(form) return res @@ -282,29 +263,19 @@ def form_res_data(self, uuid, **kwargs): except Exception as e: _logger.error("Exception: %s" % e) - def _prepare_form_options(self, form): - options = {} - context = request.env.context - Lang = request.env['res.lang'] - - if form.state in [FORM_STATE_COMPLETE, FORM_STATE_CANCEL]: - options['readOnly'] = True - - if form.builder_id.view_as_html: - options['renderMode'] = 'html' - options['viewAsHtml'] = True # backwards compatible (version < 4.x)? + def _get_form_js_options(self, form): + options = form._get_js_options() - lang = Lang._lang_get(request.env.user.lang) - if lang: - options['language'] = lang.iso_code[:2] - options['i18n'] = form.i18n_translations() + # default language + if request.env.user.lang in form.languages.mapped('iso_code'): + language = request.env.user.lang + else: + language = request._context['lang'] + options['language'] = language.replace('_', '-') return options - def _prepare_form_config(self, form): - config = { - 'portal_submit_done_url': form.portal_submit_done_url - } - return config + def _get_form_js_params(self, form): + return form._get_js_params() def _get_form(self, uuid, mode): return request.env['formio.form'].get_form(uuid, mode) diff --git a/formio/controllers/public.py b/formio/controllers/public.py index 66ddebb1..34b04826 100644 --- a/formio/controllers/public.py +++ b/formio/controllers/public.py @@ -27,52 +27,22 @@ def public_form_root(self, uuid, **kwargs): msg = 'Form UUID %s' % uuid return request.not_found(msg) - ## TODO languages ## - ## Determine lang.iso from request.__dict__ - - # Needed to update language - # context = request.env.context.copy() - # context.update({'lang': request.env.user.lang}) - # request.env.context = context - - # # Get active languages used in Builder translations. - # query = """ - # SELECT - # DISTINCT(fbt.lang_id) AS lang_id - # FROM - # formio_builder_translation AS fbt - # INNER JOIN res_lang AS l ON l.id = fbt.lang_id - # WHERE - # fbt.builder_id = {builder_id} - # AND l.active = True - # """.format(builder_id=form.builder_id.id) - - # request.env.cr.execute(query) - # builder_lang_ids = [r[0] for r in request.env.cr.fetchall()] - - # # Always include english (en_US). - # domain = ['|', ('id', 'in', builder_lang_ids), ('code', 'in', [request.env.user.lang, 'en_US'])] - # languages = request.env['res.lang'].with_context(active_test=False).search(domain, order='name asc') - # languages = languages.filtered(lambda r: r.id in builder_lang_ids or r.code == 'en_US') - values = { - 'languages': [], # initialize, otherwise template/view crashes. + 'languages': form.builder_id.languages, 'form': form, 'formio_css_assets': form.builder_id.formio_css_assets, 'formio_js_assets': form.builder_id.formio_js_assets, } - # if len(languages) > 1: - # values['languages'] = languages return request.render('formio.formio_form_public_embed', values) @http.route('/formio/public/form//config', type='json', auth='public', website=True) def form_config(self, form_uuid, **kwargs): form = self._get_public_form(form_uuid, self._check_public_form()) - res = {'schema': {}, 'options': {}, 'config': {}} + res = {'schema': {}, 'options': {}, 'params': {}} if form and form.builder_id.schema: res['schema'] = json.loads(form.builder_id.schema) - res['options'] = self._prepare_form_options(form) + res['options'] = self._get_public_form_js_options(form) return res @@ -133,45 +103,14 @@ def public_form_create_root(self, builder_uuid, **kwargs): # msg = 'Form Builder UUID %s not current/published' % builder_uuid # return request.not_found(msg) - ## TODO languages ## - ## Determine lang.iso from request.__dict__ - - # Needed to update language - # context = request.env.context.copy() - # context.update({'lang': request.env.user.lang}) - # request.env.context = context - - # # Get active languages used in Builder translations. - # query = """ - # SELECT - # DISTINCT(fbt.lang_id) AS lang_id - # FROM - # formio_builder_translation AS fbt - # INNER JOIN res_lang AS l ON l.id = fbt.lang_id - # WHERE - # fbt.builder_uuid = {builder_uuid} - # AND l.active = True - # """.format(builder_uuid=form.builder_uuid.id) - - # request.env.cr.execute(query) - # builder_lang_ids = [r[0] for r in request.env.cr.fetchall()] - - # # Always include english (en_US). - # domain = ['|', ('id', 'in', builder_lang_ids), ('code', 'in', [request.env.user.lang, 'en_US'])] - # languages = request.env['res.lang'].with_context(active_test=False).search(domain, order='name asc') - # languages = languages.filtered(lambda r: r.id in builder_lang_ids or r.code == 'en_US') - values = { - 'languages': [], # initialize, otherwise template/view crashes. + 'languages': formio_builder.languages, 'builder': formio_builder, 'public_form_create': True, 'formio_builder_uuid': formio_builder.uuid, 'formio_css_assets': formio_builder.formio_css_assets, 'formio_js_assets': formio_builder.formio_js_assets, } - # if len(languages) > 1: - # values['languages'] = languages - return request.render('formio.formio_form_public_create_embed', values) @@ -185,9 +124,8 @@ def public_form_create_config(self, builder_uuid, **kwargs): if formio_builder.schema: res['schema'] = json.loads(formio_builder.schema) - #res['options'] = self._prepare_form_options(form) - res['options'] = {'public_create': True, 'embedded': True} - res['config'] = self._prepare_form_config(formio_builder) + res['options'] = self._get_public_create_form_js_options(formio_builder) + res['params'] = self._get_public_form_js_params(formio_builder) return res @@ -223,29 +161,33 @@ def public_form_create_submit(self, builder_uuid, **post): res = form_model.sudo().create(vals) return {'form_uuid': res.uuid} - def _prepare_form_options(self, form): - options = {} - context = request.env.context - Lang = request.env['res.lang'] - - if form.state in [FORM_STATE_COMPLETE, FORM_STATE_CANCEL]: - options['readOnly'] = True + def _get_public_form_js_options(self, form): + options = form._get_js_options() - if form.builder_id.view_as_html: - options['renderMode'] = 'html' - options['viewAsHtml'] = True # backwards compatible (version < 4.x)? - - lang = Lang._lang_get(request.env.user.lang) + lang = request.env['res.lang']._lang_get(request.env.user.lang) if lang: - options['language'] = lang.iso_code[:2] + options['language'] = lang.iso_code options['i18n'] = form.i18n_translations() return options - def _prepare_form_config(self, builder): - config = { - 'public_submit_done_url': builder.public_submit_done_url + def _get_public_create_form_js_options(self, builder): + options = { + 'public_create': True, + 'embedded': True, + 'i18n': builder.i18n_translations() } - return config + + lang = request.env['res.lang']._lang_get(request.env.user.lang) + if lang: + options['language'] = lang.iso_code + else: + context = request.env.context + options['language'] = context['lang'] if context.get('lang') else self.env.ref('base.lang_en') + + return options + + def _get_public_form_js_params(self, builder): + return builder._get_public_form_js_params() def _get_public_form(self, form_uuid, public_share=False): return request.env['formio.form'].get_public_form(form_uuid, public_share) diff --git a/formio/models/formio_builder.py b/formio/models/formio_builder.py index d2780929..806f91c5 100644 --- a/formio/models/formio_builder.py +++ b/formio/models/formio_builder.py @@ -81,9 +81,23 @@ class Builder(models.Model): user_id = fields.Many2one('res.users', string='Assigned user', track_visibility='onchange') forms = fields.One2many('formio.form', 'builder_id', string='Forms') portal = fields.Boolean("Portal", track_visibility='onchange', help="Form is accessible by assigned portal user") - portal_submit_done_url = fields.Char(string='Portal Submit-done URL', track_visibility='onchange') + portal_submit_done_url = fields.Char( + string='Portal Submit-done URL', track_visibility='onchange', + help="""\ + IMPORTANT: + - Absolute URL should contain a protocol (https://, http://) + - Relative URL is also supported e.g. /web/login + """ + ) public = fields.Boolean("Public", track_visibility='onchange', help="Form is public accessible (e.g. used in Shop checkout, Events registration") - public_submit_done_url = fields.Char(string='Public Submit-done URL', track_visibility='onchange') + public_submit_done_url = fields.Char( + string='Public Submit-done URL', track_visibility='onchange', + help="""\ + IMPORTANT: + - Absolute URL should contain a protocol (https://, http://) + - Relative URL is also supported e.g. /web/login + """ + ) public_access_interval_number = fields.Integer(default=30, track_visibility='onchange', help="Public access to submitted Form shall be rejected after expiration of the configured time interval.") public_access_interval_type = fields.Selection(list(_interval_selection.items()), default='minutes', track_visibility='onchange') view_as_html = fields.Boolean("View as HTML", track_visibility='onchange', help="View submission as a HTML view instead of disabled webform.") @@ -95,6 +109,7 @@ class Builder(models.Model): "Show User Metadata", track_visibility='onchange', help="Show submission and assigned user metadata in the Form header.", default=True) wizard = fields.Boolean("Wizard", track_visibility='onchange') translations = fields.One2many('formio.builder.translation', 'builder_id', string='Translations') + languages = fields.One2many('res.lang', compute='_compute_languages', string='Languages') allow_force_update_state_group_ids = fields.Many2many( 'res.groups', string='Allow groups to force update State', help="User groups allowed to manually force an update of the Form state." @@ -228,6 +243,13 @@ def _compute_display_fields(self): r.display_name_full = _("{title} (state: {state} - version: {version})").format( title=r.title, state=r.display_state, version=r.version) + @api.depends('translations') + def _compute_languages(self): + for r in self: + languages = r.translations.mapped('lang_id') + languages |= self.env.ref('base.lang_en') + r.languages = languages.sorted('name') + def _compute_edit_url(self): # sudo() is needed for regular users. for r in self: @@ -316,18 +338,36 @@ def action_new_builder_version(self): "context": {} } - def get_js_options(self): + def _get_js_options(self): + """ formio JS (API) options """ try: options = json.loads(self.formio_js_options) except: options = ast.literal_eval(self.formio_js_options) + + # default language + if self.env.user.lang in self.languages.mapped('iso_code'): + language = self.env.user.lang + else: + language = self._context['lang'] + options['language'] = language.replace('_', '-') + + options['i18n'] = self.i18n_translations() return options - def get_js_mode(self): - mode = {} + def _get_js_params(self): + """ Odoo JS (Owl component) misc. params """ + params = {} if self.state in [STATE_CURRENT, STATE_OBSOLETE]: - mode['readOnly'] = True - return mode + params['readOnly'] = True + return params + + def _get_public_form_js_params(self): + """ Form: Odoo JS (Owl component) misc. params """ + params = { + 'public_submit_done_url': self.public_submit_done_url + } + return params @api.model def get_public_builder(self, uuid): @@ -342,3 +382,21 @@ def get_public_builder(self, uuid): return builder else: return False + + def i18n_translations(self): + i18n = {} + # Formio GUI/API translations + for trans in self.formio_version_id.translations: + if trans.lang_id.iso_code not in i18n: + i18n[trans.lang_id.iso_code] = {trans.property: trans.value} + else: + i18n[trans.lang_id.iso_code][trans.property] = trans.value + # Form Builder translations (labels etc). + # These could override the former GUI/API translations, but + # that's how the Javascript API works. + for trans in self.translations: + if trans.lang_id.iso_code not in i18n: + i18n[trans.lang_id.iso_code] = {trans.source: trans.value} + else: + i18n[trans.lang_id.iso_code][trans.source] = trans.value + return i18n diff --git a/formio/models/formio_form.py b/formio/models/formio_form.py index 1fa3fd08..a8712c1b 100644 --- a/formio/models/formio_form.py +++ b/formio/models/formio_form.py @@ -4,7 +4,6 @@ import ast import json import re -import requests import uuid from dateutil.relativedelta import relativedelta @@ -104,6 +103,7 @@ class Form(models.Model): show_id = fields.Boolean("Show ID") show_uuid = fields.Boolean("Show UUID") show_user_metadata = fields.Boolean("Show User Metadata") + languages = fields.One2many('res.lang', related='builder_id.languages', string='Languages') allow_unlink = fields.Boolean("Allow delete", compute='_compute_access') allow_force_update_state = fields.Boolean("Allow force update State", compute='_compute_access') readonly_submission_data = fields.Boolean("Data is readonly", compute='_compute_access') @@ -456,25 +456,31 @@ def get_public_form(self, uuid, public_share=False): else: return False + def _get_js_options(self): + """ formio JS (API) options """ + options = { + 'i18n': self.i18n_translations() + } + if self.state in [STATE_COMPLETE, STATE_CANCEL]: + options['readOnly'] = True + + if self.builder_id.view_as_html: + options['renderMode'] = 'html' + options['viewAsHtml'] = True # backwards compatible (version < 4.x)? + return options + + def _get_js_params(self): + """ Odoo JS (Owl component) misc. params """ + params = { + 'portal_submit_done_url': self.portal_submit_done_url + } + return params + def _etl_odoo_data(self): return {} def i18n_translations(self): - i18n = {} - # Formio GUI/API translations - for trans in self.builder_id.formio_version_id.translations: - if trans.lang_id.iso_code not in i18n: - i18n[trans.lang_id.iso_code[:2]] = {trans.property: trans.value} - else: - i18n[trans.lang_id.iso_code[:2]][trans.property] = trans.value - # Form Builder translations (labels etc). - # These could override the former GUI/API translations, but - # that's how the Javascript API works. - for trans in self.builder_id.translations: - if trans.lang_id.iso_code not in i18n: - i18n[trans.lang_id.iso_code[:2]] = {trans.source: trans.value} - else: - i18n[trans.lang_id.iso_code[:2]][trans.source] = trans.value + i18n = self.builder_id.i18n_translations() return i18n diff --git a/formio/static/description/index.html b/formio/static/description/index.html index 7426a443..49fe305f 100644 --- a/formio/static/description/index.html +++ b/formio/static/description/index.html @@ -62,7 +62,7 @@

Features

Multilingual & Translations management - Forms are multilingual: Language-switch buttons can be setup. Manage your custom translations (e.g. labels, select choices) in the Form Builder. + Forms and Builders are multilingual: Language-switch buttons can be setup. Manage your custom translations (e.g. labels, select choices) in the Form Builder. Upgrade-tool GUI software @@ -174,6 +174,17 @@

Download & Install Available (Form.io GUI) V

Releases

+

7.7

+
    +
  • + Translatable (multilingual) public Forms, with language-switcher buttons.
    + This addresses:
    + https://github.com/novacode-nl/odoo-formio/issues/58
    + https://github.com/novacode-nl/odoo-formio/issues/47 +
  • + Translatable (multilingual) Form Builder, with language-switcher buttons. +
  • +

7.6

  • diff --git a/formio/static/src/css/formio_builder_embed.css b/formio/static/src/css/formio_builder_embed.css index 24f4f0d1..3386f746 100644 --- a/formio/static/src/css/formio_builder_embed.css +++ b/formio/static/src/css/formio_builder_embed.css @@ -7,3 +7,14 @@ body { padding-left: 4px; padding-right: 4px; } + +.formio_languages { + clear: both; + margin-top: 10px; + margin-bottom: 20px; + padding-left: 4px; +} + +.formio_languages button { + border: 1px solid #d8d8d8; +} diff --git a/formio/static/src/js/builder/app.js b/formio/static/src/js/builder/app.js index c5848d89..620d4369 100644 --- a/formio/static/src/js/builder/app.js +++ b/formio/static/src/js/builder/app.js @@ -17,13 +17,13 @@ class App extends Component { self.saveUrl = '/formio/builder/' + self.builderId + '/save'; self.schema = {}; self.options = {}; - self.mode = {}; + self.params = {}; $.jsonRpc.request(self.configUrl, 'call', {}).then(function(result) { if (!$.isEmptyObject(result)) { self.schema = result.schema; self.options = result.options; - self.config = result.config; + self.params = result.params; self.createBuilder(); } }); @@ -31,22 +31,35 @@ class App extends Component { createBuilder() { const self = this; - Formio.builder(document.getElementById('formio_builder'), self.schema, self.options).then(function(builder) { - builder.on('change', function(res) { - if ('readOnly' in self.mode && self.mode['readOnly'] == true) { - alert("This Form Builder is readonly. It's state is either Current or Obsolete. Refresh the page again."); - return; - } - else { - console.log('[Form.io] Saving Builder...'); - $.jsonRpc.request(self.saveUrl, 'call', { - 'builder_id': self.builderId, - 'schema': res - }).then(function() { - console.log('[Form.io] Builder sucessfully saved.'); - }); - } - }); + const builder = new Formio.FormBuilder(document.getElementById('formio_builder'), self.schema, self.options); + + builder.instance.ready.then(function() { + if ('language' in self.options) { + builder.language = self.options['language']; + } + window.setLanguage = function(lang) { + builder.instance.webform.language = lang; + builder.instance.redraw(); + }; + }); + + builder.instance.on('change', function(res) { + if (! res.hasOwnProperty('components')) { + return; + } + else if ('readOnly' in self.params && self.params['readOnly'] == true) { + alert("This Form Builder is readonly. It's state is either Current or Obsolete. Refresh the page again."); + return; + } + else { + console.log('[Form.io] Saving Builder...'); + $.jsonRpc.request(self.saveUrl, 'call', { + 'builder_id': self.builderId, + 'schema': res + }).then(function() { + console.log('[Form.io] Builder sucessfully saved.'); + }); + } }); } } diff --git a/formio/static/src/js/form/backend_app.js b/formio/static/src/js/form/backend_app.js index 002598b6..080bcda3 100644 --- a/formio/static/src/js/form/backend_app.js +++ b/formio/static/src/js/form/backend_app.js @@ -36,14 +36,14 @@ function app() { } portalSubmitDoneUrl() { - return this.config.hasOwnProperty('portal_submit_done_url') && this.config.portal_submit_done_url; + return this.params.hasOwnProperty('portal_submit_done_url') && this.params.portal_submit_done_url; } submitDone(submission) { if (submission.state == 'submitted') { if (this.urlParams.get('portal') === 'true' && this.portalSubmitDoneUrl()) { - const config = {submit_done_url: this.portalSubmitDoneUrl()}; - window.parent.postMessage({odooFormioMessage: 'formioSubmitDone', config: config}); + const params = {submit_done_url: this.portalSubmitDoneUrl()}; + window.parent.postMessage({odooFormioMessage: 'formioSubmitDone', params: params}); } } // If the window.parent doesn't receive and handle the postMessage. diff --git a/formio/static/src/js/form/formio_form.js b/formio/static/src/js/form/formio_form.js index 63813662..fe8558f0 100644 --- a/formio/static/src/js/form/formio_form.js +++ b/formio/static/src/js/form/formio_form.js @@ -19,7 +19,7 @@ export class OdooFormioForm extends Component { this.schema = {}; this.options = {}; - this.config = {}; // extra config from Odoo backend + this.params = {}; // extra params from Odoo backend this.baseUrl = window.location.protocol + '//' + window.location.host; this.urlParams = new URLSearchParams(window.location.search); @@ -55,7 +55,7 @@ export class OdooFormioForm extends Component { if (!$.isEmptyObject(result)) { self.schema = result.schema; self.options = result.options; - self.config = result.config; + self.params = result.params; self.createForm(); } }); diff --git a/formio/static/src/js/form/public_create_app.js b/formio/static/src/js/form/public_create_app.js index 09d68fa5..25cc78be 100644 --- a/formio/static/src/js/form/public_create_app.js +++ b/formio/static/src/js/form/public_create_app.js @@ -36,14 +36,14 @@ function app() { } publicSubmitDoneUrl() { - return this.config.hasOwnProperty('public_submit_done_url') && this.config.public_submit_done_url; + return this.params.hasOwnProperty('public_submit_done_url') && this.params.public_submit_done_url; } submitDone(submission) { if (submission.state == 'submitted') { if (this.publicSubmitDoneUrl()) { - const config = {submit_done_url: this.publicSubmitDoneUrl()}; - window.parent.postMessage({odooFormioMessage: 'formioSubmitDone', config: config}); + const params = {submit_done_url: this.publicSubmitDoneUrl()}; + window.parent.postMessage({odooFormioMessage: 'formioSubmitDone', params: params}); } } // If the window.parent doesn't receive and handle the postMessage. diff --git a/formio/static/src/js/formio_form_container.js b/formio/static/src/js/formio_form_container.js index 40d602c7..0f7af524 100644 --- a/formio/static/src/js/formio_form_container.js +++ b/formio/static/src/js/formio_form_container.js @@ -9,8 +9,8 @@ $(document).ready(function() { if (event.data.hasOwnProperty('odooFormioMessage')) { const msg = event.data.odooFormioMessage, - config = event.data.config, - submitDoneUrl = config.hasOwnProperty('submit_done_url') && config.submit_done_url; + params = event.data.params, + submitDoneUrl = params.hasOwnProperty('submit_done_url') && params.submit_done_url; if (event.origin == baseUrl && msg == 'formioSubmitDone' && submitDoneUrl) { window.location = submitDoneUrl; diff --git a/formio/views/formio_builder_templates.xml b/formio/views/formio_builder_templates.xml index f2b55d22..a0561e7e 100644 --- a/formio/views/formio_builder_templates.xml +++ b/formio/views/formio_builder_templates.xml @@ -32,6 +32,13 @@ See LICENSE file for full licensing details. -->