feat: validate grades table in form

This commit is contained in:
EETagent 2023-01-16 23:41:13 +01:00
parent da3fe8c5ac
commit 16ef3569e6
2 changed files with 66 additions and 25 deletions

View file

@ -7,9 +7,11 @@
</script>
<script lang="ts">
import { createEventDispatcher } from 'svelte';
import GradesRow, { type Grade, type Semester } from './GradesRow.svelte';
let gradesLocal: Array<Grade> = Array.from({ length: 8 }, () => {
let gradesLocal: Array<Grade> = Array.from({ length: 1 }, () => {
return {
subject: '',
semesters: {
@ -21,27 +23,35 @@
};
});
export let error: string = '';
export let grades: Array<GradeBackend>;
const dispatch = createEventDispatcher();
// Convert local Grade type to expanded GradesBackend type
$: {
const gradesTemp: Array<GradeBackend> = [];
for (let index = 0; index < gradesLocal.length; index++) {
const grade = gradesLocal[index];
for (const semester in grade.semesters) {
const semesterTyped = semester as Semester;
if (grade.semesters[semesterTyped] && grade.subject) {
const gradeString = grade.semesters[semesterTyped]!;
gradesTemp.push({
subject: grade.subject,
grade: Number(gradeString),
semester: semesterTyped
});
const convertGrades = () => {
// Delay to wait for select to be updated
setTimeout(() => {
const gradesTemp: Array<GradeBackend> = [];
for (let index = 0; index < gradesLocal.length; index++) {
const grade = gradesLocal[index];
for (const semester in grade.semesters) {
const semesterTyped = semester as Semester;
if (grade.semesters[semesterTyped] && grade.subject) {
const gradeString = grade.semesters[semesterTyped]!;
gradesTemp.push({
subject: grade.subject,
grade: Number(gradeString),
semester: semesterTyped
});
}
}
}
}
grades = gradesTemp;
}
grades = [...gradesTemp];
dispatch('change', grades);
});
};
</script>
<div class="mx-auto mt-8 flex max-h-[22rem] w-full flex-col overflow-scroll lg:w-4/5">
@ -53,9 +63,10 @@
<span class="ml-0.5 w-1/6 text-center">2/9</span>
</div>
{#each gradesLocal as _, i}
<GradesRow bind:grade={gradesLocal[i]} />
<GradesRow on:keyup={convertGrades} on:change={convertGrades} bind:grade={gradesLocal[i]} />
{/each}
<button
class:isError={error}
class="ml-auto w-24 rounded-full bg-gray-400 p-1 text-xl text-white transition-colors duration-300 hover:bg-gray-500"
on:click={() => {
gradesLocal = [
@ -82,4 +93,7 @@
</div>
<style lang="postcss">
.isError {
@apply bg-red-500;
}
</style>

View file

@ -59,7 +59,8 @@
citizenship: '',
personalIdNumber: '',
schoolName: '',
healthInsurance: ''
healthInsurance: '',
grades: []
},
parents: [
{
@ -106,7 +107,20 @@
citizenship: yup.string().required(),
personalIdNumber: yup.string().required(),
schoolName: yup.string().required(),
healthInsurance: yup.number().required()
healthInsurance: yup.number().required(),
grades: yup
.array()
.min(1)
.of(
yup
.object()
.shape({
subject: yup.string().required(),
grade: yup.number().required(),
semester: yup.string().required()
})
.required()
)
}),
parents: yup.array().of(
yup.object().shape({
@ -272,7 +286,7 @@
}
};
const { form, errors, handleSubmit, handleChange } = createForm({
const { form, errors, handleSubmit, handleChange, updateValidateField } = createForm({
initialValues: formInitialValues,
validationSchema: formValidationSchema,
@ -371,7 +385,8 @@
street: details.candidate.address.split(',')[0].split(' ')[0],
houseNumber: details.candidate.address.split(',')[0].split(' ')[1],
city: details.candidate.address.split(',')[1],
zip: details.candidate.address.split(',')[2]
zip: details.candidate.address.split(',')[2],
grades: []
},
parents: [
{
@ -390,8 +405,6 @@
pageIndex = 2; // skip gdpr page
pageTexts[2] = 'Úprava osobních údajů';
}
let test = 8;
</script>
<SplitLayout>
@ -684,7 +697,21 @@
<p class="description mt-8 block text-center">
Přidejte prosím přepis Vaších známek z posledních dvou let studia
</p>
<GradesTable />
<GradesTable
error={$typedErrors['candidate']['grades']}
on:change={(event) => {
//@ts-ignore
const mockEvent = {
target: {
name: 'candidate.grades',
value: event.detail
}
};
//@ts-ignore
handleChange(mockEvent);
}}
bind:grades={$form.candidate.grades}
/>
{/if}
</div>
<div class="bottom-1/12 absolute w-full">