diff --git a/src/js/components/fields/__snapshots__/edit-panel-item.spec.js.snap b/src/js/components/fields/__snapshots__/edit-panel-item.spec.js.snap
index 363e5e00..933cc650 100644
--- a/src/js/components/fields/__snapshots__/edit-panel-item.spec.js.snap
+++ b/src/js/components/fields/__snapshots__/edit-panel-item.spec.js.snap
@@ -14,8 +14,8 @@ EditPanelItem {
>
({
click: ({ target: { checked } }) => {
+ if (field.data?.attrs?.type === 'radio') {
+ field.set('options', field.data.options.map(option => ({ ...option, selected: false })))
+ }
field.set(dataKey, checked)
field.updatePreview()
},
@@ -148,18 +151,19 @@ export default class EditPanelItem {
* @param {String} field
* @return {Object} field object
*/
- constructor(itemKey, itemData, field) {
- this.itemValues = orderObjectsBy(Object.entries(itemData), INPUT_ORDER, '0')
+ constructor({ key, data, index, field }) {
+ this.itemValues = orderObjectsBy(Object.entries(data), INPUT_ORDER, '0')
+ const [panelName, item] = key.split('.')
this.field = field
- this.itemKey = itemKey
- const [panelName, item] = itemKey.split('.')
+ this.itemKey = key
+ this.itemIndex = index
this.panelName = panelName
this.isDisabled = field.isDisabledProp(item, panelName)
this.isHidden = this.isDisabled && field.config.panels[panelName].hideDisabled
this.isLocked = field.isLockedProp(item, panelName)
this.dom = dom.create({
tag: 'li',
- className: [`field-${itemKey.replace(/\./g, '-')}`, 'prop-wrap', this.isHidden && 'hidden-property'],
+ className: [`field-${key.replace(/\./g, '-')}`, 'prop-wrap', this.isHidden && 'hidden-property'],
children: { className: 'field-prop', children: [this.itemInputs, this.itemControls] },
})
}
@@ -422,9 +426,9 @@ export default class EditPanelItem {
.filter(isNaN)
.join('.')
- const id = [this.field.id, !['selected', 'checked'].includes(key) && this.itemKey.replace(/\./g, '-')]
- .filter(Boolean)
- .join('-')
+ const [id, name] = [[...this.itemKey.split('.'), key], [key]].map(attrVars =>
+ [this.field.id, ...attrVars].filter(Boolean).join('-')
+ )
inputTypeConfig.config = Object.assign({}, inputTypeConfig.config, {
label: this.panelName !== 'options' && labelHelper(labelKey),
@@ -432,7 +436,7 @@ export default class EditPanelItem {
})
inputTypeConfig.attrs = Object.assign({}, inputTypeConfig.attrs, {
- name: inputTypeConfig.attrs.type === 'checkbox' ? `${id}[]` : id,
+ name: inputTypeConfig.attrs.type === 'checkbox' ? `${name}[]` : name,
id,
disabled: this.isDisabled,
locked: this.isLocked,
diff --git a/src/js/components/fields/edit-panel-item.spec.js b/src/js/components/fields/edit-panel-item.spec.js
index d8e19ded..56ef6168 100644
--- a/src/js/components/fields/edit-panel-item.spec.js
+++ b/src/js/components/fields/edit-panel-item.spec.js
@@ -10,12 +10,12 @@ const mockField = {
describe('EditPanelItem', () => {
it('should match attribute item snapshot', () => {
- const item = new EditPanelItem('attrs.type', { type: 'checkbox' }, mockField)
+ const item = new EditPanelItem({ key: 'attrs.type', data: { type: 'checkbox' }, field: mockField })
expect(item).toMatchSnapshot()
})
it('should match option snapshot', () => {
const itemData = { label: 'Checkbox 1', value: 'checkbox-1', checked: false }
- const item = new EditPanelItem('options.0', itemData, mockField)
+ const item = new EditPanelItem({ key: 'options.0', data: itemData, index: 0, field: mockField })
expect(item).toMatchSnapshot()
})
})
diff --git a/src/js/components/fields/edit-panel.js b/src/js/components/fields/edit-panel.js
index 0307e77c..c3c5d5aa 100644
--- a/src/js/components/fields/edit-panel.js
+++ b/src/js/components/fields/edit-panel.js
@@ -48,7 +48,7 @@ export default class EditPanel {
const itemKey = [this.name, isArray ? String(index) : data[0]].join('.')
const itemData = isArray ? data : { [data[0]]: data[1] }
- return new EditPanelItem(itemKey, itemData, this.field)
+ return new EditPanelItem({ key: itemKey, data: itemData, field: this.field })
})
const editGroupConfig = {
tag: 'ul',
@@ -138,7 +138,7 @@ export default class EditPanel {
this.field.set(`attrs.${attr}`, val)
const existingAttr = this.props.querySelector(`.field-attrs-${safeAttr}`)
- const newAttr = new EditPanelItem(itemKey, { [safeAttr]: val }, this.field)
+ const newAttr = new EditPanelItem({ key: itemKey, data: { [safeAttr]: val }, field: this.field })
if (existingAttr) {
this.props.replaceChild(newAttr.dom, existingAttr)
@@ -161,7 +161,12 @@ export default class EditPanel {
const optionTemplate = fieldOptionData.length ? cleanObj(fieldOptionData[fieldOptionData.length - 1]) : {}
const itemData = Object.assign({}, optionTemplate, { label: newOptionLabel, value: hyphenCase(newOptionLabel) })
- const newOption = new EditPanelItem(itemKey, itemData, this.field)
+ const newOption = new EditPanelItem({
+ key: itemKey,
+ data: itemData,
+ field: this.field,
+ index: this.props.children.length,
+ })
this.editPanelItems.push(newOption)
this.props.appendChild(newOption.dom)
@@ -173,7 +178,7 @@ export default class EditPanel {
const currentConditions = this.field.get('conditions')
const itemKey = `conditions.${currentConditions.length}`
const existingCondition = this.props.querySelector(`.field-${itemKey.replace('.', '-')}`)
- const newCondition = new EditPanelItem(itemKey, evt.template, this.field)
+ const newCondition = new EditPanelItem({ key: itemKey, data: evt.template, field: this.field })
if (existingCondition) {
this.props.replaceChild(newCondition.dom, existingCondition)
diff --git a/src/js/components/fields/field.js b/src/js/components/fields/field.js
index f7e9efd0..9755dfab 100644
--- a/src/js/components/fields/field.js
+++ b/src/js/components/fields/field.js
@@ -3,7 +3,7 @@ import startCase from 'lodash/startCase'
import throttle from 'lodash/throttle'
import dom from '../../common/dom'
import Panels from '../panels'
-import { indexOfNode } from '../../common/helpers'
+// import { indexOfNode } from '../../common/helpers'
import { clone, unique } from '../../common/utils'
import EditPanel from './edit-panel'
import Component from '../component'
@@ -269,12 +269,12 @@ export default class Field extends Component {
const { checked, type } = target
// @todo these kind of events should be added to control definitions
if (['checkbox', 'radio'].includes(type)) {
- const optionIndex = indexOfNode(target)
- const options = this.get('options')
+ const optionIndex = +target.id.split('-').pop()
// uncheck options if radio
if (type === 'radio') {
- options.forEach(({ selected }) => (selected = false))
+ this.set('options', this.get('options').map(option => ({ ...option, selected: false })))
}
+
const checkType = type === 'checkbox' ? 'checked' : 'selected'
this.set(`options.${optionIndex}.${checkType}`, checked)
}