diff --git a/src/lib/js/components/component.js b/src/lib/js/components/component.js index d8237af..ec8deac 100644 --- a/src/lib/js/components/component.js +++ b/src/lib/js/components/component.js @@ -20,9 +20,10 @@ import { get, set } from '../common/utils/object.mjs' import { toTitleCase } from '../common/utils/string.mjs' export default class Component extends Data { - constructor(name, data = {}, render) { - super(name, { ...data, id: data.id || uuid() }) - this.id = this.data.id + constructor(name, dataArg = {}, render) { + const data = { ...dataArg, id: dataArg.id || uuid() } + super(name, data) + this.id = data.id this.name = name this.config = Components[`${this.name}s`].config merge(this.config, data.config) @@ -96,8 +97,9 @@ export default class Component extends Data { * @return {Object} parent element */ empty() { - const removed = this.children.map(child => child.remove()) - this.data.children = this.data.children.filter(childId => removed.indexOf(childId) === -1) + const removed = this.children.map(child => { + child.remove() + }) this.dom.classList.add('empty') return removed } diff --git a/src/lib/js/components/data.js b/src/lib/js/components/data.js index 4abda6a..1555716 100644 --- a/src/lib/js/components/data.js +++ b/src/lib/js/components/data.js @@ -84,7 +84,7 @@ export default class Data { const parent = this.get(delPath) if (Array.isArray(parent)) { parent.splice(Number(delItem), 1) - } else { + } else if (parent) { delete parent[delItem] } return parent diff --git a/src/lib/js/components/index.js b/src/lib/js/components/index.js index bc8e72b..25dc234 100644 --- a/src/lib/js/components/index.js +++ b/src/lib/js/components/index.js @@ -1,5 +1,5 @@ import Data from './data.js' -import { uuid, sessionStorage, isAddress } from '../common/utils/index.mjs' +import { uuid, sessionStorage, isAddress, parseData, clone } from '../common/utils/index.mjs' import ControlsData from './controls/index.js' import StagesData from './stages/index.js' @@ -16,15 +16,28 @@ export const Fields = FieldsData export const Controls = ControlsData export const Externals = ExternalsData -const DEFAULT_DATA = { +const defaultFormData = () => ({ id: uuid(), + stages: { [uuid()]: {} }, + rows: {}, + columns: {}, + fields: {}, +}) + +const getFormData = (formData, useSessionStorage = false) => { + if (formData) { + return clone(parseData(formData)) + } + if (useSessionStorage) { + return sessionStorage.get(SESSION_FORMDATA_KEY) || defaultFormData() + } + + return defaultFormData() } export class Components extends Data { - constructor(opts) { + constructor() { super('components') - this.opts = opts - this.data = DEFAULT_DATA this.disableEvents = true this.stages = Stages this.rows = Rows @@ -34,26 +47,18 @@ export class Components extends Data { this.externals = Externals } - sessionFormData = () => { - if (this.opts?.sessionStorage) { - return sessionStorage.get(SESSION_FORMDATA_KEY) - } - } - - load = (formDataArg, opts = this.opts || Object.create(null)) => { - let formData = formDataArg + load = (formDataArg, opts) => { this.empty() - if (typeof formDataArg === 'string') { - formData = JSON.parse(formDataArg) - } + const formData = getFormData(formDataArg, opts.sessionStorage) + this.opts = opts - const { stages = { [uuid()]: {} }, rows, columns, fields, id = uuid() } = { ...this.sessionFormData(), ...formData } - this.set('id', id) - this.add('stages', Stages.load(stages)) - this.add('rows', Rows.load(rows)) - this.add('columns', Columns.load(columns)) - this.add('fields', Fields.load(fields)) - this.add('externals', Externals.load(opts.external)) + + this.set('id', formData.id) + this.add('stages', Stages.load(formData.stages)) + this.add('rows', Rows.load(formData.rows)) + this.add('columns', Columns.load(formData.columns)) + this.add('fields', Fields.load(formData.fields)) + this.add('externals', Externals.load(this.opts.external)) for (const stage of Object.values(this.get('stages'))) { stage.loadChildren() diff --git a/src/lib/js/renderer.js b/src/lib/js/renderer.js index d0704ae..d5b1489 100644 --- a/src/lib/js/renderer.js +++ b/src/lib/js/renderer.js @@ -1,18 +1,18 @@ import isEqual from 'lodash/isEqual' import dom from './common/dom' -import { uuid, isAddress, isExternalAddress, merge } from './common/utils' +import { uuid, isAddress, isExternalAddress, merge, parseData, clone } from './common/utils/index.mjs' import { STAGE_CLASSNAME, UUID_REGEXP } from './constants' import { fetchDependencies } from './common/loaders' -import { parseData } from './common/utils/index.mjs' const RENDER_PREFIX = 'f-' +const cleanFormData = formData => (formData ? clone(parseData(formData)) : {}) const containerLookup = container => (typeof container === 'string' ? document.querySelector(container) : container) const processOptions = ({ editorContainer, renderContainer, formData, ...opts }) => { const processedOptions = { renderContainer: containerLookup(renderContainer), editorContainer: containerLookup(editorContainer), - formData: parseData(formData) || {}, + formData: cleanFormData(formData), } return { elements: {}, ...opts, ...processedOptions } @@ -42,7 +42,7 @@ export default class FormeoRenderer { constructor(opts, formDataArg) { const { renderContainer, external, elements, formData } = processOptions(opts) this.container = renderContainer - this.form = parseData(formDataArg || formData) + this.form = cleanFormData(formDataArg || formData) this.external = external this.dom = dom this.components = Object.create(null) @@ -54,7 +54,7 @@ export default class FormeoRenderer { * @param {Object} formData */ render = (formData = this.form) => { - this.form = parseData(formData) + this.form = cleanFormData(formData) const renderCount = document.getElementsByClassName('formeo-render').length const config = {