PluginProbe
The Innovative Form Builder – IvyForms / 0.7
The Innovative Form Builder – IvyForms v0.7
1.5.1 1.5 1.4.1 1.4 trunk 0.1.2 0.2 0.2.1 0.3 0.3.1 0.4 0.5 0.6 0.6.1 0.6.1-backup 0.6.1.1 0.7 0.8 0.8.1 0.8.2 0.9 0.9.1 1.0 1.1 1.1.1 All 27 releases
ivyforms / frontend / src / views / admin / form-builder / fields / date / DateField.vue

DateField.vue in The Innovative Form Builder – IvyForms 0.7, at frontend/src/views/admin/form-builder/fields/date/DateField.vue

196 lines 6.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <template>
2 <div class="ivyforms-field-date" :class="{ 'ivyforms-field-date--readonly': readOnly }">
3 <!-- Date Picker Type -->
4 <template v-if="isPickerType">
5 <IvyFormItem
6 :label="hideLabel ? '' : label"
7 :required="required"
8 :label-position="labelPosition"
9 >
10 <IvyTextInput
11 :id="'date_' + index"
12 :aria-label="label"
13 :placeholder="placeholder"
14 :model-value="datePickerValue"
15 type="text"
16 readonly=""
17 />
18 <div
19 v-if="description"
20 class="ivyforms-field-date__description regular-14 ivyforms-width-100 ivyforms-mt-6"
21 >
22 {{ description }}
23 </div>
24 </IvyFormItem>
25 </template>
26
27 <!-- Input Type (manual entry) -->
28 <template v-else-if="isInputType">
29 <IvyFormItem
30 :label="hideLabel ? '' : label"
31 :required="required"
32 :label-position="labelPosition"
33 >
34 <IvyTextInput
35 :id="'date_' + index"
36 :aria-label="label"
37 readonly
38 :placeholder="placeholder"
39 :model-value="datePickerValue"
40 type="text"
41 />
42 <div
43 v-if="description"
44 class="ivyforms-field-date__description regular-14 ivyforms-width-100 ivyforms-mt-6"
45 >
46 {{ description }}
47 </div>
48 </IvyFormItem>
49 </template>
50
51 <!-- Dropdown Type -->
52 <template v-else-if="isDropdownType">
53 <IvyFormItem
54 :label="hideLabel ? '' : label"
55 :required="required"
56 :label-position="labelPosition"
57 >
58 <div class="ivyforms-flex ivyforms-width-100 ivyforms-gap-12">
59 <div class="ivyforms-flex ivyforms-flex-1 ivyforms-flex-direction-column">
60 <div class="medium-14 ivyforms-mb-6 ivyforms-field-date__sublabel">
61 {{ getDayLabel }}
62 </div>
63 <IvySelectInput
64 :model-value="dropdownDayValue"
65 placeholder="--"
66 readonly
67 @mousedown.prevent
68 @click.prevent
69 />
70 </div>
71 <div class="ivyforms-flex ivyforms-flex-1 ivyforms-flex-direction-column">
72 <div class="medium-14 ivyforms-mb-6 ivyforms-field-date__sublabel">
73 {{ getMonthLabel }}
74 </div>
75 <IvySelectInput
76 :model-value="dropdownMonthValue"
77 placeholder="--"
78 readonly
79 @mousedown.prevent
80 @click.prevent
81 />
82 </div>
83 <div class="ivyforms-flex ivyforms-flex-1 ivyforms-flex-direction-column">
84 <div class="medium-14 ivyforms-mb-6 ivyforms-field-date__sublabel">
85 {{ getYearLabel }}
86 </div>
87 <IvySelectInput
88 :model-value="dropdownYearValue"
89 placeholder="--"
90 readonly
91 @mousedown.prevent
92 @click.prevent
93 />
94 </div>
95 </div>
96 <div
97 v-if="description"
98 class="ivyforms-field-date__description regular-14 ivyforms-width-100 ivyforms-mt-6"
99 >
100 {{ description }}
101 </div>
102 </IvyFormItem>
103 </template>
104 </div>
105 </template>
106
107 <script setup lang="ts">
108 import { computed } from 'vue'
109 import { useFormBuilder } from '@/stores/useFormBuilder'
110 import { useLabels } from '@/composables/useLabels'
111 import { useDateField } from '@/composables/useDateField'
112 import IvySelectInput from '@/views/_components/input/IvySelectInput.vue'
113 import IvyTextInput from '@/views/_components/input/IvyTextInput.vue'
114 import IvyFormItem from '@/views/_components/form/IvyFormItem.vue'
115
116 const { getLabel } = useLabels()
117 const props = defineProps<{ fieldIndex: number }>()
118 const formBuilderStore = useFormBuilder()
119 const field = computed(() => formBuilderStore.fields.find((f) => f.fieldIndex === props.fieldIndex))
120 const label = computed(() => field.value?.label || '')
121 const placeholder = computed(() => field.value?.placeholder || '')
122 const required = computed(() => field.value?.required || false)
123 const hideLabel = computed(() => field.value?.hideLabel || false)
124 const readOnly = computed(() => field.value?.readOnly || false)
125 const description = computed(() => field.value?.description || '')
126 const index = computed(() => field.value?.fieldIndex ?? props.fieldIndex)
127 const modelValue = computed(() => field.value?.defaultValue || '')
128
129 const dateFieldType = computed(() => field.value?.dateFieldType || 'picker')
130 const dateFormat = computed(() => field.value?.dateFormat || 'MM/DD/YYYY')
131 const labelPosition = computed(() =>
132 field.value?.labelPosition === 'default' ? 'top' : field.value?.labelPosition || 'top',
133 )
134
135 const isPickerType = computed(() => dateFieldType.value === 'picker')
136 const isInputType = computed(() => dateFieldType.value === 'input')
137 const isDropdownType = computed(() => dateFieldType.value === 'dropdown')
138
139 const { parseDateString } = useDateField()
140
141 // Parse default value
142 const parsedDate = computed(() =>
143 parseDateString(String(modelValue.value || ''), String(dateFormat.value as unknown as string)),
144 )
145
146 // For date picker and input mode - both use the same formatted value
147 const datePickerValue = computed(() => modelValue.value || '')
148
149 // For dropdown mode
150 const dropdownDayValue = computed(() => parsedDate.value.day)
151 const dropdownMonthValue = computed(() => parsedDate.value.month)
152 const dropdownYearValue = computed(() => parsedDate.value.year)
153
154 // Labels based on format
155 const getDayLabel = computed(() => getLabel('day'))
156 const getMonthLabel = computed(() => getLabel('month'))
157 const getYearLabel = computed(() => getLabel('year'))
158 </script>
159
160 <style lang="scss" scoped>
161 .ivyforms-field-date {
162 cursor: default;
163
164 &--readonly {
165 opacity: 0.6;
166 }
167
168 &__sublabel {
169 color: var(--map-base-text-0);
170 }
171
172 &__description {
173 color: var(--map-base-text-0);
174 display: block;
175 white-space: normal;
176 overflow-wrap: anywhere;
177 word-break: break-word;
178 }
179
180 :deep(.el-input__inner),
181 :deep(.el-input__wrapper) {
182 cursor: default;
183 }
184
185 :deep(.ivyforms-input.el-input .el-input__wrapper),
186 :deep(.ivyforms-input.el-input .el-input__wrapper:hover),
187 :deep(.ivyforms-input.el-input .el-input__wrapper.is-hovering),
188 :deep(.ivyforms-input.el-input .el-input__wrapper:focus),
189 :deep(.ivyforms-input.el-input .el-input__wrapper.is-focused),
190 :deep(.ivyforms-input.el-input .el-input__wrapper:active),
191 :deep(.ivyforms-input.el-input .el-input__wrapper.is-active) {
192 border: 1px solid var(--map-base-dusk-stroke--2);
193 }
194 }
195 </style>
196