PluginProbe
The Innovative Form Builder – IvyForms / 1.0
The Innovative Form Builder – IvyForms v1.0
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 / public / fields / SelectFormField.vue

SelectFormField.vue in The Innovative Form Builder – IvyForms 1.0, at frontend/src/views/public/fields/SelectFormField.vue

132 lines 3.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <template>
2 <div
3 :class="[
4 'ivyforms-field',
5 'ivyforms-field__select',
6 'ivyforms-field__select_' + field.id,
7 field.cssClasses,
8 { 'is-readonly': !!field.readOnly },
9 ]"
10 >
11 <IvyFormItem
12 :label="field.hideLabel ? '' : field.label"
13 :required="field.required"
14 :error="error"
15 :prop="field.type + '_' + field.fieldIndex"
16 :show-info="!!field.description"
17 :info-text="String(field.description || '')"
18 :show-info-icon="false"
19 :label-position="field.labelPosition === 'default' ? 'top' : field.labelPosition || 'top'"
20 >
21 <IvySelectInput
22 :id="fieldID"
23 v-model="localModelValue"
24 :aria-label="field.label"
25 :disabled="disabled"
26 :readonly="field.readOnly"
27 :required="field.required"
28 class="ivyforms-field__select-input"
29 :filterable="field.enableSearch"
30 :multiple="field.type === 'multi-select'"
31 :placeholder="field.placeholder"
32 >
33 <IvySelectOption
34 v-for="option in selectOptions"
35 :id="option.id"
36 :key="option.id || option.value"
37 :value="option.value"
38 :label="option.label"
39 />
40 </IvySelectInput>
41 </IvyFormItem>
42 </div>
43 </template>
44
45 <script setup lang="ts">
46 import { computed, ref, watch, onMounted, inject } from 'vue'
47 import type { Field } from '@/types/field'
48 import IvyFormItem from '@/views/_components/form/IvyFormItem.vue'
49 import IvySelectInput from '@/views/_components/input/IvySelectInput.vue'
50 import IvySelectOption from '@/views/_components/input/IvySelectOption.vue'
51
52 interface FieldProps {
53 modelValue: string | string[] | null | undefined
54 field: Field
55 disabled?: boolean
56 error?: string
57 }
58
59 const props = withDefaults(defineProps<FieldProps>(), {
60 modelValue: '',
61 disabled: false,
62 error: '',
63 })
64 const emit = defineEmits(['update:modelValue'])
65
66 const fieldID = `field_${props.field.fieldIndex}`
67 const clearFieldError = inject<(fieldKey: string) => void>('clearFieldError', () => {})
68 const fieldKey = computed(() => props.field.type + '_' + props.field.fieldIndex)
69 const localModelValue = ref(props.modelValue)
70
71 watch(
72 () => props.modelValue,
73 (newVal) => {
74 localModelValue.value = newVal
75 },
76 )
77 watch(localModelValue, (newVal) => {
78 emit('update:modelValue', newVal)
79 clearFieldError(fieldKey.value)
80 })
81 const disabled = computed(() => props.disabled || props.field.readOnly)
82 const error = computed(() => props.error || '')
83 const field = computed(() => props.field)
84 const shuffledOptions = ref([])
85 function shuffle<T>(array: T[]): T[] {
86 const arr = array.slice()
87 for (let i = arr.length - 1; i > 0; i--) {
88 const j = Math.floor(Math.random() * (i + 1))
89 ;[arr[i], arr[j]] = [arr[j], arr[i]]
90 }
91 return arr
92 }
93 onMounted(() => {
94 let opts = field.value.fieldOptions || []
95 if (field.value.shuffleOptions) {
96 opts = shuffle(opts)
97 }
98 shuffledOptions.value = opts.map((opt) => ({
99 label: opt.label,
100 value: opt.value !== null && opt.value !== undefined ? String(opt.value) : '',
101 id: opt.id,
102 isDefault: opt.isDefault,
103 }))
104
105 // Default value logic for multi-select
106 const isMulti = field.value.type === 'multi-select'
107 if (isMulti) {
108 const optionDefaults = shuffledOptions.value.filter((o) => o.isDefault).map((o) => o.value)
109 const defaultsSet = new Set(optionDefaults)
110 if (defaultsSet.size) {
111 localModelValue.value = Array.from(defaultsSet)
112 emit('update:modelValue', localModelValue.value)
113 }
114 }
115 })
116 const selectOptions = computed(() =>
117 shuffledOptions.value.length
118 ? shuffledOptions.value
119 : (field.value.fieldOptions || []).map((opt) => ({
120 label: opt.label,
121 value: opt.value !== null && opt.value !== undefined ? String(opt.value) : '',
122 id: opt.id,
123 })),
124 )
125 </script>
126
127 <style scoped lang="scss">
128 .ivyforms-field__select-input {
129 width: 100%;
130 }
131 </style>
132