PluginProbe
The Innovative Form Builder – IvyForms / 0.8
The Innovative Form Builder – IvyForms v0.8
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 0.8, at frontend/src/views/public/fields/SelectFormField.vue

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