Skip to content

Commit

Permalink
fix: initialise formRender with an empty formData in cases when no fo…
Browse files Browse the repository at this point in the history
…rmData is provided, otherwise we are unable to perform setData/render functions on the container
  • Loading branch information
lucasnetau committed Oct 19, 2023
1 parent 2dde66a commit 48700de
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 44 deletions.
63 changes: 29 additions & 34 deletions src/js/form-render.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class FormRender {
container: false, // string selector or Node element
dataType: 'json',
disableHTMLLabels: false,
formData: false,
formData: [],
i18n: Object.assign({}, defaultI18n),
messages: {
formRendered: 'Form Rendered',
Expand Down Expand Up @@ -72,12 +72,12 @@ class FormRender {
}

// parse any passed formData
if (!this.options.formData) {
return false
if (this.options.formData) {
this.options.formData = this.parseFormData(this.options.formData)
} else {
this.options.formData = []
}

this.options.formData = this.parseFormData(this.options.formData)

// ability for controls to have their own configuration / options of the format control identifier (type, or type.subtype): {options}
control.controlConfig = options.controlConfig || {}

Expand Down Expand Up @@ -144,7 +144,7 @@ class FormRender {
/**
* Clean up passed object configuration to prepare for use with the markup function
* @param {Object} field - object of field configuration
* @param {number} instanceIndex - instance index
* @param {number} [instanceIndex] - instance index
* @return {Object} sanitized field object
*/
sanitizeField(field, instanceIndex) {
Expand Down Expand Up @@ -198,10 +198,9 @@ class FormRender {
// Begin the core plugin
const rendered = []

// generate field markup if we have fields
if (opts.formData) {
// instantiate the layout class & loop through the field configuration
const engine = new opts.layout(opts.layoutTemplates, false, opts.disableHTMLLabels)
// instantiate the layout class & loop through the field configuration
const engine = new opts.layout(opts.layoutTemplates, false, opts.disableHTMLLabels)
if (opts.formData.length) {
for (let i = 0; i < opts.formData.length; i++) {
const fieldData = opts.formData[i]
const sanitizedField = this.sanitizeField(fieldData, instanceIndex)
Expand All @@ -212,33 +211,29 @@ class FormRender {

rendered.push(field)
}
} else {
opts.notify.warning(opts.messages.noFormData)
}

if (element) {
this.instanceContainers[instanceIndex] = element
}
if (element) {
this.instanceContainers[instanceIndex] = element
}

// if rendering, inject the fields into the specified wrapper container/element
if (opts.render && element) {
element.emptyContainer()
element.appendFormFields(rendered)

runCallbacks()
opts.notify.success(opts.messages.formRendered)
} else {
/**
* Retrieve the html markup for a passed array of DomElements
* @param {Array} fields - array of dom elements
* @return {string} fields html
*/
const exportMarkup = fields => fields.map(elem => elem.innerHTML).join('')
formRender.markup = exportMarkup(rendered)
}
// if rendering, inject the fields into the specified wrapper container/element
if (opts.render && element) {
element.emptyContainer()
element.appendFormFields(rendered)

runCallbacks()
opts.notify.success(opts.messages.formRendered)
} else {
const noData = utils.markup('div', opts.messages.noFormData, {
className: 'no-form-data',
})
rendered.push(noData)
opts.notify.error(opts.messages.noFormData)
/**
* Retrieve the html markup for a passed array of DomElements
* @param {Array} fields - array of dom elements
* @return {string} fields html
*/
const exportMarkup = fields => fields.map(elem => elem.innerHTML).join('')
formRender.markup = exportMarkup(rendered)
}

if (opts.disableInjectedStyle === true) {
Expand Down
52 changes: 42 additions & 10 deletions tests/form-render.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,13 @@ const basicTextAreaDef = {
'required': false,
'label': 'Text Area',
'className': 'form-control',
'description': 'A nice help bubble',
'name': 'textarea-elem',
'access': false,
'subtype': 'textarea',
'userData': ['AValue'],
}

describe('FormRender invalid setup', () => {
test('will fail on no formData', () => {
const errors = [], warnings = [], success = []
$('<div>').formRender({notify: errorHandler(errors,warnings,success)})
expect(errors[0]).toBe('No form data.')
expect(success).toHaveLength(0)
})
})

describe('Form Rendering', () => {
test('can render json form document', () => {
const container = $('<div>')
Expand All @@ -31,7 +23,7 @@ describe('Form Rendering', () => {
const html = container.formRender('html')

expect(success[0]).toBe('Form Rendered')
expect(html).toContain('<textarea class="form-control" name="textarea-elem" user-data="AValue" id="textarea-elem"></textarea>')
expect(html).toContain('<textarea class="form-control" name="textarea-elem" user-data="AValue" id="textarea-elem" title="A nice help bubble"></textarea>')
expect(container.find('textarea[name=textarea-elem]').val()).toBe('AValue')
})

Expand Down Expand Up @@ -81,4 +73,44 @@ describe('Form Rendering', () => {
fb.clear()
expect(fb.userData[0].userData).not.toEqual(['string to find'])
})

test('will load empty form on no formData', () => {
const errors = [], warnings = [], success = []
$('<div>').formRender({notify: errorHandler(errors,warnings,success)})
expect(warnings[0]).toBe('No form data.')
expect(success).toHaveLength(1)
})

test('will load empty form on undefined formData', () => {
const errors = [], warnings = [], success = []
$('<div>').formRender({notify: errorHandler(errors,warnings,success), formData: undefined})
expect(warnings[0]).toBe('No form data.')
expect(success).toHaveLength(1)
})

test('Can set data then render after initialisation of empty form', () => {
const errors = [], warnings = [], success = []
const container = $('<div>')
container.formRender({notify: errorHandler(errors,warnings,success)})
container.formRender('setData', [basicTextAreaDef])
let textarea = container.find('#textarea-elem')
expect(textarea).toHaveLength(0)

container.formRender('render')

textarea = container.find('#textarea-elem')
expect(textarea).not.toHaveLength(0)
})

test('Can render after initialisation of empty form', () => {
const errors = [], warnings = [], success = []
const container = $('<div>')
container.formRender({notify: errorHandler(errors,warnings,success)})
let textarea = container.find('#textarea-elem')
expect(textarea).toHaveLength(0)

container.formRender('render', [basicTextAreaDef])
textarea = container.find('#textarea-elem')
expect(textarea).not.toHaveLength(0)
})
})

0 comments on commit 48700de

Please sign in to comment.