Fix field validation

This commit is contained in:
philipp lang 2024-02-19 03:27:46 +01:00
parent 1fc676a5fa
commit 1bdc9b8c9c
10 changed files with 62 additions and 52 deletions

View File

@ -232,7 +232,7 @@ function reload() {
reload();
watch(
() => props.value,
(value) => reload()
(value) => reload(),
);
const { back, next, backable, nextable } = useNav(active, v.value.sections.length);

View File

@ -3,8 +3,10 @@
<div class="grid grid-cols-1 gap-2">
<label :for="field.key" class="p-0 block leading-none relative flex items-start">
<input :id="field.key" v-model="inner" type="checkbox" :name="field.key" class="peer absolute invisible" />
<span class="border-neutral-400 border-4 border-solid peer-checked:border-primary absolute left-0 w-6 h-6 rounded block top-0"></span>
<span class="peer-checked:bg-primary left-[0.5rem] top-[0.5rem] w-2 h-2 absolute rounded block top-0"></span>
<span
class="border-neutral-400 border-4 border-solid peer-checked:border-primary absolute left-0 w-6 h-6 rounded block top-0"></span>
<span
class="peer-checked:bg-primary left-[0.5rem] top-[0.5rem] w-2 h-2 absolute rounded block top-0"></span>
<span class="pl-8 pt-1 @sm:pt-0 text-gray-600 text-sm @sm:text-base">
<span v-text="field.description"></span>
<span v-show="field.required" class="text-red-800">*</span>
@ -15,7 +17,7 @@
</template>
<script setup>
import {computed} from 'vue';
import { computed } from 'vue';
const emit = defineEmits(['update:modelValue']);
const props = defineProps({
@ -26,7 +28,7 @@ const props = defineProps({
field: {
required: true,
validator: (value) =>
hasKeys(value, ['required', 'type', 'key', 'columns', 'name', 'default', 'description']) &&
hasKeys(value, [...globalFieldRules(), 'required', 'description']) &&
typeof value.required === 'boolean' &&
typeof value.key === 'string' &&
value.key.length > 0 &&

View File

@ -1,9 +1,12 @@
<template>
<div class="relative">
<div class="grid grid-cols-1 gap-2 mt-3">
<label v-for="(option, index) in field.options" :key="index" :for="`${field.key}-${index}`" class="block relative flex items-start">
<input :id="`${field.key}-${index}`" v-model="inner" type="checkbox" :name="field.key" :value="option" class="peer absolute invisible" />
<span class="border-neutral-400 border-4 border-solid peer-checked:border-primary absolute left-0 w-6 h-6 rounded block"></span>
<label v-for="(option, index) in field.options" :key="index" :for="`${field.key}-${index}`"
class="block relative flex items-start">
<input :id="`${field.key}-${index}`" v-model="inner" type="checkbox" :name="field.key" :value="option"
class="peer absolute invisible" />
<span
class="border-neutral-400 border-4 border-solid peer-checked:border-primary absolute left-0 w-6 h-6 rounded block"></span>
<span class="peer-checked:bg-primary left-[0.5rem] top-[0.5rem] w-2 h-2 absolute rounded block"></span>
<span class="pl-8 pt-1 @sm:pt-0 text-gray-600 text-sm @sm:text-base" v-text="option"></span>
</label>
@ -14,7 +17,7 @@
</template>
<script setup>
import {computed} from 'vue';
import { computed } from 'vue';
import FieldLabel from '../FieldLabel.vue';
const emit = defineEmits(['update:modelValue']);
@ -26,7 +29,7 @@ const props = defineProps({
field: {
required: true,
validator: (value) =>
hasKeys(value, ['required', 'type', 'key', 'columns', 'name', 'default', 'options']) &&
hasKeys(value, [...globalFieldRules(), 'required', 'options']) &&
typeof value.required === 'boolean' &&
typeof value.key === 'string' &&
value.key.length > 0 &&

View File

@ -1,20 +1,13 @@
<template>
<label class="w-full border border-solid border-gray-500 focus-within:border-primary rounded-lg relative flex">
<input
:id="field.key"
v-model="inner"
:name="field.key"
type="date"
:max="max"
placeholder=""
class="bg-white rounded-lg focus:outline-none text-gray-600 text-left py-1 px-2 @sm:py-2 text-sm @sm:text-base @sm:px-3 w-full"
/>
<input :id="field.key" v-model="inner" :name="field.key" type="date" :max="max" placeholder=""
class="bg-white rounded-lg focus:outline-none text-gray-600 text-left py-1 px-2 @sm:py-2 text-sm @sm:text-base @sm:px-3 w-full" />
<field-label :name="field.name" :required="field.required"></field-label>
</label>
</template>
<script setup>
import {computed} from 'vue';
import { computed } from 'vue';
import FieldLabel from '../FieldLabel.vue';
import dayjs from 'dayjs';
@ -27,7 +20,7 @@ const props = defineProps({
field: {
required: true,
validator: (value) =>
hasKeys(value, ['required', 'type', 'key', 'columns', 'name', 'default', 'max_today']) &&
hasKeys(value, [...globalFieldRules(), 'required', 'max_today']) &&
typeof value.required === 'boolean' &&
typeof value.max_today === 'boolean' &&
typeof value.key === 'string' &&

View File

@ -1,6 +1,9 @@
<template>
<label class="w-full border border-solid border-gray-500 focus-within:border-primary rounded-lg relative flex" :for="field.key">
<select :name="field.key" :id="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" v-model="inner">
<label class="w-full border border-solid border-gray-500 focus-within:border-primary rounded-lg relative flex"
:for="field.key">
<select :name="field.key" :id="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"
v-model="inner">
<option :value="null">-- kein --</option>
<option v-for="(option, index) in field.options" :key="index" :value="option" v-text="option"></option>
</select>
@ -9,7 +12,7 @@
</template>
<script setup>
import {computed} from 'vue';
import { computed } from 'vue';
import FieldLabel from '../FieldLabel.vue';
const emit = defineEmits(['update:modelValue']);
@ -21,7 +24,7 @@ const props = defineProps({
field: {
required: true,
validator: (value) =>
hasKeys(value, ['required', 'type', 'key', 'columns', 'name', 'default', 'options']) &&
hasKeys(value, [...globalFieldRules(), 'required', 'options']) &&
typeof value.required === 'boolean' &&
typeof value.key === 'string' &&
value.key.length > 0 &&

View File

@ -1,12 +1,8 @@
<template>
<label class="w-full border border-solid border-gray-500 focus-within:border-primary rounded-lg relative flex" :for="field.key">
<select
:id="field.key"
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"
>
<label class="w-full border border-solid border-gray-500 focus-within:border-primary rounded-lg relative flex"
:for="field.key">
<select :id="field.key" 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>
</select>
@ -15,7 +11,7 @@
</template>
<script setup>
import {computed, ref, watch} from 'vue';
import { computed, ref, watch } from 'vue';
import FieldLabel from '../FieldLabel.vue';
const emit = defineEmits(['update:modelValue']);
@ -27,7 +23,7 @@ const props = defineProps({
field: {
required: true,
validator: (value) =>
hasKeys(value, ['required', 'type', 'key', 'columns', 'name', 'default', 'parent_field', 'parent_group']) &&
hasKeys(value, [...globalFieldRules(), 'required', 'parent_field', 'parent_group']) &&
typeof value.required === 'boolean' &&
typeof value.key === 'string' &&
value.key.length > 0 &&
@ -84,7 +80,7 @@ if (props.field.parent_field) {
if (oldValue !== newValue) {
refreshOptions();
}
}
},
);
}
</script>

View File

@ -1,9 +1,12 @@
<template>
<div class="relative">
<div class="grid grid-cols-1 gap-2 mt-3">
<label v-for="(option, index) in field.options" :key="index" :for="`${field.key}-${index}`" class="block relative flex items-center">
<input :id="`${field.key}-${index}`" v-model="inner" type="radio" :name="field.key" :value="option" class="peer absolute invisible" />
<span class="border-neutral-400 border-4 border-solid peer-checked:border-primary absolute left-0 w-6 h-6 rounded-full block"></span>
<label v-for="(option, index) in field.options" :key="index" :for="`${field.key}-${index}`"
class="block relative flex items-center">
<input :id="`${field.key}-${index}`" v-model="inner" type="radio" :name="field.key" :value="option"
class="peer absolute invisible" />
<span
class="border-neutral-400 border-4 border-solid peer-checked:border-primary absolute left-0 w-6 h-6 rounded-full block"></span>
<span class="peer-checked:bg-primary left-2 w-2 h-2 absolute rounded-full block"></span>
<span class="pl-8 text-gray-600 text-sm @sm:text-base" v-text="option"></span>
</label>
@ -14,7 +17,7 @@
</template>
<script setup>
import {computed} from 'vue';
import { computed } from 'vue';
import FieldLabel from '../FieldLabel.vue';
const emit = defineEmits(['update:modelValue']);
@ -26,7 +29,7 @@ const props = defineProps({
field: {
required: true,
validator: (value) =>
hasKeys(value, ['required', 'type', 'key', 'columns', 'name', 'default', 'options']) &&
hasKeys(value, [...globalFieldRules(), 'required', 'options']) &&
typeof value.required === 'boolean' &&
typeof value.key === 'string' &&
value.key.length > 0 &&

View File

@ -19,7 +19,7 @@ const props = defineProps({
field: {
required: true,
validator: (value) =>
hasKeys(value, ['required', 'type', 'key', 'columns', 'name', 'default']) &&
hasKeys(value, [...globalFieldRules(), 'required']) &&
typeof value.required === 'boolean' &&
typeof value.key === 'string' &&
value.key.length > 0 &&

View File

@ -1,18 +1,13 @@
<template>
<label class="w-full border border-solid border-gray-500 focus-within:border-primary rounded-lg relative flex">
<textarea
:id="field.key"
v-model="inner"
:name="field.key"
:rows="field.rows"
class="bg-white rounded-lg focus:outline-none text-gray-600 text-left py-1 px-2 @sm:py-2 text-sm @sm:text-base @sm:px-3 w-full"
/>
<textarea :id="field.key" v-model="inner" :name="field.key" :rows="field.rows"
class="bg-white rounded-lg focus:outline-none text-gray-600 text-left py-1 px-2 @sm:py-2 text-sm @sm:text-base @sm:px-3 w-full" />
<field-label :name="field.name" :required="field.required"></field-label>
</label>
</template>
<script setup>
import {computed} from 'vue';
import { computed } from 'vue';
import FieldLabel from '../FieldLabel.vue';
const emit = defineEmits(['update:modelValue']);
@ -24,7 +19,7 @@ const props = defineProps({
field: {
required: true,
validator: (value) =>
hasKeys(value, ['required', 'type', 'key', 'columns', 'name', 'default', 'rows']) &&
hasKeys(value, [...globalFieldRules(), 'required', 'rows']) &&
typeof value.required === 'boolean' &&
typeof value.key === 'string' &&
value.key.length > 0 &&

View File

@ -12,7 +12,22 @@ window.axios = axios;
axios.defaults.baseURL = window.document.querySelector('[name="adrema_base_url"]').content;
window.hasKeys = function (object, expected) {
return typeof object === 'object' && JSON.stringify(Object.keys(object).sort()) === JSON.stringify(expected.sort());
if (typeof object !== 'object') {
return false;
}
var givenKeys = JSON.stringify(Object.keys(object).sort());
var expectedKeys = JSON.stringify(expected.sort());
if (givenKeys !== expectedKeys) {
console.log('Fields ' + givenKeys + ' dont match ' + expectedKeys);
return false;
}
return true;
};
window.globalFieldRules = function () {
return ['default', 'nami_type', 'for_members', 'key', 'columns', 'name', 'type'];
};
EventForm.styles = [classes, carousel, carouselStyle];