Skip to content

Commit

Permalink
feat: Allow custom controls to add one or more Option based attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasnetau committed Jan 29, 2024
1 parent 2ac8653 commit 2e58689
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 29 deletions.
25 changes: 16 additions & 9 deletions src/js/form-builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -363,14 +363,17 @@ function FormBuilder(opts, element, $) {
/**
* Add data for field with options [select, checkbox-group, radio-group]
*
* @param {string} fieldName
* @param {Object} fieldData
* @return {string} field options markup
*/
const fieldOptions = function (fieldData) {
const fieldOptions = function (fieldName, fieldData) {
const { type, values } = fieldData
let fieldValues
const optionActions = [m('a', mi18n.get('addOption'), { className: 'add add-opt' })]
const fieldOptions = [m('label', mi18n.get('selectOptions'), { className: 'false-label' })]
const fieldLabel = fieldName === 'values' ? mi18n.get('selectOptions') : i18n[fieldName]
const fieldOptions = [m('label', fieldLabel, { className: 'false-label' })]
const optionsNoSelect = fieldData['noSelect'] ?? false
const isMultiple = fieldData.multiple || type === 'checkbox-group'
const optionDataTemplate = count => {
const label = mi18n.get('optionCount', count)
Expand All @@ -393,27 +396,29 @@ function FormBuilder(opts, element, $) {
firstOption.selected = true
}
} else {
// ensure option data is has all required keys
// ensure option data contains all required keys
fieldValues = values.map(option => Object.assign({}, { selected: false }, option))
}

const optionActionsWrap = m('div', optionActions, { className: 'option-actions' })
const optionGroupName = window.crypto.randomUUID() + '-options'
const options = m(
'ol',
fieldValues.map((option, index, _, fieldName = fieldData.name) => {
fieldValues.map((option, index) => {
const optionData = config.opts.onAddOption(option, { type, index, isMultiple })
const optionGroupName = fieldName + '-options'
if (optionsNoSelect) {
optionData.selected = false
}
return selectFieldOptions(optionGroupName, optionData, isMultiple)
}),
{
className: 'sortable-options',
className: 'sortable-options' + (optionsNoSelect ? ' options-no-select' : ''),
},
)
const optionsWrap = m('div', [options, optionActionsWrap], { className: 'sortable-options-wrap' })

fieldOptions.push(optionsWrap)

return m('div', fieldOptions, { className: 'form-group field-options' }).outerHTML
return m('div', fieldOptions, { name: fieldName, className: 'form-group field-options' }).outerHTML
}

const defaultFieldAttrs = type => {
Expand Down Expand Up @@ -540,7 +545,7 @@ function FormBuilder(opts, element, $) {
first: mi18n.get('enableOther'),
second: mi18n.get('enableOtherMsg'),
}),
options: () => fieldOptions(values),
options: () => fieldOptions('values', values),
requireValidOption: () =>
boolAttribute('requireValidOption', values, {
first: ' ',
Expand Down Expand Up @@ -636,6 +641,7 @@ function FormBuilder(opts, element, $) {
[
['array', ({ options }) => !!options],
['boolean', ({ type }) => type === 'checkbox'], // automatic bool if checkbox
['options', ({ type }) => type === 'options'],
[typeof attrData.value, () => true], // string, number,
].find(typeCondition => typeCondition[1](attrData))[0]
)
Expand Down Expand Up @@ -674,6 +680,7 @@ function FormBuilder(opts, element, $) {
}
return boolAttribute(attr, { ...attrData, [attr]: isChecked }, { first: i18n[attr] })
},
options: fieldOptions,
}

for (const attribute in typeUserAttr) {
Expand Down
28 changes: 8 additions & 20 deletions src/js/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,6 @@ export default class Helpers {
*/
prepData(form) {
const formData = []
const d = this.d
const _this = this

if (form.childNodes.length !== 0) {
Expand Down Expand Up @@ -277,11 +276,10 @@ export default class Helpers {

fieldData = trimObj(fieldData)

const multipleField = fieldData.type && fieldData.type.match(d.optionFieldsRegEx)

if (multipleField) {
fieldData.values = _this.fieldOptionData($field)
}
$field.find('.form-group.field-options').each((_, attribute) => {
const attributeName = attribute.getAttribute('name')
fieldData[attributeName] = _this.fieldOptionData(attribute)
})

formData.push(fieldData)
}
Expand Down Expand Up @@ -390,7 +388,6 @@ export default class Helpers {
*/
updatePreview($field) {
const _this = this
const d = this.d
const fieldClass = $field.attr('class')
const field = $field[0]
if (fieldClass.includes('input-control')) {
Expand All @@ -401,19 +398,10 @@ export default class Helpers {
const $prevHolder = $('.prev-holder', field)
let previewData = Object.assign({}, _this.getAttrVals(field), { type: fieldType })

if (fieldType.match(d.optionFieldsRegEx)) {
previewData.values = []
previewData.multiple = $('[name="multiple"]', field).is(':checked')

$('.sortable-options li', field).each(function (i, $option) {
const option = {
selected: $('.option-selected', $option).is(':checked'),
value: $('.option-value', $option).val(),
label: $('.option-label', $option).val(),
}
previewData.values.push(option)
})
}
$field.find('.form-group.field-options').each((_, attribute) => {
const attributeName = attribute.getAttribute('name')
previewData[attributeName] = _this.fieldOptionData(attribute)
})

previewData = trimObj(previewData, true)

Expand Down
4 changes: 4 additions & 0 deletions src/sass/_stage.scss
Original file line number Diff line number Diff line change
Expand Up @@ -856,3 +856,7 @@
position: fixed !important;
left: -100px !important;
}

ol.options-no-select input[type=radio]{
display: none;
}

0 comments on commit 2e58689

Please sign in to comment.