diff --git a/src/App.vue b/src/App.vue index 4c8c85b42..71b0c63b4 100644 --- a/src/App.vue +++ b/src/App.vue @@ -33,7 +33,7 @@ - + { if (item.container) { item.items.forEach(containerItems => { + if (!Array.isArray(containerItems)) { + containerItems = [containerItems]; + } validationErrors.push(...this.getValidationErrorsForItems(containerItems, page)); }); } diff --git a/src/components/editor/loop.vue b/src/components/editor/loop.vue new file mode 100644 index 000000000..70b947219 --- /dev/null +++ b/src/components/editor/loop.vue @@ -0,0 +1,194 @@ + + + + + diff --git a/src/components/renderer/form-loop.vue b/src/components/renderer/form-loop.vue new file mode 100644 index 000000000..70444c0a3 --- /dev/null +++ b/src/components/renderer/form-loop.vue @@ -0,0 +1,115 @@ + + + diff --git a/src/components/vue-form-builder.vue b/src/components/vue-form-builder.vue index cdcb99f25..d5780a091 100644 --- a/src/components/vue-form-builder.vue +++ b/src/components/vue-form-builder.vue @@ -269,6 +269,7 @@ import undoRedoModule from '../undoRedoModule'; import accordions from './accordions'; import { keyNameProperty } from '../form-control-common-properties'; import VariableNameGenerator from '@/components/VariableNameGenerator'; +import Loop from './editor/loop'; Vue.use(BootstrapVue); @@ -330,6 +331,7 @@ export default { mixins: [HasColorProperty], components: { draggable, + Loop, FormInput, FormSelectList, FormCheckbox, diff --git a/src/components/vue-form-renderer.vue b/src/components/vue-form-renderer.vue index eb6233bf5..86e7f7296 100644 --- a/src/components/vue-form-renderer.vue +++ b/src/components/vue-form-renderer.vue @@ -52,6 +52,7 @@ import * as editor from './editor'; import * as renderer from './renderer'; import * as inspector from './inspector'; import FormMultiColumn from '@/components/renderer/form-multi-column'; +import FormLoop from '@/components/renderer/form-loop'; import FormMaskedInput from '@/components/renderer/form-masked-input'; import CustomCSS from './custom-css'; import { @@ -99,6 +100,7 @@ export default { FormHtmlViewer, FormMultiColumn, CustomCSS, + FormLoop, ...editor, ...inspector, ...renderer, diff --git a/src/form-builder-controls.js b/src/form-builder-controls.js index acfb51eec..b64959efb 100644 --- a/src/form-builder-controls.js +++ b/src/form-builder-controls.js @@ -1,6 +1,8 @@ import FormText from './components/renderer/form-text'; import FormButton from './components/renderer/form-button'; import FormMultiColumn from './components/renderer/form-multi-column'; +import FormLoop from './components/renderer/form-loop'; +import Loop from './components/editor/loop'; import FormRecordList from './components/renderer/form-record-list'; import FormImage from './components/renderer/form-image'; import FormMaskedInput from './components/renderer/form-masked-input'; @@ -346,6 +348,36 @@ export default [ ], }, }, + { + editorComponent: Loop, + editorBinding: 'Loop', + rendererComponent: FormLoop, + rendererBinding: 'FormLoop', + control: { + label: 'Loop', + component: 'FormLoop', + 'editor-component': 'Loop', + 'editor-control': 'Loop', + container: true, + // Default items container + items: [], + config: { + icon: 'fas fa-redo', + times: '2', + }, + inspector: [ + keyNameProperty, + { + type: 'FormInput', + field: 'times', + config: { + label: 'Number of times', + helper: 'Enter the number of times to repeat the element(s)', + }, + }, + ], + }, + }, { editorComponent: FormText, editorBinding: 'FormText',