327 lines
9.3 KiB
Vue
327 lines
9.3 KiB
Vue
<template>
|
|
<div class="min-h-screen bg-gray-100 flex flex-row items-start p-4">
|
|
<div class="flex-col flex-1 items-center justify-center p-4">
|
|
<h2 class="text-xl font-bold mb-4">Form Builder</h2>
|
|
<div>
|
|
<DynamicForm
|
|
class="space-y-2 p-6 bg-white shadow-lg rounded-lg max-w-md"
|
|
:formInputs="formBuilderPropertiesInputs"
|
|
@send="handleFormPropertiesSubmit"
|
|
form-title="Form Properties"
|
|
submit-label="Update Form"
|
|
/>
|
|
</div>
|
|
<div class="mt-6">
|
|
<DynamicForm
|
|
class="space-y-2 p-6 bg-white shadow-lg rounded-lg max-w-md"
|
|
:formInputs="formBuilderFieldInputs"
|
|
@send="handleFormBuilderSubmit"
|
|
form-title="Add a new field"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div v-if="generatedFormInputs.length" class="flex-col flex-1 items-center justify-center p-4">
|
|
<h2 class="text-xl font-bold mb-4">Generated Form</h2>
|
|
<DynamicForm
|
|
class="space-y-2 p-6 bg-white shadow-lg rounded-lg max-w-md"
|
|
:formInputs="generatedFormInputs"
|
|
:submitLabel="submitLabel"
|
|
:formTitle="formTitle"
|
|
@edit="handleEditRequest"
|
|
@delete="handleDeleteRequest"
|
|
@move-up="handleMoveUp"
|
|
@move-down="handleMoveDown"
|
|
:is-editing="showEditOption"
|
|
/>
|
|
<button
|
|
@click.prevent="showEditOption = !showEditOption"
|
|
class="px-2 py-1 bg-gray-200 text-black font-semibold rounded-md shadow-md hover:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-gray-300 mt-4">preview: {{showEditOption ? 'off' : 'on'}}</button>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import { ref } from 'vue';
|
|
import DynamicForm from './DynamicForm.vue';
|
|
import type {FormInput} from "@/components/DynamicForm.vue";
|
|
|
|
const formBuilderPropertiesInputs = ref<FormInput[]>([
|
|
{
|
|
id: 'formTitle',
|
|
label: 'Form Title',
|
|
type: 'text',
|
|
required: false
|
|
},
|
|
{
|
|
id: 'formDescription',
|
|
label: 'Form Description',
|
|
type: 'textarea',
|
|
required: false
|
|
},
|
|
{
|
|
id: 'submitLabel',
|
|
label: 'Submit Button Label',
|
|
type: 'text',
|
|
required: false
|
|
}
|
|
]);
|
|
|
|
const formTitle = ref('');
|
|
const formDescription = ref('');
|
|
const submitLabel = ref('');
|
|
const showEditOption = ref(true);
|
|
|
|
const formBuilderFieldInputs = ref<FormInput[]>([
|
|
{
|
|
id: 'fieldType',
|
|
label: 'Field Type',
|
|
type: 'select',
|
|
required: true,
|
|
options: [
|
|
{ label: 'Text', value: 'text' },
|
|
{ label: 'Email', value: 'email' },
|
|
{ label: 'Password', value: 'password' },
|
|
{ label: 'Number', value: 'number' },
|
|
{ label: 'Textarea', value: 'textarea' },
|
|
{ label: 'Select', value: 'select' },
|
|
{ label: 'Radio', value: 'radio' },
|
|
{ label: 'Checkbox', value: 'checkbox' },
|
|
{ label: 'Multi-Input', value: 'multi-input' },
|
|
{ label: 'URL', value: 'url' },
|
|
{ label: 'Telephone', value: 'tel' },
|
|
{ label: 'Search', value: 'search' },
|
|
{ label: 'Color', value: 'color' },
|
|
{ label: 'Date', value: 'date' },
|
|
{ label: 'Datetime-local', value: 'datetime-local' },
|
|
{ label: 'Month', value: 'month' },
|
|
{ label: 'Time', value: 'time' },
|
|
{ label: 'Week', value: 'week' },
|
|
{ label: 'Description', value: 'description' }
|
|
]
|
|
},
|
|
{
|
|
id: 'fieldLabel',
|
|
label: 'Field Label',
|
|
type: 'text',
|
|
required: true
|
|
},
|
|
{
|
|
id: 'fieldID',
|
|
label: 'Field ID',
|
|
type: 'text',
|
|
required: true
|
|
},
|
|
{
|
|
id: 'placeholder',
|
|
label: 'Placeholder',
|
|
type: 'text',
|
|
required: false
|
|
},
|
|
{
|
|
id: 'required',
|
|
label: 'Required',
|
|
type: 'checkbox',
|
|
required: false,
|
|
showLabel: false,
|
|
options: [{ label: 'Required', value: 'true' }]
|
|
},
|
|
{
|
|
id: 'showLabel',
|
|
label: 'Show Label',
|
|
type: 'checkbox',
|
|
required: false,
|
|
showLabel: false,
|
|
defaultValue: ['true'],
|
|
options: [{ label: 'Show Label', value: 'true' }]
|
|
},
|
|
{
|
|
id: 'defaultValue',
|
|
label: 'Default Value',
|
|
type: 'text',
|
|
required: false
|
|
},
|
|
{
|
|
id: 'min',
|
|
label: 'Min (for Number, Date, etc.)',
|
|
type: 'text',
|
|
required: false
|
|
},
|
|
{
|
|
id: 'max',
|
|
label: 'Max (for Number, Date, etc.)',
|
|
type: 'text',
|
|
required: false
|
|
},
|
|
{
|
|
id: 'options',
|
|
label: 'Options (for Select, Radio, Checkbox)',
|
|
type: 'multi-input',
|
|
required: false
|
|
}
|
|
]);
|
|
|
|
const defaultFormInput: FormInput = {
|
|
id: '',
|
|
label: '',
|
|
type: '',
|
|
required: false,
|
|
showLabel: true
|
|
};
|
|
|
|
const generatedFormInputs = ref<FormInput[]>([]);
|
|
|
|
const handleFormPropertiesSubmit = (formData: Record<string, any>) => {
|
|
formTitle.value = formData.formTitle;
|
|
formDescription.value = formData.formDescription;
|
|
submitLabel.value = formData.submitLabel;
|
|
};
|
|
|
|
const handleEditRequest = (inputToEdit: FormInput) => {
|
|
// set formBuilderFieldInputs to the input values
|
|
console.log(inputToEdit);
|
|
formBuilderFieldInputs.value.forEach((input: FormInput, i) => {
|
|
// fieldtype
|
|
if (input.id === 'fieldType') {
|
|
input.defaultValue = inputToEdit.type;
|
|
}
|
|
// fieldlabel
|
|
if (input.id === 'fieldLabel') {
|
|
input.defaultValue = inputToEdit.label;
|
|
}
|
|
// fieldid
|
|
if (input.id === 'fieldID') {
|
|
input.defaultValue = inputToEdit.id;
|
|
}
|
|
// placeholder
|
|
if (input.id === 'placeholder') {
|
|
input.defaultValue = inputToEdit.placeholder;
|
|
}
|
|
// required
|
|
if (input.id === 'required') {
|
|
input.defaultValue = inputToEdit.required ? ['true'] : [];
|
|
}
|
|
// showlabel
|
|
if (input.id === 'showLabel') {
|
|
input.defaultValue = inputToEdit.showLabel ? ['true'] : [];
|
|
}
|
|
// defaultvalue
|
|
if (input.id === 'defaultValue') {
|
|
input.defaultValue = inputToEdit.defaultValue;
|
|
}
|
|
// min
|
|
if (input.id === 'min') {
|
|
input.defaultValue = inputToEdit.min;
|
|
}
|
|
// max
|
|
if (input.id === 'max') {
|
|
input.defaultValue = inputToEdit.max;
|
|
}
|
|
// options
|
|
if (input.id === 'options') {
|
|
input.defaultValue = inputToEdit.options ? inputToEdit.options.map(opt => opt.value) : [];
|
|
}
|
|
});
|
|
};
|
|
|
|
const handleDeleteRequest = (inputID: string) => {
|
|
const index = generatedFormInputs.value.findIndex(input => input.id === inputID);
|
|
if (index > -1) {
|
|
generatedFormInputs.value.splice(index, 1);
|
|
}
|
|
};
|
|
|
|
const handleMoveUp = (inputID: string) => {
|
|
const index = generatedFormInputs.value.findIndex(input => input.id === inputID);
|
|
if (index > 0) {
|
|
const temp = generatedFormInputs.value[index];
|
|
generatedFormInputs.value[index] = generatedFormInputs.value[index - 1];
|
|
generatedFormInputs.value[index - 1] = temp;
|
|
}
|
|
};
|
|
|
|
const handleMoveDown = (inputID: string) => {
|
|
const index = generatedFormInputs.value.findIndex(input => input.id === inputID);
|
|
if (index < generatedFormInputs.value.length - 1) {
|
|
const temp = generatedFormInputs.value[index];
|
|
generatedFormInputs.value[index] = generatedFormInputs.value[index + 1];
|
|
generatedFormInputs.value[index + 1] = temp;
|
|
}
|
|
};
|
|
|
|
const handleFormBuilderSubmit = (formData: Record<string, any>) => {
|
|
const newField: FormInput = {
|
|
id: formData.fieldID,
|
|
label: formData.fieldLabel,
|
|
type: formData.fieldType,
|
|
placeholder: formData.placeholder || undefined,
|
|
required: formData.required && formData.required.includes('true'),
|
|
showLabel: formData.showLabel && formData.showLabel.includes('true'),
|
|
defaultValue: formData.defaultValue || undefined,
|
|
min: formData.min || undefined,
|
|
max: formData.max || undefined,
|
|
options: formData.options ? formData.options.map((opt: string) => ({ label: opt, value: opt })) : undefined
|
|
};
|
|
|
|
// if field id already exists, replace the previous field otherwise add the new field
|
|
const existingFieldIndex = generatedFormInputs.value.findIndex(field => field.id === newField.id);
|
|
if (existingFieldIndex > -1) {
|
|
generatedFormInputs.value.splice(existingFieldIndex, 1, newField);
|
|
} else {
|
|
generatedFormInputs.value.push(newField);
|
|
}
|
|
|
|
// Reset form builder fields
|
|
resetBuilderFields();
|
|
};
|
|
|
|
function resetBuilderFields() {
|
|
formBuilderFieldInputs.value.forEach((input: FormInput, i) => {
|
|
// fieldtype
|
|
if (input.id === 'fieldType') {
|
|
input.defaultValue = defaultFormInput.type;
|
|
}
|
|
// fieldlabel
|
|
if (input.id === 'fieldLabel') {
|
|
input.defaultValue = defaultFormInput.label;
|
|
}
|
|
// fieldid
|
|
if (input.id === 'fieldID') {
|
|
input.defaultValue = defaultFormInput.id;
|
|
}
|
|
// placeholder
|
|
if (input.id === 'placeholder') {
|
|
input.defaultValue = defaultFormInput.placeholder;
|
|
}
|
|
// required
|
|
if (input.id === 'required') {
|
|
input.defaultValue = defaultFormInput.required ? ['true'] : [];
|
|
}
|
|
// showlabel
|
|
if (input.id === 'showLabel') {
|
|
input.defaultValue = defaultFormInput.showLabel ? ['true'] : [];
|
|
}
|
|
// defaultvalue
|
|
if (input.id === 'defaultValue') {
|
|
input.defaultValue = defaultFormInput.defaultValue;
|
|
}
|
|
// min
|
|
if (input.id === 'min') {
|
|
input.defaultValue = defaultFormInput.min;
|
|
}
|
|
// max
|
|
if (input.id === 'max') {
|
|
input.defaultValue = defaultFormInput.max;
|
|
}
|
|
// options
|
|
if (input.id === 'options') {
|
|
input.defaultValue = defaultFormInput.options ? defaultFormInput.options.map(opt => opt.value) : [];
|
|
}
|
|
});
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
/* Add any additional styling if needed */
|
|
</style>
|