Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix processing of number attributes for a field #1521

Merged
merged 2 commits into from
Mar 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions src/js/form-builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import {
safename,
forceNumber,
getContentType,
generateSelectorClassNames,
generateSelectorClassNames, firstNumberOrUndefined,
} from './utils'
import { attributeWillClobber, setElementContent, setSanitizerConfig } from './sanitizer'
import fontConfig from '../fonts/config.json'
Expand Down Expand Up @@ -682,8 +682,16 @@ function FormBuilder(opts, element, $) {
if (attrValType !== 'undefined') {
const orig = mi18n.get(attribute)
const tUA = typeUserAttr[attribute]
const origValue = attrValType === 'boolean' ? tUA.value : (tUA.value || '')
tUA.value = values[attribute] || origValue
let origValue = tUA.value
if (attrValType === 'boolean') {
origValue = tUA.value
tUA[attribute] ??= tUA.value
} else if (attrValType === 'number') {
tUA[attribute] ??= firstNumberOrUndefined(values[attribute], origValue)
} else {
origValue ??= ''
tUA[attribute] ??= values[attribute] || origValue
}

if (tUA.label) {
i18n[attribute] = Array.isArray(tUA.label) ? mi18n.get(...tUA.label) || tUA.label[0] : tUA.label
Expand Down Expand Up @@ -871,7 +879,7 @@ function FormBuilder(opts, element, $) {
*/
const numberAttribute = (attribute, values) => {
const { class: classname, className, ...attrs } = values
const attrVal = (isNaN(attrs[attribute])) ? undefined : attrs[attribute]
const attrVal = (Number.isNaN(attrs[attribute])) ? undefined : attrs[attribute]
const attrLabel = mi18n.get(attribute) || attribute
const placeholder = mi18n.get(`placeholder.${attribute}`)

Expand Down
5 changes: 5 additions & 0 deletions src/js/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,10 @@ export function titleCase(str) {
)
}

export function firstNumberOrUndefined(...options) {
return options.find(x => typeof x === 'number')
}

const utils = {
addEventListeners,
attrString,
Expand Down Expand Up @@ -733,6 +737,7 @@ const utils = {
unique,
validAttr,
titleCase,
firstNumberOrUndefined,
}

/**
Expand Down
59 changes: 58 additions & 1 deletion tests/form-builder.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,38 @@ describe('FormBuilder stage names translated', () => {
})
})

describe('FormBuilder attribute setup', () => {
test('number control number attributes do not inherit field value when not set', async() => {
const config = {}
const fbWrap = $('<div>')
const fb = await fbWrap.formBuilder(config).promise
fb.actions.addField({
type: 'number',
value: '5.2',
})
expect(fbWrap.find('.value-wrap input').val()).toBe('5.2')
expect(fbWrap.find('.min-wrap input').val()).toBe('')
expect(fbWrap.find('.max-wrap input').val()).toBe('')
expect(fbWrap.find('.step-wrap input').val()).toBe('')
})
test('number control number attributes do not inherit field value when set', async() => {
const config = {}
const fbWrap = $('<div>')
const fb = await fbWrap.formBuilder(config).promise
fb.actions.addField({
type: 'number',
value: '5.2',
min: 2,
max: 10,
step: 1.0,
})
expect(fbWrap.find('.value-wrap input').val()).toBe('5.2')
expect(fbWrap.find('.min-wrap input').val()).toBe('2')
expect(fbWrap.find('.max-wrap input').val()).toBe('10')
expect(fbWrap.find('.step-wrap input').val()).toBe('1')
})

})
describe('FormBuilder typeUserAttrs detection', () => {
test('renders text/string user attribute', async () => {
const config = {
Expand Down Expand Up @@ -238,6 +270,27 @@ describe('FormBuilder typeUserAttrs detection', () => {
expect(input.is(':checked')).toBeFalsy()
})
test('renders number user attribute when value is number', async () => {
const config = {
typeUserAttrs: {
text: {
testAttribute: {
label: 'test',
value: 10,
},
},
},
}
const fbWrap = $('<div>')
const fb = await fbWrap.formBuilder(config).promise
fb.actions.addField({
type: 'text',
value: '1',
})
const input = fbWrap.find('.testAttribute-wrap input')
expect(input.attr('type')).toBe('number')
expect(input.val()).toBe('10')
})
test('renders number user attribute when value is zero', async () => {
const config = {
typeUserAttrs: {
text: {
Expand All @@ -250,9 +303,13 @@ describe('FormBuilder typeUserAttrs detection', () => {
}
const fbWrap = $('<div>')
const fb = await fbWrap.formBuilder(config).promise
fb.actions.addField({ type: 'text'})
fb.actions.addField({
type: 'text',
value: '1',
})
const input = fbWrap.find('.testAttribute-wrap input')
expect(input.attr('type')).toBe('number')
expect(input.val()).toBe('0')
})
test('renders select user attribute when options given', async () => {
const config = {
Expand Down
8 changes: 7 additions & 1 deletion tests/utils.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const utils = require('./../src/js/utils.js')
const { safeAttr, flattenArray, safeAttrName, hyphenCase, camelCase, bindEvents, attrString, nameAttr, markup,
parsedHtml, escapeAttrs, getScripts, capitalize, addEventListeners, unique, escapeAttr, escapeHtml,
getAllGridRelatedClasses, subtract, safename, xmlParseAttrs, parseXML
getAllGridRelatedClasses, subtract, safename, xmlParseAttrs, parseXML, firstNumberOrUndefined
} = require('../src/js/utils')

describe('Test Util functions', () => {
Expand Down Expand Up @@ -143,6 +143,12 @@ describe('Test Util functions', () => {
expect(subtract([2],[1,2,3])).toEqual([1,3])
expect(subtract(['remove-me'],['classA','classB','remove-me','classC'])).toEqual(['classA','classB','classC'])
})

test('firstNumberOrUndefined', () => {
expect(firstNumberOrUndefined(1)).toEqual(1)
expect(firstNumberOrUndefined(1,2,3)).toEqual(1)
expect(firstNumberOrUndefined(undefined,'',2,1)).toEqual(2)
})
})

describe('Test XML functions', () => {
Expand Down
Loading