Fix field validation
This commit is contained in:
parent
1fc676a5fa
commit
1bdc9b8c9c
|
@ -232,7 +232,7 @@ function reload() {
|
||||||
reload();
|
reload();
|
||||||
watch(
|
watch(
|
||||||
() => props.value,
|
() => props.value,
|
||||||
(value) => reload()
|
(value) => reload(),
|
||||||
);
|
);
|
||||||
|
|
||||||
const { back, next, backable, nextable } = useNav(active, v.value.sections.length);
|
const { back, next, backable, nextable } = useNav(active, v.value.sections.length);
|
||||||
|
|
|
@ -3,8 +3,10 @@
|
||||||
<div class="grid grid-cols-1 gap-2">
|
<div class="grid grid-cols-1 gap-2">
|
||||||
<label :for="field.key" class="p-0 block leading-none relative flex items-start">
|
<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" />
|
<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
|
||||||
<span class="peer-checked:bg-primary left-[0.5rem] top-[0.5rem] w-2 h-2 absolute rounded block top-0"></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 class="pl-8 pt-1 @sm:pt-0 text-gray-600 text-sm @sm:text-base">
|
||||||
<span v-text="field.description"></span>
|
<span v-text="field.description"></span>
|
||||||
<span v-show="field.required" class="text-red-800">*</span>
|
<span v-show="field.required" class="text-red-800">*</span>
|
||||||
|
@ -15,7 +17,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import {computed} from 'vue';
|
import { computed } from 'vue';
|
||||||
|
|
||||||
const emit = defineEmits(['update:modelValue']);
|
const emit = defineEmits(['update:modelValue']);
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
@ -26,7 +28,7 @@ const props = defineProps({
|
||||||
field: {
|
field: {
|
||||||
required: true,
|
required: true,
|
||||||
validator: (value) =>
|
validator: (value) =>
|
||||||
hasKeys(value, ['required', 'type', 'key', 'columns', 'name', 'default', 'description']) &&
|
hasKeys(value, [...globalFieldRules(), 'required', 'description']) &&
|
||||||
typeof value.required === 'boolean' &&
|
typeof value.required === 'boolean' &&
|
||||||
typeof value.key === 'string' &&
|
typeof value.key === 'string' &&
|
||||||
value.key.length > 0 &&
|
value.key.length > 0 &&
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<div class="grid grid-cols-1 gap-2 mt-3">
|
<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">
|
<label v-for="(option, index) in field.options" :key="index" :for="`${field.key}-${index}`"
|
||||||
<input :id="`${field.key}-${index}`" v-model="inner" type="checkbox" :name="field.key" :value="option" class="peer absolute invisible" />
|
class="block relative flex items-start">
|
||||||
<span class="border-neutral-400 border-4 border-solid peer-checked:border-primary absolute left-0 w-6 h-6 rounded block"></span>
|
<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="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>
|
<span class="pl-8 pt-1 @sm:pt-0 text-gray-600 text-sm @sm:text-base" v-text="option"></span>
|
||||||
</label>
|
</label>
|
||||||
|
@ -14,7 +17,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import {computed} from 'vue';
|
import { computed } from 'vue';
|
||||||
import FieldLabel from '../FieldLabel.vue';
|
import FieldLabel from '../FieldLabel.vue';
|
||||||
|
|
||||||
const emit = defineEmits(['update:modelValue']);
|
const emit = defineEmits(['update:modelValue']);
|
||||||
|
@ -26,7 +29,7 @@ const props = defineProps({
|
||||||
field: {
|
field: {
|
||||||
required: true,
|
required: true,
|
||||||
validator: (value) =>
|
validator: (value) =>
|
||||||
hasKeys(value, ['required', 'type', 'key', 'columns', 'name', 'default', 'options']) &&
|
hasKeys(value, [...globalFieldRules(), 'required', 'options']) &&
|
||||||
typeof value.required === 'boolean' &&
|
typeof value.required === 'boolean' &&
|
||||||
typeof value.key === 'string' &&
|
typeof value.key === 'string' &&
|
||||||
value.key.length > 0 &&
|
value.key.length > 0 &&
|
||||||
|
|
|
@ -1,20 +1,13 @@
|
||||||
<template>
|
<template>
|
||||||
<label class="w-full border border-solid border-gray-500 focus-within:border-primary rounded-lg relative flex">
|
<label class="w-full border border-solid border-gray-500 focus-within:border-primary rounded-lg relative flex">
|
||||||
<input
|
<input :id="field.key" v-model="inner" :name="field.key" type="date" :max="max" placeholder=""
|
||||||
:id="field.key"
|
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" />
|
||||||
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>
|
<field-label :name="field.name" :required="field.required"></field-label>
|
||||||
</label>
|
</label>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import {computed} from 'vue';
|
import { computed } from 'vue';
|
||||||
import FieldLabel from '../FieldLabel.vue';
|
import FieldLabel from '../FieldLabel.vue';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
|
@ -27,7 +20,7 @@ const props = defineProps({
|
||||||
field: {
|
field: {
|
||||||
required: true,
|
required: true,
|
||||||
validator: (value) =>
|
validator: (value) =>
|
||||||
hasKeys(value, ['required', 'type', 'key', 'columns', 'name', 'default', 'max_today']) &&
|
hasKeys(value, [...globalFieldRules(), 'required', 'max_today']) &&
|
||||||
typeof value.required === 'boolean' &&
|
typeof value.required === 'boolean' &&
|
||||||
typeof value.max_today === 'boolean' &&
|
typeof value.max_today === 'boolean' &&
|
||||||
typeof value.key === 'string' &&
|
typeof value.key === 'string' &&
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<label class="w-full border border-solid border-gray-500 focus-within:border-primary rounded-lg relative flex" :for="field.key">
|
<label class="w-full border border-solid border-gray-500 focus-within:border-primary rounded-lg relative flex"
|
||||||
<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">
|
: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 :value="null">-- kein --</option>
|
||||||
<option v-for="(option, index) in field.options" :key="index" :value="option" v-text="option"></option>
|
<option v-for="(option, index) in field.options" :key="index" :value="option" v-text="option"></option>
|
||||||
</select>
|
</select>
|
||||||
|
@ -9,7 +12,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import {computed} from 'vue';
|
import { computed } from 'vue';
|
||||||
import FieldLabel from '../FieldLabel.vue';
|
import FieldLabel from '../FieldLabel.vue';
|
||||||
|
|
||||||
const emit = defineEmits(['update:modelValue']);
|
const emit = defineEmits(['update:modelValue']);
|
||||||
|
@ -21,7 +24,7 @@ const props = defineProps({
|
||||||
field: {
|
field: {
|
||||||
required: true,
|
required: true,
|
||||||
validator: (value) =>
|
validator: (value) =>
|
||||||
hasKeys(value, ['required', 'type', 'key', 'columns', 'name', 'default', 'options']) &&
|
hasKeys(value, [...globalFieldRules(), 'required', 'options']) &&
|
||||||
typeof value.required === 'boolean' &&
|
typeof value.required === 'boolean' &&
|
||||||
typeof value.key === 'string' &&
|
typeof value.key === 'string' &&
|
||||||
value.key.length > 0 &&
|
value.key.length > 0 &&
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<label class="w-full border border-solid border-gray-500 focus-within:border-primary rounded-lg relative flex" :for="field.key">
|
<label class="w-full border border-solid border-gray-500 focus-within:border-primary rounded-lg relative flex"
|
||||||
<select
|
:for="field.key">
|
||||||
:id="field.key"
|
<select :id="field.key" v-model="inner" :disabled="disabled" :name="field.key"
|
||||||
v-model="inner"
|
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">
|
||||||
: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 :value="null">-- kein --</option>
|
||||||
<option v-for="(option, index) in options" :key="index" :value="option.id" v-text="option.name"></option>
|
<option v-for="(option, index) in options" :key="index" :value="option.id" v-text="option.name"></option>
|
||||||
</select>
|
</select>
|
||||||
|
@ -15,7 +11,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import {computed, ref, watch} from 'vue';
|
import { computed, ref, watch } from 'vue';
|
||||||
import FieldLabel from '../FieldLabel.vue';
|
import FieldLabel from '../FieldLabel.vue';
|
||||||
|
|
||||||
const emit = defineEmits(['update:modelValue']);
|
const emit = defineEmits(['update:modelValue']);
|
||||||
|
@ -27,7 +23,7 @@ const props = defineProps({
|
||||||
field: {
|
field: {
|
||||||
required: true,
|
required: true,
|
||||||
validator: (value) =>
|
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.required === 'boolean' &&
|
||||||
typeof value.key === 'string' &&
|
typeof value.key === 'string' &&
|
||||||
value.key.length > 0 &&
|
value.key.length > 0 &&
|
||||||
|
@ -84,7 +80,7 @@ if (props.field.parent_field) {
|
||||||
if (oldValue !== newValue) {
|
if (oldValue !== newValue) {
|
||||||
refreshOptions();
|
refreshOptions();
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<div class="grid grid-cols-1 gap-2 mt-3">
|
<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">
|
<label v-for="(option, index) in field.options" :key="index" :for="`${field.key}-${index}`"
|
||||||
<input :id="`${field.key}-${index}`" v-model="inner" type="radio" :name="field.key" :value="option" class="peer absolute invisible" />
|
class="block relative flex items-center">
|
||||||
<span class="border-neutral-400 border-4 border-solid peer-checked:border-primary absolute left-0 w-6 h-6 rounded-full block"></span>
|
<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="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>
|
<span class="pl-8 text-gray-600 text-sm @sm:text-base" v-text="option"></span>
|
||||||
</label>
|
</label>
|
||||||
|
@ -14,7 +17,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import {computed} from 'vue';
|
import { computed } from 'vue';
|
||||||
import FieldLabel from '../FieldLabel.vue';
|
import FieldLabel from '../FieldLabel.vue';
|
||||||
|
|
||||||
const emit = defineEmits(['update:modelValue']);
|
const emit = defineEmits(['update:modelValue']);
|
||||||
|
@ -26,7 +29,7 @@ const props = defineProps({
|
||||||
field: {
|
field: {
|
||||||
required: true,
|
required: true,
|
||||||
validator: (value) =>
|
validator: (value) =>
|
||||||
hasKeys(value, ['required', 'type', 'key', 'columns', 'name', 'default', 'options']) &&
|
hasKeys(value, [...globalFieldRules(), 'required', 'options']) &&
|
||||||
typeof value.required === 'boolean' &&
|
typeof value.required === 'boolean' &&
|
||||||
typeof value.key === 'string' &&
|
typeof value.key === 'string' &&
|
||||||
value.key.length > 0 &&
|
value.key.length > 0 &&
|
||||||
|
|
|
@ -19,7 +19,7 @@ const props = defineProps({
|
||||||
field: {
|
field: {
|
||||||
required: true,
|
required: true,
|
||||||
validator: (value) =>
|
validator: (value) =>
|
||||||
hasKeys(value, ['required', 'type', 'key', 'columns', 'name', 'default']) &&
|
hasKeys(value, [...globalFieldRules(), 'required']) &&
|
||||||
typeof value.required === 'boolean' &&
|
typeof value.required === 'boolean' &&
|
||||||
typeof value.key === 'string' &&
|
typeof value.key === 'string' &&
|
||||||
value.key.length > 0 &&
|
value.key.length > 0 &&
|
||||||
|
|
|
@ -1,18 +1,13 @@
|
||||||
<template>
|
<template>
|
||||||
<label class="w-full border border-solid border-gray-500 focus-within:border-primary rounded-lg relative flex">
|
<label class="w-full border border-solid border-gray-500 focus-within:border-primary rounded-lg relative flex">
|
||||||
<textarea
|
<textarea :id="field.key" v-model="inner" :name="field.key" :rows="field.rows"
|
||||||
:id="field.key"
|
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" />
|
||||||
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>
|
<field-label :name="field.name" :required="field.required"></field-label>
|
||||||
</label>
|
</label>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import {computed} from 'vue';
|
import { computed } from 'vue';
|
||||||
import FieldLabel from '../FieldLabel.vue';
|
import FieldLabel from '../FieldLabel.vue';
|
||||||
|
|
||||||
const emit = defineEmits(['update:modelValue']);
|
const emit = defineEmits(['update:modelValue']);
|
||||||
|
@ -24,7 +19,7 @@ const props = defineProps({
|
||||||
field: {
|
field: {
|
||||||
required: true,
|
required: true,
|
||||||
validator: (value) =>
|
validator: (value) =>
|
||||||
hasKeys(value, ['required', 'type', 'key', 'columns', 'name', 'default', 'rows']) &&
|
hasKeys(value, [...globalFieldRules(), 'required', 'rows']) &&
|
||||||
typeof value.required === 'boolean' &&
|
typeof value.required === 'boolean' &&
|
||||||
typeof value.key === 'string' &&
|
typeof value.key === 'string' &&
|
||||||
value.key.length > 0 &&
|
value.key.length > 0 &&
|
||||||
|
|
17
src/main.js
17
src/main.js
|
@ -12,7 +12,22 @@ window.axios = axios;
|
||||||
axios.defaults.baseURL = window.document.querySelector('[name="adrema_base_url"]').content;
|
axios.defaults.baseURL = window.document.querySelector('[name="adrema_base_url"]').content;
|
||||||
|
|
||||||
window.hasKeys = function (object, expected) {
|
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];
|
EventForm.styles = [classes, carousel, carouselStyle];
|
||||||
|
|
Loading…
Reference in New Issue