\")\n\n $fieldDiv.append(\n this.generateFieldName(fieldName),\n this.generateIncrementable(fieldName)\n )\n\n this.$renderer.append($fieldDiv)\n }\n\n renderLicensePlateField (fieldName) {\n const $fieldDiv = $(\"
\")\n\n $fieldDiv.append(\n this.generateFieldName(fieldName),\n this.generateTextInput(fieldName, 'AA00AA')\n )\n\n this.$renderer.append($fieldDiv)\n }\n\n /* FIELD GENERATORS */\n generateFieldName (fieldName) {\n const fieldRequired = this.options.schema.required.includes(fieldName)\n return $(`
`)\n }\n\n generateTextInput (fieldName, placeholder) {\n const $placeholder = placeholder != null ? `placeholder=${placeholder}` : ''\n const $errorClass = this.options.errors[fieldName] ? 'form-control is-invalid' : 'form-control'\n const $textInput = $('
')\n\n this.setNameAttr($textInput, fieldName)\n this.setValueAttr($textInput, fieldName)\n\n const $error = this.generateError(fieldName)\n\n return [$textInput, $error]\n }\n\n generateSelect (fieldName, fieldEnum) {\n const $select = $(\n `
`\n )\n\n this.setNameAttr($select, fieldName)\n this.setValueAttr($select, fieldName)\n\n return [$select]\n }\n\n generateCheckbox (fieldName) {\n const text = this.options.schema.properties[fieldName].text\n const errorClass = this.options.errors[fieldName] ? 'form-control is-invalid' : 'form-control'\n\n const $label = $('
')\n const $checkbox = $(`
`)\n const $checkboxIndicator = $('
')\n const $name = $(`
${text}
`)\n const $error = this.generateError(fieldName)\n\n this.setNameAttr($checkbox, fieldName)\n this.setValueAttr($checkbox, fieldName)\n\n $label.append([$checkbox, $checkboxIndicator, $name, $error])\n\n return $label\n }\n\n generateMultipleCheckbox (fieldName, fieldEnum) {\n return fieldEnum.map((option) => {\n const $label = $('
')\n const $checkbox = $(`
`)\n const $option = $(`
${option}
`)\n const $indicator = $('
')\n\n this.setNameAttr($checkbox, fieldName, true)\n this.setValueAttr($checkbox, fieldName)\n\n $label.append([$checkbox, $option, $indicator])\n\n return $label\n })\n }\n\n generateDate (fieldName) {\n const $errorClass = this.options.errors[fieldName] ? 'form-control is-invalid' : 'form-control'\n const today = moment().format('YYYY-MM-DD')\n const $dateWrapper = $('
')\n const $dateInput = $(`
`)\n\n $dateInput.datetimepicker({\n locale: 'pt',\n format: 'YYYY-MM-DD',\n icons: {\n next: 'fa fa-chevron-right',\n previous: 'fa fa-chevron-left'\n }\n })\n\n this.setNameAttr($dateInput, fieldName)\n this.setValueAttr($dateInput, fieldName)\n\n $dateWrapper.append($dateInput)\n const $error = this.generateError(fieldName)\n\n return [$dateWrapper, $error]\n }\n\n generateRadios (fieldName, fieldEnum) {\n return fieldEnum.map((option, i) => {\n const $label = $('
')\n const $option = $(``)\n const $radioInput = $(`
`)\n const $indicator = $('
')\n\n this.setNameAttr($radioInput, fieldName)\n this.setValueAttr($radioInput, fieldName)\n\n $label.append([$option, $radioInput, $indicator])\n\n return $label\n })\n }\n\n generateIncrementable (fieldName) {\n const $errorClass = this.options.errors[fieldName] ? 'form-control is-invalid' : 'form-control'\n const $numberInput = $(`
`)\n\n this.setNameAttr($numberInput, fieldName)\n this.setValueAttr($numberInput, fieldName)\n\n const $error = this.generateError(fieldName)\n\n return [$numberInput, $error]\n }\n\n generateError (fieldName) {\n const errorMessage = (this.options.errors[fieldName] || []).join(', ').capitalize()\n return $(`
${errorMessage}
`)\n }\n}\n","import { CREATOR } from './constants.js.erb'\n\nexport default class Creator {\n constructor (formSelector, previewRenderer = null) {\n this.$form = $(formSelector).first()\n this.$addFieldButton = this.$form.find(\"[dynamic-form-creator='add_field']\").first()\n this.$fieldsWorkshop = this.$form.find(\"[dynamic-form-creator='fields_workshop']\").first()\n this.$schema = this.$form.find(\"[dynamic-form-creator='schema']\").first()\n this.previewRenderer = previewRenderer\n this.collapsedState = {}\n this.tinymceSelectors = {}\n\n const schema = this.$schema.val()\n this.schema = schema ? JSON.parse(schema) : CREATOR.DEFAULT_SCHEMA\n\n const sortedEntries = Object.entries(this.schema.properties).sort((a, b) => a[1].position - b[1].position)\n this.schema.properties = Object.fromEntries(sortedEntries)\n\n this.renderFieldByTypeObject = {\n [CREATOR.FIELD_TYPE_TEXT]: this.renderSingleValueField.bind(this),\n [CREATOR.FIELD_TYPE_SELECT]: this.renderMultiValueField.bind(this),\n [CREATOR.FIELD_TYPE_SINGLE_CHECKBOX]: this.renderSingleValueField.bind(this),\n [CREATOR.FIELD_TYPE_MULTIPLE_CHECKBOX]: this.renderMultiValueField.bind(this),\n [CREATOR.FIELD_TYPE_DATE]: this.renderSingleValueField.bind(this),\n [CREATOR.FIELD_TYPE_RADIO]: this.renderMultiValueField.bind(this),\n [CREATOR.FIELD_TYPE_INCREMENTABLE]: this.renderSingleValueField.bind(this),\n [CREATOR.FIELD_TYPE_LICENSE_PLATE]: this.renderSingleValueField.bind(this)\n }\n }\n\n setup () {\n this.$addFieldButton.get(0).onmouseup = this.addField.bind(this)\n Object.keys(this.schema.properties).length ? this.render() : this.addField()\n }\n\n sortPropertiesByPosition (callback = null) {\n let entries = Object.entries(this.schema.properties).sort((a, b) => a[1].position - b[1].position)\n if (callback) entries = callback(entries)\n this.schema.properties = Object.fromEntries(entries)\n }\n\n setGlobalCollapseState (state) {\n Object.keys(this.collapsedState).forEach((fieldName) => {\n if (fieldName !== '') this.collapsedState[fieldName] = state\n })\n }\n\n toggleFieldCollapseState (fieldName, $toggle) {\n const $content = $toggle.parents('.dyn-form').find('.dyn-form__content')\n const $arrow = $toggle.find('.rotate')\n\n $content.slideToggle('fast')\n $arrow.toggleClass('down')\n\n this.collapsedState[fieldName] = $arrow.hasClass('down')\n }\n\n getFieldEnum (fieldName) {\n if (this.schema.properties[fieldName].type === 'array') {\n return this.schema.properties[fieldName].items.enum\n } else {\n return this.schema.properties[fieldName].enum\n }\n }\n\n setFieldEnum (fieldName, newEnum) {\n const enumSet = new Set(newEnum)\n\n if (this.schema.properties[fieldName].type === 'array') {\n this.schema.properties[fieldName].items.enum = [...enumSet]\n } else {\n this.schema.properties[fieldName].enum = [...enumSet]\n }\n }\n\n /* ADD FIELD */\n addField () {\n this.schema.properties[''] = {\n ...FIELD_TYPE_SCHEMA_OBJECT[CREATOR.FIELD_TYPE_TEXT]\n }\n this.schema.properties[''].position = Object.keys(this.schema.properties).length - 1\n this.setGlobalCollapseState(true)\n this.render()\n }\n\n addSelectFieldOption (fieldName) {\n const enums = this.getFieldEnum(fieldName)\n enums.push('')\n\n this.setFieldEnum(fieldName, enums)\n this.render()\n }\n\n /* UPDATE FIELD */\n updateFieldName (oldFieldName, $fieldNameInput) {\n const newFieldName = $fieldNameInput.val()\n\n this.schema.properties[newFieldName] = {\n ...this.schema.properties[oldFieldName]\n }\n\n if (oldFieldName !== newFieldName) {\n delete this.schema.properties[oldFieldName]\n\n if (this.schema.required.includes(oldFieldName)) {\n this.schema.required.splice(this.schema.required.indexOf(oldFieldName), 1, newFieldName)\n }\n }\n\n this.setGlobalCollapseState(true)\n this.collapsedState[newFieldName] = false\n\n this.render()\n }\n\n updateFieldType ($event, fieldName) {\n const newFieldType = $($event.target).val()\n this.schema.properties[fieldName] = {\n ...FIELD_TYPE_SCHEMA_OBJECT[newFieldType]\n }\n if (newFieldType === CREATOR.FIELD_TYPE_SINGLE_CHECKBOX) {\n this.schema.properties[fieldName].text = ''\n }\n this.render()\n }\n\n updateFieldRequired (fieldName, $fieldRequiredCheckbox) {\n const required = $fieldRequiredCheckbox.is(':checked')\n\n if (required) {\n this.schema.required.push(fieldName)\n } else {\n this.schema.required.splice(this.schema.required.indexOf(fieldName), 1)\n }\n\n switch (this.schema.properties[fieldName].type) {\n case 'array':\n this.schema.properties[fieldName].minItems = required ? 1 : 0\n break\n\n default:\n this.schema.properties[fieldName].minLength = required ? 1 : 0\n break\n }\n\n this.render()\n }\n\n updateSelectFieldOptionName (fieldName, oldOptionName, $optionNameInput) {\n const enums = this.getFieldEnum(fieldName)\n this.setFieldEnum(fieldName, enums.map((e) => (e === oldOptionName ? $optionNameInput.val() : e)))\n this.render()\n }\n\n updateText (fieldName, newText) {\n if (tinyMCE.activeEditor) {\n newText = tinyMCE.activeEditor.getContent()\n }\n this.schema.properties[fieldName].text = newText\n this.render()\n }\n\n /* REMOVE FIELD */\n removeField (fieldName) {\n delete this.schema.properties[fieldName]\n this.schema.required.splice(this.schema.required.indexOf(fieldName), 1)\n\n this.render()\n }\n\n removeSelectFieldOption (fieldName, option) {\n const enums = this.getFieldEnum(fieldName)\n this.setFieldEnum(fieldName, enums.filter((e) => e !== option))\n this.render()\n }\n\n /* RENDERERS */\n render (sortCallback = null) {\n this.sortPropertiesByPosition(sortCallback)\n this.$schema.val(JSON.stringify(this.schema))\n this.renderFieldsWorkshop()\n this.renderPreview()\n }\n\n renderPreview () {\n if (this.previewRenderer) {\n this.previewRenderer.updateSchema(this.schema)\n this.previewRenderer.render()\n }\n }\n\n renderSingleValueField (fieldName) {\n const $fieldDiv = $('
')\n\n /* TOP */\n const $fieldTop = $('
')\n $fieldDiv.append($fieldTop)\n\n /* TOP - SIDEBAR */\n const $fieldSidebar = $('