Skip to content

Commit

Permalink
Merge pull request #1580 from lucasnetau/fix/1578
Browse files Browse the repository at this point in the history
Fix GH-1578 incorrect handling of label translation for custom controls
  • Loading branch information
kevinchappell authored Jul 5, 2024
2 parents 6bed8f2 + f1b580b commit b24e2f6
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 16 deletions.
4 changes: 3 additions & 1 deletion src/js/controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,10 @@ export default class Controls {
// first check if this is a custom control
let custom = this.custom.lookup(type)
let controlClass
let label
if (custom) {
controlClass = custom.class
label = this.custom.label(type)
} else {
custom = {}

Expand All @@ -76,9 +78,9 @@ export default class Controls {
if (!controlClass || !controlClass.active(type)) {
continue
}
label = controlClass.label(type)
}
const icon = custom.icon || controlClass.icon(type)
let label = custom.label || controlClass.label(type)
const iconClassName = !icon ? custom.iconClassName || `${css_prefix_text + type.replace(/-[\d]{4}$/, '')}` : ''

// if the class has specified a custom icon, inject it into the label
Expand Down
30 changes: 15 additions & 15 deletions src/js/customControls.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,24 +75,24 @@ export default class customControls {
// if there is no template defined for this type, check if we already have this type/subtype registered
if (!templates[type]) {
// check that this type is already registered
const controlClass = control.getClass(type, field.subtype)
if (!controlClass) {
super.error(
try {
const controlClass = control.getClass(type, field.subtype)

// generate a random key & map the settings against it
lookup = field.datatype ? field.datatype : `${type}-${Math.floor(Math.random() * 9000 + 1000)}`

this.customRegister[lookup] = jQuery.extend(field, {
type: type,
class: controlClass,
})
} catch(e) {
control.error(
'Error while registering custom field: ' +
type +
(field.subtype ? ':' + field.subtype : '') +
'. Unable to find any existing defined control or template for rendering.',
)
continue
}

// generate a random key & map the settings against it
lookup = field.datatype ? field.datatype : `${type}-${Math.floor(Math.random() * 9000 + 1000)}`

this.customRegister[lookup] = jQuery.extend(field, {
type: type,
class: controlClass,
})
} else {
//Map the field definition into the templated control class
const controlClass = this.templateControlRegister[type]
Expand All @@ -104,7 +104,7 @@ export default class customControls {
}

// map label & icon
this.def.i18n[locale][lookup] = field.label
this.def.i18n[locale][lookup] = Array.isArray(field.label) ? mi18n.get(...field.label) || field.label[0] : field.label
this.def.icon[lookup] = field.icon
}
}
Expand All @@ -123,7 +123,7 @@ export default class customControls {
* @param {Object|Number|String} [args] - string or key/val pairs for string lookups with variables
* @return {String} the translated label
*/
const def = this.definition
const def = this.def
let i18n = def.i18n || {}
const locale = mi18n.locale
i18n = i18n[locale] || i18n.default || i18n
Expand Down Expand Up @@ -158,7 +158,7 @@ export default class customControls {
icon(type) {
// @todo - support for `${css_prefix_text}${attr.name}` - is this for inputSets? Doesnt look like it but can't see anything else that sets attr.name?
// https://formbuilder.online/docs/formBuilder/options/inputSets/
const def = this.definition
const def = this.def
if (def && typeof def.icon === 'object') {
return def.icon[type]
}
Expand Down
2 changes: 2 additions & 0 deletions src/js/form-builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,9 @@ function FormBuilder(opts, element, $) {
// check for a custom type
const custom = controls.custom.lookup(field.type)
if (custom) {
const customType = field.type
field = Object.assign({}, custom)
field.label = controls.custom.label(customType)
} else {
const controlClass = controls.getClass(field.type)
field.label = controlClass.label(field.type)
Expand Down
28 changes: 28 additions & 0 deletions tests/control/custom.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -404,4 +404,32 @@ describe('Test Custom Control', () => {
expect(fbWrap.find('#starRating-1697591966052-0')[0].outerHTML).toBe('<span id="starRating-1697591966052-0"></span>')

})

test('custom replacedField with invalid type throws Error', async () => {
const fbWrap = $('<div>')

const replaceFields = [{
type: 'nonExistent'
}]

let error
await fbWrap.formBuilder({replaceFields}).promise.catch(e => error = e)

expect(error).toBeInstanceOf(Error)
expect(error.message).toMatch(/Error while registering custom field:/)
})

test('custom replacedField with missing type throws Error', async () => {
const fbWrap = $('<div>')

const replaceFields = [{
value: 1
}]

let error
await fbWrap.formBuilder({replaceFields}).promise.catch(e => error = e)

expect(error).toBeInstanceOf(Error)
expect(error.message).toMatch(/Ignoring invalid custom field definition. Please specify a type property./)
})
})
32 changes: 32 additions & 0 deletions tests/translation.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,38 @@ describe('FormBuilder stage names translated', () => {
expect(fbWrap.find('.readonly-wrap label').text()).toBe(config.i18n.override['en-US'].readOnly)
})

test('can change label of built-in control via replaceFields GH-1578', async () => {
const config = {
replaceFields: [{
label: ['myTranslateLabel'],
type: 'text'
}],
i18n: {
location: LANGUAGE_LOCATION,
override: {
'en-US': {
myTranslateLabel: 'Translated Field',
}
}
}
}

const fbWrap = $('<div>')
const fb = await $(fbWrap).formBuilder(config).promise

const overrideField = fbWrap.find('.cb-wrap .input-control[data-type*="text-"]')

expect(overrideField.find('span').text()).toBe(config.i18n.override['en-US'].myTranslateLabel)

//@TODO support adding custom fields via addField
//const field = {
// type: overrideField.data('type'),
// class: 'form-control'
//}
//fb.actions.addField(field)
//expect(fbWrap.find('.fld-label').val()).toBe(config.i18n.override['en-US'].myTranslateLabel)
})

test('can set form to another language than default with config', async () => {
const config = {
i18n: {
Expand Down

0 comments on commit b24e2f6

Please sign in to comment.