tethys.backend/resources/js/Components/FormCheckRadio.vue
Arno Kaimbacher 09f65359f9 hotfix(dataset): enhance radio button and checkbox components and add arrayContainsTypes validation
- Added checkbox support to the `FormCheckRadio` component.
- Updated the styling of the radio button and checkbox components.
- Added the `arrayContainsTypes` validation rule to ensure that arrays contain specific types.
- Updated the `dataset` validators and controllers to use the new validation rule.
- Updated the `FormCheckRadioGroup` component to correctly handle the `input-value` as a number.
- Removed the default value from the `id` column in the `collections` migration.
- Added the `array_contains_types` rule to the `adonisrc.ts` file.
2025-03-28 17:34:46 +01:00

91 lines
3.3 KiB
Vue

<script setup lang="ts">
import { computed } from 'vue';
interface Props {
name: string;
type?: 'checkbox' | 'radio' | 'switch';
label?: string | null;
modelValue: Array<any> | string | number | boolean | null;
inputValue: string | number | boolean;
}
const props = defineProps({
name: {
type: String,
required: true,
},
type: {
type: String,
default: 'checkbox',
validator: (value: string) => ['checkbox', 'radio', 'switch'].includes(value),
},
label: {
type: String,
default: null,
},
modelValue: {
type: [Array, String, Number, Boolean],
default: null,
},
inputValue: {
type: [String, Number, Boolean],
required: true,
},
});// const props = defineProps<Props>();
// const emit = defineEmits(['update:modelValue']);
const emit = defineEmits<{ (e: 'update:modelValue', value: Props['modelValue']): void }>();
const computedValue = computed({
get: () => props.modelValue,
set: (value) => {
// If type is radio, wrap the new value inside an array.
if (props.type === 'radio') {
emit('update:modelValue', [value]);
} else {
emit('update:modelValue', value);
}
},
});
const inputType = computed(() => (props.type === 'radio' ? 'radio' : 'checkbox'));
// Define isChecked for radio inputs: it's true when the current modelValue equals the inputValue
const isChecked = computed(() => {
if (props.type === 'radio') {
return Array.isArray(computedValue.value) &&
computedValue.value.length > 0 &&
computedValue.value[0] === props.inputValue;
} else if (props.type === 'checkbox') {
return Array.isArray(computedValue.value) &&
computedValue.value.length > 0 &&
computedValue.value.includes(props.inputValue);
}
return computedValue.value === props.inputValue;
});
</script>
<template>
<label v-if="type === 'radio'" :class="[type]"
class="mr-6 mb-3 last:mr-0 inline-flex items-center cursor-pointer relative">
<input v-model="computedValue" :type="inputType" :name="name" :value="inputValue"
class="absolute left-0 opacity-0 -z-1 focus:outline-none focus:ring-0"
:checked="isChecked" />
<span class="check border transition-colors duration-200 dark:bg-slate-800 block w-5 h-5 rounded-full" :class="{
'border-gray-700': !isChecked,
'bg-radio-checked bg-no-repeat bg-center bg-lime-600 border-lime-600 border-4': isChecked
}" />
<span class="pl-2 control-label">{{ label }}</span>
</label>
<label v-else-if="type === 'checkbox'" :class="[type]"
class="mr-6 mb-3 last:mr-0 inline-flex items-center cursor-pointer relative">
<input v-model="computedValue" :type="inputType" :name="name" :value="inputValue"
class="absolute left-0 opacity-0 -z-1 focus:outline-none focus:ring-0" />
<span class="check border transition-colors duration-200 dark:bg-slate-800 block w-5 h-5 rounded" :class="{
'border-gray-700': !isChecked,
'bg-checkbox-checked bg-no-repeat bg-center bg-lime-600 border-lime-600 border-4': isChecked
}" />
<span class="pl-2 control-label">{{ label }}</span>
</label>
</template>