Skip to content

Commit

Permalink
fix: setData working intermittently
Browse files Browse the repository at this point in the history
resolves #1197
  • Loading branch information
kevinchappell committed Jun 4, 2021
1 parent 224f234 commit 753280f
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 63 deletions.
17 changes: 12 additions & 5 deletions src/demo/js/actionButtons.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,16 @@ export const builderActions = {
console.log($('.build-wrap').formBuilder('getData'))
},
setData: () => {
const { value } = document.getElementById('set-form-data-value')
window.sessionStorage.setItem('formData', value)
$('.build-wrap').formBuilder('setData', value)
const fb = $('.build-wrap').formBuilder
const dataInput = fb('markup', 'textarea', fb('getData', 'json', true), {
id: 'setData-value',
rows: 30,
style: 'width: 100%',
})
const click = () => $('.build-wrap').formBuilder('setData', dataInput.value)
const setDataButton = fb('markup', 'button', 'Set Data', { events: { click } })
const dialogContents = fb('markup', 'div', [dataInput, setDataButton])
fb('showDialog', dialogContents, null, 'data-dialog')
},
save: () => {
$('.build-wrap').formBuilder('save')
Expand Down Expand Up @@ -67,8 +74,8 @@ export const renderActions = {
'link',
'alignleft aligncenter alignright alignjustify',
'numlist bullist outdent indent',
'preview'
].join(' | ')
'preview',
].join(' | '),
},
},
formData:
Expand Down
2 changes: 1 addition & 1 deletion src/demo/js/demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ jQuery(function ($) {
demoApi.appendChild(generateActionTable(demoActions, columns))

if (formData && formData !== '[]') {
const setFormDataInputValue = document.getElementById('set-form-data-value')
const setFormDataInputValue = document.getElementById('setData-value')
if (setFormDataInputValue) {
setFormDataInputValue.value = window.JSON.stringify(JSON.parse(formData), null, ' ')
}
Expand Down
11 changes: 11 additions & 0 deletions src/demo/sass/demo.scss
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,14 @@ body {
align-items: center;
justify-content: space-between;
}

#setData-value {
background-color: transparent;
border: 0 none;
color: #fff;
padding: 0;
}

.form-builder-dialog {
overflow-y: auto;
}
92 changes: 52 additions & 40 deletions src/js/form-builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ import {
closest,
safename,
forceNumber,
getContentType
getContentType,
} from './utils'
import { css_prefix_text } from '../fonts/config.json'

const DEFAULT_TIMEOUT = 333

const FormBuilder = function(opts, element, $) {
const FormBuilder = function (opts, element, $) {
const formBuilder = this
const i18n = mi18n.current
const formID = `frmb-${new Date().getTime()}`
Expand Down Expand Up @@ -89,7 +89,7 @@ const FormBuilder = function(opts, element, $) {
revert: 150,
beforeStop: (evt, ui) => h.beforeStop.call(h, evt, ui),
distance: 3,
update: function(event, ui) {
update: function (event, ui) {
if (h.doCancel) {
return false
}
Expand Down Expand Up @@ -247,7 +247,7 @@ const FormBuilder = function(opts, element, $) {
formBuilder.prepFieldVars = prepFieldVars

// Parse saved XML template data
const loadFields = function(formData) {
const loadFields = function (formData) {
formData = h.getData(formData)
if (formData && formData.length) {
formData.forEach(fieldData => prepFieldVars(trimObj(fieldData)))
Expand All @@ -272,7 +272,7 @@ const FormBuilder = function(opts, element, $) {
* @param {Object} fieldData
* @return {String} field options markup
*/
const fieldOptions = function(fieldData) {
const fieldOptions = function (fieldData) {
const { type, values } = fieldData
let fieldValues
const optionActions = [m('a', mi18n.get('addOption'), { className: 'add add-opt' })]
Expand All @@ -283,7 +283,7 @@ const FormBuilder = function(opts, element, $) {
return {
selected: false,
label,
value: hyphenCase(label)
value: hyphenCase(label),
}
}

Expand All @@ -307,8 +307,9 @@ const FormBuilder = function(opts, element, $) {
const options = m(
'ol',
fieldValues.map((option, index) => {
const optionData = config.opts.onAddOption(option, {type, index, isMultiple})
return selectFieldOptions(optionData, isMultiple)}),
const optionData = config.opts.onAddOption(option, { type, index, isMultiple })
return selectFieldOptions(optionData, isMultiple)
}),
{
className: 'sortable-options',
},
Expand Down Expand Up @@ -508,7 +509,7 @@ const FormBuilder = function(opts, element, $) {
})

// Append custom attributes as defined in control plugin definition
if (typeClass.definition.hasOwnProperty('defaultAttrs')){
if (typeClass.definition.hasOwnProperty('defaultAttrs')) {
const customAttr = processTypeUserAttrs(typeClass.definition.defaultAttrs, values)
advFields.push(customAttr)
}
Expand Down Expand Up @@ -626,15 +627,15 @@ const FormBuilder = function(opts, element, $) {
}

textAttrs = Object.assign({}, attrs, textAttrs)

const textInput = (() => {
if (textAttrs.type === 'textarea') {
const textValue = textAttrs.value
delete textAttrs.value
return `<textarea ${attrString(textAttrs)}>${textValue}</textarea>`
} else {
return `<input ${attrString(textAttrs)}>`
}
if (textAttrs.type === 'textarea') {
const textValue = textAttrs.value
delete textAttrs.value
return `<textarea ${attrString(textAttrs)}>${textValue}</textarea>`
} else {
return `<input ${attrString(textAttrs)}>`
}
})()

const inputWrap = `<div class="input-wrap">${textInput}</div>`
Expand Down Expand Up @@ -674,7 +675,7 @@ const FormBuilder = function(opts, element, $) {

const label = `<label for="${selectAttrs.id}">${i18n[name]}</label>`

Object.keys(restData).forEach(function(attr) {
Object.keys(restData).forEach(function (attr) {
selectAttrs[attr] = restData[attr]
})

Expand Down Expand Up @@ -904,7 +905,7 @@ const FormBuilder = function(opts, element, $) {
}

// Append the new field to the editor
const appendNewField = function(values, isNew = true) {
const appendNewField = function (values, isNew = true) {
data.lastID = h.incrementId(data.lastID)

const type = values.type || 'text'
Expand Down Expand Up @@ -1012,26 +1013,30 @@ const FormBuilder = function(opts, element, $) {
}

// Select field html, since there may be multiple
const selectFieldOptions = function(optionData, multipleSelect) {
const selectFieldOptions = function (optionData, multipleSelect) {
const optionTemplate = { selected: false, label: '', value: '' }
const optionInputType = {
selected: multipleSelect ? 'checkbox' : 'radio',
}
const optionInputTypeMap = {
boolean: (value, prop) => {
const attrs = {value, type: optionInputType[prop] || 'checkbox'}
const attrs = { value, type: optionInputType[prop] || 'checkbox' }
if (value) {
attrs.checked = !!value
attrs.checked = !!value
}
return['input', null, attrs]
return ['input', null, attrs]
},
number: value => ['input', null, {value, type: 'number'}],
string: (value, prop) => (['input', null, {value, type: 'text', placeholder: mi18n.get(`placeholder.${prop}`) || ''}]),
array: values => ['select', values.map(({label, value}) => m('option', label, {value}))],
object: ({tag, content, ...attrs}) => [tag, content, attrs],
number: value => ['input', null, { value, type: 'number' }],
string: (value, prop) => [
'input',
null,
{ value, type: 'text', placeholder: mi18n.get(`placeholder.${prop}`) || '' },
],
array: values => ['select', values.map(({ label, value }) => m('option', label, { value }))],
object: ({ tag, content, ...attrs }) => [tag, content, attrs],
}

optionData = {...optionTemplate, ...optionData}
optionData = { ...optionTemplate, ...optionData }

const optionInputs = Object.entries(optionData).map(([prop, val]) => {
const optionInputDataType = getContentType(val)
Expand Down Expand Up @@ -1141,7 +1146,7 @@ const FormBuilder = function(opts, element, $) {
})

// toggle fields
$stage.on('click touchstart', '.toggle-form, .close-field', function(e) {
$stage.on('click touchstart', '.toggle-form, .close-field', function (e) {
e.stopPropagation()
e.preventDefault()
if (e.handled !== true) {
Expand Down Expand Up @@ -1217,7 +1222,7 @@ const FormBuilder = function(opts, element, $) {
$stage.on('keyup', 'input.error', ({ target }) => $(target).removeClass('error'))

// update preview for description
$stage.on('keyup', 'input[name="description"]', function(e) {
$stage.on('keyup', 'input[name="description"]', function (e) {
const $field = $(e.target).parents('.form-field:eq(0)')
const closestToolTip = $('.tooltip-element', $field)
const ttVal = $(e.target).val()
Expand Down Expand Up @@ -1248,7 +1253,7 @@ const FormBuilder = function(opts, element, $) {
})

// format name attribute
$stage.on('blur', 'input.fld-name', function(e) {
$stage.on('blur', 'input.fld-name', function (e) {
e.target.value = safename(e.target.value)
if (e.target.value === '') {
$(e.target).addClass('field-error').attr('placeholder', mi18n.get('cannotBeEmpty'))
Expand All @@ -1262,7 +1267,7 @@ const FormBuilder = function(opts, element, $) {
})

// Copy field
$stage.on('click touchstart', `.${css_prefix_text}copy`, function(evt) {
$stage.on('click touchstart', `.${css_prefix_text}copy`, function (evt) {
evt.preventDefault()
const currentItem = $(evt.target).parent().parent('li')
const $clone = cloneItem(currentItem)
Expand All @@ -1287,7 +1292,7 @@ const FormBuilder = function(opts, element, $) {

document.addEventListener(
'modalClosed',
function() {
function () {
$field.removeClass('deleting')
},
false,
Expand Down Expand Up @@ -1323,18 +1328,18 @@ const FormBuilder = function(opts, element, $) {
})

// Attach a callback to toggle roles visibility
$stage.on('click', 'input.fld-access', function(e) {
$stage.on('click', 'input.fld-access', function (e) {
const roles = $(e.target).closest('.form-field').find('.available-roles')
const enableRolesCB = $(e.target)
roles.slideToggle(250, function() {
roles.slideToggle(250, function () {
if (!enableRolesCB.is(':checked')) {
$('input[type=checkbox]', roles).removeAttr('checked')
}
})
})

// Attach a callback to add new options
$stage.on('click', '.add-opt', function(e) {
$stage.on('click', '.add-opt', function (e) {
e.preventDefault()
const type = $(e.target).closest('.form-field').attr('type')
const $optionWrap = $(e.target).closest('.field-options')
Expand All @@ -1350,7 +1355,11 @@ const FormBuilder = function(opts, element, $) {

const optionTemplate = { selected: false, label: '', value: '' }
const $sortableOptions = $('.sortable-options', $optionWrap)
const optionData = config.opts.onAddOption(optionTemplate, {type, index: $sortableOptions.children().length, isMultiple})
const optionData = config.opts.onAddOption(optionTemplate, {
type,
index: $sortableOptions.children().length,
isMultiple,
})
$sortableOptions.append(selectFieldOptions(optionData, isMultiple))
})

Expand Down Expand Up @@ -1394,6 +1403,7 @@ const FormBuilder = function(opts, element, $) {
h.formActionButtons().forEach(button => d.formActions.appendChild(button))
})
},
showDialog: h.dialog.bind(h),
toggleFieldEdit: fieldId => {
const fieldIds = Array.isArray(fieldId) ? fieldId : [fieldId]
fieldIds.forEach(fId => {
Expand Down Expand Up @@ -1452,21 +1462,23 @@ const methods = {
setData: null,
setLang: null,
showData: null,
showDialog: null,
toggleAllFieldEdit: null,
toggleFieldEdit: null,
getCurrentFieldId: null,
},
markup,
get formData() {
return methods.instance.actions.getData && methods.instance.actions.getData('json')
},
promise: new Promise(function(resolve, reject) {
promise: new Promise(function (resolve, reject) {
mi18n
.init(i18nOpts)
.then(() => {
elems.each(i => {
const formBuilder = new FormBuilder(opts, elems[i], jQuery)
jQuery(elems[i]).data('formBuilder', formBuilder)
Object.assign(methods, formBuilder.actions)
Object.assign(methods, formBuilder.actions, { markup })
methods.instance.actions = formBuilder.actions
})
delete methods.instance.promise
Expand All @@ -1483,7 +1495,7 @@ const methods = {
},
}

jQuery.fn.formBuilder = function(methodOrOptions = {}, ...args) {
jQuery.fn.formBuilder = function (methodOrOptions = {}, ...args) {
const isMethod = typeof methodOrOptions === 'string'
if (isMethod) {
if (methods[methodOrOptions]) {
Expand Down
24 changes: 7 additions & 17 deletions src/js/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -647,7 +647,11 @@ export default class Helpers {
i18n.clearAllMessage,
() => {
_this.removeAllFields.call(_this, stage)
config.opts.notify.success(i18n.allFieldsRemoved)
if (config.opts.persistDefaultFields && config.opts.defaultFields) {
this.addDefaultFields()
} else {
config.opts.notify.success(i18n.allFieldsRemoved)
}
config.opts.onClearAll()
},
coords,
Expand All @@ -669,7 +673,7 @@ export default class Helpers {
* @param {Boolean} animate whether to animate or not
* @return {void}
*/
removeAllFields(stage, animate = true) {
removeAllFields(stage) {
const i18n = mi18n.current
const opts = config.opts
const fields = stage.querySelectorAll('li.form-field')
Expand All @@ -692,26 +696,12 @@ export default class Helpers {
stage.dataset.content = i18n.getStarted
}

if (animate) {
stage.classList.add('removing')
let outerHeight = 0
forEach(fields, index => (outerHeight += fields[index].offsetHeight + 3))
fields[0].style.marginTop = `${-outerHeight}px`
}

const animationTimeout = animate ? 400 : 0
const animateTimeout = setTimeout(() => {
this.emptyStage(stage)
clearTimeout(animateTimeout)
}, animationTimeout)
this.emptyStage(stage)
}

emptyStage(stage) {
empty(stage).classList.remove('removing')
this.save()
if (config.opts.persistDefaultFields) {
this.addDefaultFields()
}
}

/**
Expand Down

0 comments on commit 753280f

Please sign in to comment.