PluginProbe
The Innovative Form Builder – IvyForms / 0.4
The Innovative Form Builder – IvyForms v0.4
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 / address / AddressField.vue

AddressField.vue in The Innovative Form Builder – IvyForms 0.4, at frontend/src/views/admin/form-builder/fields/address/AddressField.vue

164 lines 4.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <template>
2 <div
3 class="ivyforms-field__address"
4 :class="{ 'ivyforms-field__address--readonly': !!field?.readOnly }"
5 >
6 <div v-if="!field?.hideLabel" class="ivyforms-field__address-label ivyforms-mb-16 regular-16">
7 {{ field?.label || getLabel('address') }}
8 </div>
9 <div
10 class="ivyforms-field__address-layout ivyforms-flex ivyforms-flex-direction-column ivyforms-gap-16 ivyforms-width-100"
11 >
12 <!-- First 3 fields: streetAddress, addressLine2, city (each full width, stacked) -->
13 <div
14 v-for="fieldData in addressFields.slice(0, 3)"
15 :key="fieldData.type"
16 class="ivyforms-field__address-row ivyforms-field__address-row--full ivyforms-flex ivyforms-flex-direction-row ivyforms-width-100"
17 >
18 <div :class="['ivyforms-field__address-field', fieldData.type.toLowerCase() + '-address']">
19 <IvyFormItem
20 :label="fieldData.hideLabel ? '' : fieldData.label"
21 :required="fieldData.required"
22 >
23 <IvyTextInput
24 :id="fieldData.id"
25 readonly
26 :model-value="fieldData.value"
27 type="text"
28 :placeholder="fieldData.placeholder"
29 />
30 <div
31 v-if="fieldData.description"
32 class="ivyforms-field__address-description regular-14"
33 >
34 {{ fieldData.description }}
35 </div>
36 </IvyFormItem>
37 </div>
38 </div>
39 <!-- Last 3 fields: state, zip, country (in a single row, 3 columns) -->
40 <div
41 class="ivyforms-field__address-row ivyforms-field__address-row--three-cols ivyforms-flex ivyforms-flex-direction-row ivyforms-gap-16 ivyforms-width-100"
42 >
43 <div
44 v-for="fieldData in addressFields.slice(3, 6)"
45 :key="fieldData.type"
46 :class="['ivyforms-field__address-field', fieldData.type.toLowerCase() + '-address']"
47 >
48 <IvyFormItem
49 :label="fieldData.hideLabel ? '' : fieldData.label"
50 :required="fieldData.required"
51 >
52 <template v-if="fieldData.type === 'country'">
53 <IvySelectInput
54 :id="fieldData.id"
55 v-model="countryValue"
56 :placeholder="getLabel('select_country')"
57 disabled
58 readonly
59 >
60 <IvySelectOption value="">{{ getLabel('select_country') }}</IvySelectOption>
61 <IvySelectOption
62 v-for="country in countryOptions"
63 :key="country"
64 :value="country"
65 >{{ country }}</IvySelectOption
66 >
67 </IvySelectInput>
68 </template>
69 <template v-else>
70 <IvyTextInput
71 :id="fieldData.id"
72 readonly
73 :model-value="fieldData.value"
74 type="text"
75 :placeholder="fieldData.placeholder"
76 />
77 </template>
78 <div
79 v-if="fieldData.description"
80 class="ivyforms-field__address-description regular-14"
81 >
82 {{ fieldData.description }}
83 </div>
84 </IvyFormItem>
85 </div>
86 </div>
87 </div>
88 </div>
89 </template>
90
91 <script setup lang="ts">
92 import { computed } from 'vue'
93 import { useFormBuilder } from '@/stores/useFormBuilder'
94 import { useLabels } from '@/composables/useLabels'
95 import { countryList } from '@/constants/countries'
96 import type { AddressSubField } from '@/types/field'
97
98 const { getLabel } = useLabels()
99
100 const props = defineProps<{ fieldIndex: number }>()
101 const formBuilderStore = useFormBuilder()
102
103 const field = computed(() => formBuilderStore.fields.find((f) => f.fieldIndex === props.fieldIndex))
104
105 const addressFields = computed<AddressSubField[]>(() =>
106 (field.value?.addressFields || []).filter((f) => f.visible !== false),
107 )
108
109 const countryOptions = countryList.map((c) => c.name)
110
111 const countryValue = computed({
112 get: () => addressFields.value.find((f) => f.type === 'country')?.value || '',
113 set: () => {}, // No-op, readonly in builder
114 })
115 </script>
116
117 <style lang="scss" scoped>
118 .ivyforms-field__address {
119 cursor: move;
120
121 &--readonly {
122 opacity: 0.6;
123 }
124
125 .ivyforms-form-item {
126 margin-bottom: 0;
127 cursor: move;
128
129 :deep(.ivyforms-form-item__label) {
130 display: flex;
131 align-items: center;
132 color: var(--map-base-text-0);
133 font-size: 14px;
134 font-style: normal;
135 font-weight: 500;
136 margin-bottom: 6px;
137 height: 20px !important;
138 }
139
140 :deep(.el-form-item__label) {
141 cursor: move;
142 }
143 }
144
145 &-description {
146 white-space: normal;
147 overflow-wrap: anywhere;
148 word-break: break-word;
149 }
150
151 &-row--full {
152 .ivyforms-field__address-field {
153 flex: 1 1 100%;
154 }
155 }
156
157 &-row--three-cols {
158 .ivyforms-field__address-field {
159 flex: 1 1 0;
160 }
161 }
162 }
163 </style>
164