basic table and input validation
This commit is contained in:
parent
146ae2b11c
commit
58591364f1
|
|
@ -5,6 +5,8 @@
|
|||
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
%sveltekit.head%
|
||||
|
||||
<link rel="stylesheet" href="%sveltekit.assets%/global.css" />
|
||||
</head>
|
||||
<body data-sveltekit-preload-data="hover">
|
||||
<div style="display: contents">%sveltekit.body%</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
<script lang="ts">
|
||||
let { children } = $props();
|
||||
</script>
|
||||
|
||||
{@render children()}
|
||||
|
|
@ -1,2 +1,399 @@
|
|||
<h1>Welcome to SvelteKit</h1>
|
||||
<p>Visit <a href="https://svelte.dev/docs/kit">svelte.dev/docs/kit</a> to read the documentation</p>
|
||||
<script lang="ts">
|
||||
let { data } = $props();
|
||||
|
||||
const HEADERS: string[] = [ "Datum", "Wochentag", "Beginn", "Ende", "Dauer", "Anmerkung" ];
|
||||
|
||||
const TODAY: Date = new Date();
|
||||
const CENTURY_PREF: number = Math.floor(TODAY.getFullYear() / 100);
|
||||
const CENTURY_YEAR: number = CENTURY_PREF * 100;
|
||||
|
||||
let dateValid: boolean = $state(false);
|
||||
let startValid: boolean = $state(false);
|
||||
let endValid: boolean = $state(false);
|
||||
|
||||
function toInt(str: string): number {
|
||||
let value = 0;
|
||||
for (let i = 0; i < str.length; ++i) {
|
||||
let c = str.charAt(i);
|
||||
let n = Number(c);
|
||||
if (isNaN(n)) {
|
||||
return NaN;
|
||||
}
|
||||
value = value*10 + n;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
function validateDate(element: HTMLInputElement) {
|
||||
|
||||
/*
|
||||
supports:
|
||||
D.M
|
||||
|
||||
DDMM
|
||||
D.MM
|
||||
DD.M
|
||||
|
||||
DD.MM
|
||||
|
||||
DDMMYY
|
||||
D.M.YY
|
||||
|
||||
D.M.YYYY
|
||||
DD.MM.YY
|
||||
DDMMYYYY
|
||||
|
||||
DD.MM.YYYY
|
||||
*/
|
||||
|
||||
switch (element.value.length) {
|
||||
case 3: {
|
||||
/*
|
||||
* D.M
|
||||
*/
|
||||
|
||||
let day = toInt(element.value.charAt(0));
|
||||
let month = toInt(element.value.charAt(2));
|
||||
|
||||
if (isNaN(day) || isNaN(month) || element.value.charAt(1) !== '.') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (day > 0 && month > 0) {
|
||||
element.value = "0" + day + ".0" + month + "." + TODAY.getFullYear();
|
||||
return true;
|
||||
}
|
||||
} break;
|
||||
case 4: if (
|
||||
(() =>{
|
||||
/*
|
||||
* DDMM
|
||||
*/
|
||||
|
||||
let day = toInt(element.value.slice(0, 2));
|
||||
let month = toInt(element.value.slice(2, 4));
|
||||
|
||||
if (isNaN(day) || isNaN(month)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(month < 1 || month > 12
|
||||
|| day < 1 || day > new Date(TODAY.getFullYear(), month, 0).getDate())) {
|
||||
element.value = element.value.slice(0, 2) + "." + element.value.slice(2, 4) + "." + TODAY.getFullYear();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
})() === true
|
||||
|| (() => {
|
||||
/*
|
||||
* DD.M
|
||||
*/
|
||||
|
||||
let day = toInt(element.value.slice(0, 2));
|
||||
let month = toInt(element.value.charAt(3));
|
||||
|
||||
if (isNaN(day) || isNaN(month) || element.value.charAt(2) !== '.') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(month < 1 || month > 12
|
||||
|| day < 1 || day > new Date(TODAY.getFullYear(), month, 0).getDate())) {
|
||||
element.value = element.value.slice(0, 2) + ".0" + month + "." + TODAY.getFullYear();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
})() === true
|
||||
|| (() => {
|
||||
/*
|
||||
* D.MM
|
||||
*/
|
||||
|
||||
let day = toInt(element.value.charAt(0));
|
||||
let month = toInt(element.value.slice(2, 4));
|
||||
|
||||
if (isNaN(day) || isNaN(month) || element.value.charAt(1) !== '.') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(month < 1 || month > 12
|
||||
|| day < 1 || day > new Date(TODAY.getFullYear(), month, 0).getDate())) {
|
||||
element.value = "0" + day + "." + element.value.slice(2, 4) + "." + TODAY.getFullYear();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
})() === true) {
|
||||
return true;
|
||||
} break;
|
||||
case 5: {
|
||||
/*
|
||||
* DD.MM
|
||||
*/
|
||||
|
||||
let day = toInt(element.value.slice(0, 2));
|
||||
let month = toInt(element.value.slice(3, 5));
|
||||
|
||||
if (isNaN(day) || isNaN(month) || element.value.charAt(2) !== '.') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!((month < 1 || month > 12)
|
||||
|| (day < 1 || day > new Date(TODAY.getFullYear(), month, 0).getDate()))) {
|
||||
element.value = element.value + "." + TODAY.getFullYear();
|
||||
return true;
|
||||
}
|
||||
} break;
|
||||
case 6: if ((() => {
|
||||
/*
|
||||
* DDMMYY
|
||||
*/
|
||||
|
||||
let day = toInt(element.value.slice(0, 2));
|
||||
let month = toInt(element.value.slice(2, 4));
|
||||
let year = toInt(element.value.slice(4, 6));
|
||||
|
||||
if (isNaN(day) || isNaN(month) || isNaN(year)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
year += CENTURY_YEAR;
|
||||
|
||||
if (!(month < 1 || month > 12
|
||||
|| day < 1 || day > new Date(year, month, 0).getDate())) {
|
||||
element.value = element.value.slice(0, 2) + "." + element.value.slice(2, 4) + "." + CENTURY_PREF + element.value.slice(4, 6);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
})() === true
|
||||
|| (() => {
|
||||
/*
|
||||
* D.M.YY
|
||||
*/
|
||||
|
||||
let day = toInt(element.value.charAt(0));
|
||||
let month = toInt(element.value.charAt(2));
|
||||
let year = toInt(element.value.slice(4, 6));
|
||||
|
||||
if (isNaN(day) || isNaN(month) || isNaN(year) || element.value.charAt(1) !== '.' || element.value.charAt(3) !== '.') {
|
||||
return false;
|
||||
}
|
||||
|
||||
year += CENTURY_YEAR;
|
||||
|
||||
if (!(month < 1 || month > 12
|
||||
|| day < 1 || day > new Date(year, month, 0).getDate())) {
|
||||
element.value = "0" + day + ".0" + month + "." + CENTURY_PREF + element.value.slice(4, 6);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
})() === true) {
|
||||
return true;
|
||||
} break;
|
||||
case 8: if (
|
||||
(() => {
|
||||
/*
|
||||
* D.M.YYYY
|
||||
*/
|
||||
|
||||
let day = toInt(element.value.charAt(0));
|
||||
let month = toInt(element.value.charAt(2));
|
||||
let year = toInt(element.value.slice(4, 8));
|
||||
|
||||
if (isNaN(day) || isNaN(month) || isNaN(year) || element.value.charAt(1) !== '.' || element.value.charAt(3) !== '.') {
|
||||
return false;
|
||||
}
|
||||
|
||||
year += CENTURY_YEAR;
|
||||
|
||||
if (!(month < 1 || month > 12
|
||||
|| day < 1 || day > new Date(year, month, 0).getDate())) {
|
||||
element.value = "0" + day + ".0" + month + "." + element.value.slice(4, 8);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
})() === true
|
||||
|| (() => {
|
||||
/*
|
||||
* DD.MM.YY
|
||||
*/
|
||||
|
||||
let day = toInt(element.value.slice(0, 2));
|
||||
let month = toInt(element.value.slice(3, 5));
|
||||
let year = toInt(element.value.slice(6, 8));
|
||||
|
||||
if (isNaN(day) || isNaN(month) || isNaN(year) || element.value.charAt(2) !== '.' || element.value.charAt(5) !== '.') {
|
||||
return false;
|
||||
}
|
||||
|
||||
year += CENTURY_YEAR;
|
||||
|
||||
if (!(month < 1 || month > 12
|
||||
|| day < 1 || day > new Date(year, month, 0).getDate())) {
|
||||
element.value = element.value.slice(0, 2) + "." + element.value.slice(3, 5) + "." + CENTURY_PREF + element.value.slice(6, 8);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
})() === true
|
||||
|| (() => {
|
||||
/*
|
||||
* DDMMYYYY
|
||||
*/
|
||||
|
||||
let day = toInt(element.value.slice(0, 2));
|
||||
let month = toInt(element.value.slice(2, 4));
|
||||
let year = toInt(element.value.slice(4, 8));
|
||||
|
||||
if (isNaN(day) || isNaN(month) || isNaN(year)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(month < 1 || month > 12
|
||||
|| day < 1 || day > new Date(year, month, 0).getDate())) {
|
||||
element.value = element.value.slice(0, 2) + "." + element.value.slice(2, 4) + "." + element.value.slice(4, 8);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
})() === true) {
|
||||
return true;
|
||||
} break;
|
||||
case 10: {
|
||||
/*
|
||||
* DD.MM.YYYY
|
||||
*/
|
||||
|
||||
let day = toInt(element.value.slice(0, 2));
|
||||
let month = toInt(element.value.slice(3, 5));
|
||||
let year = toInt(element.value.slice(6, 10));
|
||||
|
||||
if (isNaN(day) || isNaN(month) || isNaN(year) || element.value.charAt(2) !== '.' || element.value.charAt(5) !== '.') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(month < 1 || month > 12
|
||||
|| day < 1 || day > new Date(year, month, 0).getDate())) {
|
||||
return true;
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
let entries: number[][] = [];
|
||||
|
||||
for (let i = 0; i < 50; ++i) {
|
||||
entries.push([i, i, i, i, i, i]);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<form id="form_new_entry" method="POST" action="?/new_entry"></form>
|
||||
|
||||
<table class="list">
|
||||
<caption>Stundenliste</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
{#each HEADERS as header}
|
||||
<th>{header}</th>
|
||||
{/each}
|
||||
<!--
|
||||
<th>Datum</th>
|
||||
<th>Wochentag</th>
|
||||
<th>Beginn</th>
|
||||
<th>Ende</th>
|
||||
<th>Dauer</th>
|
||||
<th>Anmerkung</th>
|
||||
-->
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<input
|
||||
class="text-input"
|
||||
class:form-invalid={!dateValid}
|
||||
name="Datum"
|
||||
type="text"
|
||||
form="form_new_entry"
|
||||
onfocusin={
|
||||
(event) => {
|
||||
(event.target as HTMLInputElement).select();
|
||||
dateValid = true;
|
||||
}
|
||||
}
|
||||
onfocusout={
|
||||
(event) => {
|
||||
dateValid = validateDate(event.target as HTMLInputElement);
|
||||
}
|
||||
}
|
||||
required>
|
||||
</td>
|
||||
</tr>
|
||||
{#each entries as entry}
|
||||
<!--<tr><td>{entry}</td></tr>-->
|
||||
<tr>
|
||||
{#each entry as i}
|
||||
<td>{i}</td>
|
||||
{/each}
|
||||
</tr>
|
||||
{/each}
|
||||
<tr></tr>
|
||||
</tbody>
|
||||
{#if entries === undefined || entries.length === 0}
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td class="td-no-elements" colspan="999">No elements</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
{/if}
|
||||
</table>
|
||||
|
||||
<style>
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
|
||||
border-collapse: collapse;
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
table caption {
|
||||
font-size: 25px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
th {
|
||||
width: 70px;
|
||||
}
|
||||
|
||||
tbody * {
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
tbody tr:nth-child(odd) {
|
||||
background: gray;
|
||||
}
|
||||
|
||||
tbody tr:nth-child(even) {
|
||||
background: lightgray;
|
||||
}
|
||||
|
||||
.td-no-elements {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.text-input {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.form-invalid {
|
||||
background: #FF4444;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
body {
|
||||
background: #BBBBBB;
|
||||
}
|
||||
|
||||
/*body * {
|
||||
color: white;
|
||||
} */
|
||||
Loading…
Reference in New Issue