Enhance Default Value Handling in Form Builder Components
- Updated ComponentPreview.vue to initialize default values for standard input fields based on the component's defaultValue property, improving user experience during form previews. - Enhanced FormBuilderFieldSettingsModal.vue by introducing a Default Value field, allowing users to set initial values for various input types, with appropriate help texts and placeholders for better guidance. - Implemented helper functions to determine the visibility and type of the Default Value field based on the component type, ensuring consistent behavior across supported input types.
This commit is contained in:
parent
2b322c38c6
commit
b72bf2f89c
@ -933,6 +933,22 @@ onUnmounted(() => {
|
||||
|
||||
// Initialize data for components
|
||||
onMounted(() => {
|
||||
// Initialize default values for standard input fields
|
||||
if (isInputType.value && props.component.props.name && props.isPreview) {
|
||||
const fieldName = props.component.props.name;
|
||||
const currentValue = safeGetField(fieldName, formStore.previewFormData, { warn: false });
|
||||
|
||||
// If field doesn't have a value yet and has a defaultValue, set it
|
||||
if ((currentValue === undefined || currentValue === null || currentValue === '') &&
|
||||
props.component.props.defaultValue !== undefined &&
|
||||
props.component.props.defaultValue !== null) {
|
||||
nextTick(() => {
|
||||
const updatedData = { ...formStore.previewFormData, [fieldName]: props.component.props.defaultValue };
|
||||
formStore.updatePreviewFormData(updatedData);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize search and selection data for dynamic lists
|
||||
if (props.component.type === 'dynamic-list') {
|
||||
const listName = props.component.props.name;
|
||||
@ -983,7 +999,7 @@ onMounted(() => {
|
||||
|
||||
// If this component has a name, add it to the group
|
||||
if (comp.props && comp.props.name) {
|
||||
newGroup[comp.props.name] = getDefaultValueForType(comp.type);
|
||||
newGroup[comp.props.name] = getDefaultValueForType(comp.type, comp);
|
||||
}
|
||||
|
||||
// Handle layout grid components
|
||||
@ -1093,7 +1109,7 @@ watch(() => props.component.props.minItems, (newMinItems, oldMinItems) => {
|
||||
|
||||
// If this component has a name, add it to the group
|
||||
if (comp.props && comp.props.name) {
|
||||
newGroup[comp.props.name] = getDefaultValueForType(comp.type);
|
||||
newGroup[comp.props.name] = getDefaultValueForType(comp.type, comp);
|
||||
}
|
||||
|
||||
// Handle layout grid components
|
||||
@ -1592,12 +1608,17 @@ const getFieldValue = (component) => {
|
||||
}
|
||||
}
|
||||
|
||||
// Check for defaultValue property first
|
||||
if (component.props.defaultValue !== undefined && component.props.defaultValue !== null) {
|
||||
return component.props.defaultValue;
|
||||
}
|
||||
|
||||
// For select fields, return first option value as default if no form data exists
|
||||
if (component.type === 'select' && component.props.options && component.props.options.length > 0) {
|
||||
return component.props.options[0].value || '';
|
||||
}
|
||||
|
||||
// Return component default value if no form data exists
|
||||
// Return component value property if no default value exists
|
||||
return component.props.value || '';
|
||||
};
|
||||
|
||||
@ -1659,6 +1680,11 @@ const getRepeatingGroupFieldValue = (group, fieldName, fieldType, component = nu
|
||||
|
||||
// Helper function to get default values based on field type
|
||||
const getDefaultValueForType = (fieldType, component = null) => {
|
||||
// First check if component has a defaultValue property
|
||||
if (component && component.props && component.props.defaultValue !== undefined) {
|
||||
return component.props.defaultValue;
|
||||
}
|
||||
|
||||
switch (fieldType) {
|
||||
case 'number':
|
||||
return 0;
|
||||
@ -1687,12 +1713,8 @@ const addRepeatingGroupItem = (groupName, children) => {
|
||||
|
||||
// If this component has a name, add it to the item
|
||||
if (comp.props && comp.props.name) {
|
||||
// Use the same default value logic as getDefaultValueForType
|
||||
if (comp.type === 'select' && comp.props.options && comp.props.options.length > 0) {
|
||||
newItem[comp.props.name] = comp.props.options[0].value || '';
|
||||
} else {
|
||||
newItem[comp.props.name] = getDefaultValueForType(comp.type);
|
||||
}
|
||||
// Use the getDefaultValueForType function with the component
|
||||
newItem[comp.props.name] = getDefaultValueForType(comp.type, comp);
|
||||
}
|
||||
|
||||
// Handle layout grid components
|
||||
|
@ -280,6 +280,20 @@
|
||||
rows="2"
|
||||
/>
|
||||
|
||||
<!-- Default Value Field -->
|
||||
<FormKit
|
||||
v-if="showDefaultValueField()"
|
||||
:type="getDefaultValueFieldType()"
|
||||
label="Default Value"
|
||||
name="defaultValue"
|
||||
v-model="configModel.defaultValue"
|
||||
:help="getDefaultValueHelp()"
|
||||
:classes="{ outer: 'field-wrapper' }"
|
||||
:placeholder="getDefaultValuePlaceholder()"
|
||||
:options="component.type === 'select' || component.type === 'radio' || component.type === 'checkbox' ? configModel.options : undefined"
|
||||
:rows="component.type === 'textarea' ? 2 : undefined"
|
||||
/>
|
||||
|
||||
<FormKit
|
||||
v-if="showField('rows')"
|
||||
type="number"
|
||||
@ -3329,6 +3343,85 @@ const isTextBasedField = computed(() => {
|
||||
return ['text', 'textarea', 'email', 'password', 'url', 'tel'].includes(props.component?.type)
|
||||
})
|
||||
|
||||
// Default Value Field Helpers
|
||||
const showDefaultValueField = () => {
|
||||
if (!props.component) return false
|
||||
|
||||
// List of components that support default values
|
||||
const supportedTypes = [
|
||||
'text', 'textarea', 'number', 'email', 'password', 'url', 'tel',
|
||||
'mask', 'select', 'searchSelect', 'checkbox', 'radio', 'switch',
|
||||
'date', 'time', 'datetime-local', 'range', 'color', 'hidden'
|
||||
]
|
||||
|
||||
return supportedTypes.includes(props.component.type)
|
||||
}
|
||||
|
||||
const getDefaultValueFieldType = () => {
|
||||
if (!props.component) return 'text'
|
||||
|
||||
const fieldTypeMap = {
|
||||
'text': 'text',
|
||||
'textarea': 'textarea',
|
||||
'number': 'number',
|
||||
'email': 'email',
|
||||
'password': 'text',
|
||||
'url': 'url',
|
||||
'tel': 'tel',
|
||||
'mask': 'text',
|
||||
'select': 'select',
|
||||
'searchSelect': 'select',
|
||||
'checkbox': 'checkbox',
|
||||
'radio': 'select',
|
||||
'switch': 'switch',
|
||||
'date': 'date',
|
||||
'time': 'time',
|
||||
'datetime-local': 'datetime-local',
|
||||
'range': 'number',
|
||||
'color': 'color',
|
||||
'hidden': 'text'
|
||||
}
|
||||
|
||||
return fieldTypeMap[props.component.type] || 'text'
|
||||
}
|
||||
|
||||
const getDefaultValueHelp = () => {
|
||||
if (!props.component) return 'Initial value when the form loads'
|
||||
|
||||
const helpTexts = {
|
||||
'select': 'Choose the default selected option',
|
||||
'searchSelect': 'Choose the default selected option',
|
||||
'checkbox': 'Select the default checked options',
|
||||
'radio': 'Choose the default selected option',
|
||||
'switch': 'Set the default on/off state',
|
||||
'date': 'Set the default date (YYYY-MM-DD)',
|
||||
'time': 'Set the default time (HH:MM)',
|
||||
'datetime-local': 'Set the default date and time',
|
||||
'range': 'Set the default slider value',
|
||||
'color': 'Choose the default color',
|
||||
'number': 'Set the default numeric value'
|
||||
}
|
||||
|
||||
return helpTexts[props.component.type] || 'Initial value when the form loads'
|
||||
}
|
||||
|
||||
const getDefaultValuePlaceholder = () => {
|
||||
if (!props.component) return ''
|
||||
|
||||
const placeholders = {
|
||||
'text': 'e.g., John Doe',
|
||||
'email': 'e.g., user@example.com',
|
||||
'url': 'e.g., https://example.com',
|
||||
'tel': 'e.g., +1234567890',
|
||||
'number': 'e.g., 100',
|
||||
'date': 'YYYY-MM-DD',
|
||||
'time': 'HH:MM',
|
||||
'datetime-local': 'YYYY-MM-DDTHH:MM'
|
||||
}
|
||||
|
||||
return placeholders[props.component.type] || ''
|
||||
}
|
||||
|
||||
// Safe HTML preview for custom HTML component
|
||||
const getSafeHtmlPreview = (htmlContent) => {
|
||||
if (!htmlContent) return ''
|
||||
|
Loading…
x
Reference in New Issue
Block a user