99 lines
3.4 KiB
Vue
99 lines
3.4 KiB
Vue
<template>
|
|
<label class="w-full border border-solid border-gray-500 focus-within:border-primary rounded-lg relative flex" :for="field.key">
|
|
<select
|
|
:id="innerId"
|
|
v-model="inner"
|
|
:disabled="disabled"
|
|
:name="field.key"
|
|
class="bg-white rounded-lg focus:outline-none text-gray-600 text-left peer py-1 px-2 @sm:py-2 text-sm @sm:text-base @sm:px-3 w-full"
|
|
>
|
|
<option :value="null">-- kein --</option>
|
|
<option v-for="(option, index) in options" :key="index" :value="option.id" v-text="option.name"></option>
|
|
<option v-if="field.has_empty_option" :value="-1" v-text="field.empty_option_value"></option>
|
|
</select>
|
|
<field-label :name="field.name" :required="field.required"></field-label>
|
|
</label>
|
|
</template>
|
|
|
|
<script setup>
|
|
import {computed, ref, watch} from 'vue';
|
|
import FieldLabel from '../FieldLabel.vue';
|
|
|
|
const emit = defineEmits(['update:modelValue']);
|
|
const props = defineProps({
|
|
modelValue: {
|
|
required: true,
|
|
validator: (value) => value === null || typeof value === 'string' || typeof value === 'number',
|
|
},
|
|
field: {
|
|
required: true,
|
|
validator: (value) =>
|
|
hasKeys(value, [...globalFieldRules(), 'required', 'parent_field', 'parent_group', 'has_empty_option', 'empty_option_value']) &&
|
|
typeof value.required === 'boolean' &&
|
|
typeof value.has_empty_option === 'boolean' &&
|
|
typeof value.empty_option_value === 'string' &&
|
|
typeof value.key === 'string' &&
|
|
value.key.length > 0 &&
|
|
typeof value.name === 'string' &&
|
|
value.name.length > 0 &&
|
|
hasKeys(value.columns, ['mobile', 'desktop', 'tablet']),
|
|
},
|
|
payload: {},
|
|
id: {
|
|
required: false,
|
|
},
|
|
});
|
|
|
|
const innerId = computed(() => (props.id ? props.id : props.field.key));
|
|
|
|
const inner = computed({
|
|
get: () => props.modelValue,
|
|
set: (v) => emit('update:modelValue', v),
|
|
});
|
|
|
|
const options = ref([]);
|
|
const disabled = ref(false);
|
|
|
|
async function refreshOptions() {
|
|
if (props.field.parent_group === null && props.field.parent_field === null) {
|
|
emit('update:modelValue', null);
|
|
options.value = (await axios.get('/api/group?prefer_inner')).data.data;
|
|
disabled.value = false;
|
|
return;
|
|
}
|
|
if (props.field.parent_group !== null) {
|
|
emit('update:modelValue', null);
|
|
options.value = (await axios.get('/api/group/' + props.field.parent_group + '?prefer_inner')).data.data;
|
|
disabled.value = false;
|
|
return;
|
|
}
|
|
|
|
if (props.field.parent_field !== null && props.field.parent_field in props.payload && !props.payload[props.field.parent_field]) {
|
|
options.value = [];
|
|
emit('update:modelValue', null);
|
|
disabled.value = true;
|
|
return;
|
|
}
|
|
|
|
if (props.field.parent_field !== null && props.field.parent_field in props.payload && props.payload[props.field.parent_field]) {
|
|
emit('update:modelValue', null);
|
|
options.value = (await axios.get('/api/group/' + props.payload[props.field.parent_field] + '?prefer_inner')).data.data;
|
|
disabled.value = false;
|
|
return;
|
|
}
|
|
}
|
|
|
|
refreshOptions();
|
|
|
|
if (props.field.parent_field) {
|
|
watch(
|
|
() => props.payload[props.field.parent_field],
|
|
function (oldValue, newValue) {
|
|
if (oldValue !== newValue) {
|
|
refreshOptions();
|
|
}
|
|
},
|
|
);
|
|
}
|
|
</script>
|