diff --git a/src/js/controls.js b/src/js/controls.js index 78bb8a554..54f4ded8e 100644 --- a/src/js/controls.js +++ b/src/js/controls.js @@ -21,9 +21,6 @@ export default class Controls { this.opts = opts this.dom = d.controls this.getRegistered = control.getRegistered - // ability for controls to have their own configuration / options - // of the format control identifier (type, or type.subtype): {options} - control.controlConfig = opts.controlConfig || {} this.init() } diff --git a/src/js/form-builder.js b/src/js/form-builder.js index d02338aa8..8572bb3ea 100644 --- a/src/js/form-builder.js +++ b/src/js/form-builder.js @@ -75,7 +75,7 @@ function FormBuilder(opts, element, $) { if (!opts.layout) { opts.layout = layout } - const layoutEngine = new opts.layout(opts.layoutTemplates, true, opts.disableHTMLLabels) + const layoutEngine = new opts.layout(opts.layoutTemplates, true, opts.disableHTMLLabels, opts.controlConfig) const h = new Helpers(formID, layoutEngine, formBuilder) const m = markup diff --git a/src/js/form-render.js b/src/js/form-render.js index 29d492c9c..30e545992 100644 --- a/src/js/form-render.js +++ b/src/js/form-render.js @@ -197,7 +197,7 @@ class FormRender { const rendered = [] // instantiate the layout class & loop through the field configuration - const engine = new opts.layout(opts.layoutTemplates, false, opts.disableHTMLLabels) + const engine = new opts.layout(opts.layoutTemplates, false, opts.disableHTMLLabels, opts.controlConfig) if (opts.formData.length) { for (let i = 0; i < opts.formData.length; i++) { const fieldData = opts.formData[i] diff --git a/src/js/layout.js b/src/js/layout.js index 48c2c1f7d..93baf1825 100644 --- a/src/js/layout.js +++ b/src/js/layout.js @@ -1,6 +1,7 @@ // LAYOUT.JS import utils from './utils' import { getAllGridRelatedClasses } from './utils' +import control from './control' const processClassName = (data, field) => { // wrap the output in a form-group div & return @@ -43,12 +44,14 @@ export default class layout { /** * Prepare the templates for layout * @param {Object} templates object containing custom or overwrite templates - * @param {Boolean} preview - are we rendering a preview for the formBuilder stage - * @param {Boolean} disableHTMLLabels - do we render labels as HTML or plain text + * @param {Boolean} [preview=false] - are we rendering a preview for the formBuilder stage + * @param {Boolean} [disableHTMLLabels=false] - do we render labels as HTML or plain text + * @param {Array} [controlConfig={}] - ability for controls to have their own configuration / options of the format control identifier (type, or type.subtype): {options} */ - constructor(templates, preview = false, disableHTMLLabels = false) { + constructor(templates, preview = false, disableHTMLLabels = false, controlConfig = {}) { this.preview = preview ?? false this.disableHTMLLabels = disableHTMLLabels ?? false + this.controlConfig = controlConfig ?? {} // supported templates for outputting a field // preferred layout template can be indicated by specifying a 'layout' in the return object of control::build @@ -115,8 +118,9 @@ export default class layout { this.data = jQuery.extend({}, data) // build the control - const control = new renderControl(data, this.preview) - let field = control.build() + control.controlConfig = this.controlConfig + const controlInstance = new renderControl(data, this.preview) + let field = controlInstance.build() if (typeof field !== 'object' || !field.field) { field = { field: field } } @@ -145,10 +149,10 @@ export default class layout { const element = this.processTemplate(elementTemplate, field.field, label, help) // execute prerender events - control.on('prerender')(element) + controlInstance.on('prerender')(element) // bind control on render events - element.addEventListener('fieldRendered', control.on('render')) + element.addEventListener('fieldRendered', controlInstance.on('render')) return element } diff --git a/tests/form-builder.test.js b/tests/form-builder.test.js index d026c917a..7ba47f98b 100644 --- a/tests/form-builder.test.js +++ b/tests/form-builder.test.js @@ -435,4 +435,54 @@ describe('async loading tests', () => { expect(wrap2.formBuilder('markup', 'div').outerHTML).toBe('
') }) + + test('controlConfig is loaded per instance', async () => { + const wrap1 = $('
') + const wrap2 = $('
') + const templates = { + text: function(fieldData) { + this.classConfig.callback() + return { + field: 'preview' + } + } + } + const cb1 = jest.fn() + const cb2 = jest.fn() + const config1 = { + templates, + controlConfig: { + 'text.text': { + callback: cb1 + } + } + } + const config2 = { + templates, + controlConfig: { + 'text.text': { + callback: cb2 + } + } + } + const p1 = wrap1.formBuilder(config1).promise + const p2 = wrap2.formBuilder(config2).promise + + const fb1 = await p1 + const fb2 = await p2 + + const field = { + type: 'text', + class: 'form-control' + } + fb1.actions.addField(field) + + expect(cb1.mock.calls).toHaveLength(1) + expect(cb2.mock.calls).toHaveLength(0) + + fb2.actions.addField(field) + expect(cb1.mock.calls).toHaveLength(1) + expect(cb2.mock.calls).toHaveLength(1) + }) + }) \ No newline at end of file