Felder Validierung für E-Mail, PLZ und Telefonnummer. Eingabe akzeptieren wenn wenniger als 3 Plätze vorhanden sind.
This commit is contained in:
Binary file not shown.
@@ -44,6 +44,10 @@
|
||||
let alterFehler = '';
|
||||
let notenFehler = '';
|
||||
let sozialverhaltenFehler = '';
|
||||
let emailFehler = '';
|
||||
let telefonFehler = '';
|
||||
let notfallTelefonFehler = '';
|
||||
let plzFehler = '';
|
||||
|
||||
// Hinweis für IGS/KGS mit Lernentwicklungsbericht
|
||||
$: zeigeIgsKgsHinweis =
|
||||
@@ -80,6 +84,92 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Echtzeit-Validierung: E-Mail
|
||||
$: {
|
||||
if (email) {
|
||||
// RFC 5322 konforme E-Mail-Validierung (vereinfacht)
|
||||
const emailRegex = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$/;
|
||||
if (!emailRegex.test(email)) {
|
||||
emailFehler = 'Bitte gib eine gültige E-Mail-Adresse ein.';
|
||||
} else {
|
||||
emailFehler = '';
|
||||
}
|
||||
} else {
|
||||
emailFehler = '';
|
||||
}
|
||||
}
|
||||
|
||||
// Echtzeit-Validierung: Telefonnummer
|
||||
// Deutsche Telefonnummern: Festnetz 10-11 Ziffern, Mobil 11-12 Ziffern (mit führender 0)
|
||||
// Erlaubt: Ziffern, Leerzeichen, Bindestriche, Schrägstriche, Klammern, + am Anfang
|
||||
$: {
|
||||
if (telefon) {
|
||||
// Entferne alle Formatierungszeichen für die Ziffernzählung
|
||||
const nurZiffern = telefon.replace(/[\s\-\/\(\)\+]/g, '');
|
||||
|
||||
// Prüfe ob nur erlaubte Zeichen enthalten sind
|
||||
const erlaubteZeichenRegex = /^[\d\s\-\/\(\)\+]+$/;
|
||||
|
||||
if (!erlaubteZeichenRegex.test(telefon)) {
|
||||
telefonFehler = 'Die Telefonnummer enthält ungültige Zeichen.';
|
||||
} else if (!/^\d+$/.test(nurZiffern)) {
|
||||
telefonFehler = 'Die Telefonnummer muss Ziffern enthalten.';
|
||||
} else if (nurZiffern.length < 10) {
|
||||
telefonFehler = 'Die Telefonnummer ist zu kurz (mindestens 10 Ziffern).';
|
||||
} else if (nurZiffern.length > 15) {
|
||||
telefonFehler = 'Die Telefonnummer ist zu lang (maximal 15 Ziffern).';
|
||||
} else {
|
||||
telefonFehler = '';
|
||||
}
|
||||
} else {
|
||||
telefonFehler = '';
|
||||
}
|
||||
}
|
||||
|
||||
// Echtzeit-Validierung: Notfall-Telefonnummer
|
||||
$: {
|
||||
if (notfallTelefon) {
|
||||
const nurZiffern = notfallTelefon.replace(/[\s\-\/\(\)\+]/g, '');
|
||||
const erlaubteZeichenRegex = /^[\d\s\-\/\(\)\+]+$/;
|
||||
|
||||
if (!erlaubteZeichenRegex.test(notfallTelefon)) {
|
||||
notfallTelefonFehler = 'Die Telefonnummer enthält ungültige Zeichen.';
|
||||
} else if (!/^\d+$/.test(nurZiffern)) {
|
||||
notfallTelefonFehler = 'Die Telefonnummer muss Ziffern enthalten.';
|
||||
} else if (nurZiffern.length < 10) {
|
||||
notfallTelefonFehler = 'Die Telefonnummer ist zu kurz (mindestens 10 Ziffern).';
|
||||
} else if (nurZiffern.length > 15) {
|
||||
notfallTelefonFehler = 'Die Telefonnummer ist zu lang (maximal 15 Ziffern).';
|
||||
} else {
|
||||
notfallTelefonFehler = '';
|
||||
}
|
||||
} else {
|
||||
notfallTelefonFehler = '';
|
||||
}
|
||||
}
|
||||
|
||||
// Echtzeit-Validierung: PLZ (genau 5 Ziffern für deutsche PLZ)
|
||||
$: {
|
||||
if (plz) {
|
||||
const plzRegex = /^\d{5}$/;
|
||||
if (!plzRegex.test(plz)) {
|
||||
if (!/^\d*$/.test(plz)) {
|
||||
plzFehler = 'Die Postleitzahl darf nur Ziffern enthalten.';
|
||||
} else if (plz.length < 5) {
|
||||
plzFehler = 'Die Postleitzahl muss genau 5 Ziffern haben.';
|
||||
} else if (plz.length > 5) {
|
||||
plzFehler = 'Die Postleitzahl darf maximal 5 Ziffern haben.';
|
||||
} else {
|
||||
plzFehler = 'Bitte gib eine gültige Postleitzahl ein.';
|
||||
}
|
||||
} else {
|
||||
plzFehler = '';
|
||||
}
|
||||
} else {
|
||||
plzFehler = '';
|
||||
}
|
||||
}
|
||||
|
||||
// Echtzeit-Validierung: Noten
|
||||
$: {
|
||||
const deutsch = parseInt(noteDeutsch);
|
||||
@@ -125,8 +215,18 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Prüfen ob Formular gültig ist
|
||||
$: formHatFehler = alterFehler !== '' || notenFehler !== '' || sozialverhaltenFehler !== '';
|
||||
// Prüfen ob alle erforderlichen Wünsche ausgewählt wurden (abhängig von verfügbaren Dienststellen)
|
||||
$: wuenscheVollstaendig = (() => {
|
||||
const anzahl = filteredDienststellen.length;
|
||||
if (anzahl === 0) return false;
|
||||
if (anzahl === 1) return !!wunsch1Id;
|
||||
if (anzahl === 2) return !!wunsch1Id && !!wunsch2Id;
|
||||
return !!wunsch1Id && !!wunsch2Id && !!wunsch3Id;
|
||||
})();
|
||||
|
||||
// Prüfen ob Formular gültig ist (erweitert um neue Validierungen)
|
||||
$: formHatFehler = alterFehler !== '' || notenFehler !== '' || sozialverhaltenFehler !== '' ||
|
||||
emailFehler !== '' || telefonFehler !== '' || notfallTelefonFehler !== '' || plzFehler !== '';
|
||||
|
||||
// Dienststellen laden wenn Zeitraum sich ändert
|
||||
async function ladeDienststellen(zeitraumId: string) {
|
||||
@@ -222,6 +322,10 @@
|
||||
alterFehler = '';
|
||||
notenFehler = '';
|
||||
sozialverhaltenFehler = '';
|
||||
emailFehler = '';
|
||||
telefonFehler = '';
|
||||
notfallTelefonFehler = '';
|
||||
plzFehler = '';
|
||||
dienststellen = [];
|
||||
}
|
||||
|
||||
@@ -300,10 +404,55 @@
|
||||
<input bind:value={geburtsdatum} type="date" placeholder="Geburtsdatum" required class="input" />
|
||||
<input bind:value={strasse} placeholder="Straße" required class="input" />
|
||||
<input bind:value={hausnummer} placeholder="Hausnummer" required class="input" />
|
||||
<input bind:value={plz} placeholder="Postleitzahl" required class="input" />
|
||||
|
||||
<!-- PLZ mit Validierung -->
|
||||
<div>
|
||||
<input
|
||||
bind:value={plz}
|
||||
placeholder="Postleitzahl"
|
||||
required
|
||||
class="input"
|
||||
class:input-error={plzFehler}
|
||||
maxlength="5"
|
||||
inputmode="numeric"
|
||||
/>
|
||||
{#if plzFehler}
|
||||
<p class="text-red-600 text-sm mt-1">{plzFehler}</p>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<input bind:value={ort} placeholder="Ort" required class="input" />
|
||||
<input bind:value={telefon} placeholder="Telefonnummer" required class="input col-span-2" />
|
||||
<input bind:value={email} type="email" placeholder="E-Mail-Adresse" required class="input col-span-2" />
|
||||
|
||||
<!-- Telefonnummer mit Validierung -->
|
||||
<div class="col-span-2">
|
||||
<input
|
||||
bind:value={telefon}
|
||||
type="tel"
|
||||
placeholder="Telefonnummer (z.B. 0511 1234567 oder 0171 1234567)"
|
||||
required
|
||||
class="input"
|
||||
class:input-error={telefonFehler}
|
||||
/>
|
||||
{#if telefonFehler}
|
||||
<p class="text-red-600 text-sm mt-1">{telefonFehler}</p>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<!-- E-Mail mit Validierung -->
|
||||
<div class="col-span-2">
|
||||
<input
|
||||
bind:value={email}
|
||||
type="email"
|
||||
placeholder="E-Mail-Adresse"
|
||||
required
|
||||
class="input"
|
||||
class:input-error={emailFehler}
|
||||
/>
|
||||
{#if emailFehler}
|
||||
<p class="text-red-600 text-sm mt-1">{emailFehler}</p>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<select bind:value={schulart} required class="input">
|
||||
<option value="" disabled selected hidden>Schulart wählen</option>
|
||||
<option value="Gymnasium">Gymnasium</option>
|
||||
@@ -423,6 +572,22 @@
|
||||
Lade verfügbare Dienststellen...
|
||||
</div>
|
||||
{:else}
|
||||
<!-- Hinweis wenn nur begrenzte Auswahl möglich -->
|
||||
{#if zeitraum && filteredDienststellen.length > 0 && filteredDienststellen.length < 3}
|
||||
<div class="p-3 bg-blue-50 border border-blue-200 rounded-xl">
|
||||
<div class="flex items-start">
|
||||
<svg class="w-5 h-5 text-blue-500 mr-2 mt-0.5 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
<p class="text-sm text-blue-700">
|
||||
Für diesen Zeitraum {filteredDienststellen.length === 1 ? 'ist nur noch 1 Dienststelle' : 'sind nur noch ' + filteredDienststellen.length + ' Dienststellen'} verfügbar.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- 1. Wunsch - immer anzeigen wenn Dienststellen vorhanden -->
|
||||
{#if filteredDienststellen.length >= 1}
|
||||
<select bind:value={wunsch1Id} required disabled={!zeitraum} class="input" class:opacity-50={!zeitraum}>
|
||||
<option value="" disabled selected>
|
||||
{zeitraum ? '1. Wunschdienststelle' : 'Bitte zuerst Zeitraum wählen'}
|
||||
@@ -431,14 +596,20 @@
|
||||
<option value={d.id}>{d.name} ({d.plaetze} {d.plaetze === 1 ? 'Platz' : 'Plätze'} frei)</option>
|
||||
{/each}
|
||||
</select>
|
||||
{/if}
|
||||
|
||||
<!-- 2. Wunsch - nur anzeigen wenn mindestens 2 Dienststellen verfügbar -->
|
||||
{#if filteredDienststellen.length >= 2}
|
||||
<select bind:value={wunsch2Id} required disabled={!zeitraum || !wunsch1Id} class="input" class:opacity-50={!zeitraum || !wunsch1Id}>
|
||||
<option value="" disabled selected>2. Wunschdienststelle</option>
|
||||
{#each filteredDienststellen.filter(d => d.id != wunsch1Id) as d}
|
||||
<option value={d.id}>{d.name} ({d.plaetze} {d.plaetze === 1 ? 'Platz' : 'Plätze'} frei)</option>
|
||||
{/each}
|
||||
</select>
|
||||
{/if}
|
||||
|
||||
<!-- 3. Wunsch - nur anzeigen wenn mindestens 3 Dienststellen verfügbar -->
|
||||
{#if filteredDienststellen.length >= 3}
|
||||
<select bind:value={wunsch3Id} required disabled={!zeitraum || !wunsch2Id} class="input" class:opacity-50={!zeitraum || !wunsch2Id}>
|
||||
<option value="" disabled selected>3. Wunschdienststelle</option>
|
||||
{#each filteredDienststellen.filter(d => d.id != wunsch1Id && d.id != wunsch2Id) as d}
|
||||
@@ -446,6 +617,7 @@
|
||||
{/each}
|
||||
</select>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
<!-- Hinweis wenn keine Dienststellen verfügbar -->
|
||||
{#if zeitraum && !isLoadingDienststellen && filteredDienststellen.length === 0}
|
||||
@@ -488,7 +660,21 @@
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<input bind:value={notfallVorname} placeholder="Vorname Notfallkontakt" required class="input" />
|
||||
<input bind:value={notfallNachname} placeholder="Nachname Notfallkontakt" required class="input" />
|
||||
<input bind:value={notfallTelefon} type="tel" placeholder="Mobilnummer Notfallkontakt" required class="input col-span-2" />
|
||||
|
||||
<!-- Notfall-Telefonnummer mit Validierung -->
|
||||
<div class="col-span-2">
|
||||
<input
|
||||
bind:value={notfallTelefon}
|
||||
type="tel"
|
||||
placeholder="Mobilnummer Notfallkontakt (z.B. 0171 1234567)"
|
||||
required
|
||||
class="input"
|
||||
class:input-error={notfallTelefonFehler}
|
||||
/>
|
||||
{#if notfallTelefonFehler}
|
||||
<p class="text-red-600 text-sm mt-1">{notfallTelefonFehler}</p>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -509,13 +695,13 @@
|
||||
<!-- Button - deaktiviert bei Validierungsfehlern oder fehlenden Pflichtfeldern -->
|
||||
<button
|
||||
type="submit"
|
||||
disabled={formHatFehler || !zeitraum || !wunsch1Id || !wunsch2Id || !wunsch3Id}
|
||||
disabled={formHatFehler || !zeitraum || !wuenscheVollstaendig}
|
||||
class="w-full py-3 rounded-xl transition-all"
|
||||
class:bg-blue-600={!formHatFehler && zeitraum && wunsch1Id && wunsch2Id && wunsch3Id}
|
||||
class:hover:bg-blue-700={!formHatFehler && zeitraum && wunsch1Id && wunsch2Id && wunsch3Id}
|
||||
class:text-white={!formHatFehler && zeitraum && wunsch1Id && wunsch2Id && wunsch3Id}
|
||||
class:bg-gray-400={formHatFehler || !zeitraum || !wunsch1Id || !wunsch2Id || !wunsch3Id}
|
||||
class:cursor-not-allowed={formHatFehler || !zeitraum || !wunsch1Id || !wunsch2Id || !wunsch3Id}
|
||||
class:bg-blue-600={!formHatFehler && zeitraum && wuenscheVollstaendig}
|
||||
class:hover:bg-blue-700={!formHatFehler && zeitraum && wuenscheVollstaendig}
|
||||
class:text-white={!formHatFehler && zeitraum && wuenscheVollstaendig}
|
||||
class:bg-gray-400={formHatFehler || !zeitraum || !wuenscheVollstaendig}
|
||||
class:cursor-not-allowed={formHatFehler || !zeitraum || !wuenscheVollstaendig}
|
||||
>
|
||||
Jetzt anmelden
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user