2024-12-25 01:48:49 +01:00
|
|
|
<script lang="ts">
|
|
|
|
|
let { data } = $props();
|
|
|
|
|
|
2024-12-26 00:14:02 +01:00
|
|
|
const WEEKDAYS: string[] = [ "Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag" ]
|
|
|
|
|
|
2024-12-25 01:48:49 +01:00
|
|
|
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;
|
2024-12-26 00:14:02 +01:00
|
|
|
|
|
|
|
|
let dateInput: HTMLInputElement;
|
|
|
|
|
let startInput: HTMLInputElement;
|
|
|
|
|
let endInput: HTMLInputElement;
|
2024-12-25 01:48:49 +01:00
|
|
|
|
2024-12-26 00:14:02 +01:00
|
|
|
let dateValid: boolean = $state(true);
|
|
|
|
|
let startValid: boolean = $state(true);
|
|
|
|
|
let endValid: boolean = $state(true);
|
|
|
|
|
|
|
|
|
|
let inWeekDay: string = $state("");
|
|
|
|
|
let inDuration: string = $state("");
|
2024-12-25 01:48:49 +01:00
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-26 00:14:02 +01:00
|
|
|
function parseDate(str: string): Date | null {
|
|
|
|
|
if (str.length != 2+1+2+1+4) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let day = toInt(str.slice(0, 2))
|
|
|
|
|
let month = toInt(str.slice(3, 5));
|
|
|
|
|
let year = toInt(str.slice(6, 10));
|
|
|
|
|
|
|
|
|
|
if (isNaN(day) || isNaN(month) || isNaN(year) || str.charAt(2) !== '.' || str.charAt(5) !== '.') {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let date = new Date(year, month-1, day);
|
|
|
|
|
|
|
|
|
|
if (isNaN(date.valueOf())) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return date;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function validateForm(event: Event): boolean {
|
|
|
|
|
let valid = dateValid && dateInput.value.length !== 0
|
|
|
|
|
&& startValid && startInput.value.length !== 0
|
|
|
|
|
&& endValid && endInput.value.length !== 0;
|
|
|
|
|
|
|
|
|
|
if (!valid) {
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
}
|
|
|
|
|
return valid;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-25 01:48:49 +01:00
|
|
|
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) {
|
2024-12-26 00:14:02 +01:00
|
|
|
case 0: return true;
|
2024-12-25 01:48:49 +01:00
|
|
|
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;
|
|
|
|
|
}
|
2024-12-26 00:14:02 +01:00
|
|
|
|
|
|
|
|
function validateTime(element: HTMLInputElement): boolean {
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
supports:
|
|
|
|
|
|
|
|
|
|
H:MM
|
|
|
|
|
HHMM
|
|
|
|
|
HH:MM
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
switch(element.value.length) {
|
|
|
|
|
case 0: return true;
|
|
|
|
|
case 4: if (
|
|
|
|
|
(() => {
|
|
|
|
|
let h = toInt(element.value.slice(0, 2));
|
|
|
|
|
let m = toInt(element.value.slice(2, 4));
|
|
|
|
|
|
|
|
|
|
if (isNaN(h) || isNaN(m)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (0 <= h && h <= 24 && 0 <= m && m <= 59) {
|
|
|
|
|
element.value = element.value.slice(0, 2) + ":" + element.value.slice(2, 4);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
})() === true
|
|
|
|
|
|| (() => {
|
|
|
|
|
let h = toInt(element.value.charAt(0));
|
|
|
|
|
let m = toInt(element.value.slice(2, 4));
|
|
|
|
|
|
|
|
|
|
if (isNaN(h) || isNaN(m) || element.value.charAt(1) !== ':') {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (0 <= m && m <= 59) {
|
|
|
|
|
element.value = "0" + element.value;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
})() === true) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
case 5: {
|
|
|
|
|
let h = toInt(element.value.slice(0, 2));
|
|
|
|
|
let m = toInt(element.value.slice(3, 5));
|
|
|
|
|
|
|
|
|
|
if (isNaN(h) || isNaN(m) || element.value.charAt(2) !== ':') {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (0 <= h && h <= 24 && 0 <= m && m <= 59) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
} break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function calculateDuration(start: string, end: string): string {
|
|
|
|
|
|
|
|
|
|
if (start.length !== 5 || end.length !== 5) {
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let start_h = toInt(start.slice(0, 2));
|
|
|
|
|
let start_m = toInt(start.slice(3, 5));
|
|
|
|
|
|
|
|
|
|
let end_h = toInt(end.slice(0, 2));
|
|
|
|
|
let end_m = toInt(end.slice(3, 5));
|
|
|
|
|
|
|
|
|
|
if (isNaN(start_h) || isNaN(start_m) || start.charAt(2) !== ':'
|
|
|
|
|
|| isNaN(end_h) || isNaN(end_m) || end.charAt(2) !== ':') {
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let start_n = start_h * 60 + start_m;
|
|
|
|
|
let end_n = end_h * 60 + end_m;
|
|
|
|
|
|
|
|
|
|
let duration = (end_n - start_n) / 60;
|
|
|
|
|
|
|
|
|
|
return duration.toFixed(2);
|
|
|
|
|
}
|
2024-12-25 01:48:49 +01:00
|
|
|
|
|
|
|
|
let entries: number[][] = [];
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < 50; ++i) {
|
2024-12-26 00:14:02 +01:00
|
|
|
entries.push([i, i, i, i, i, i, i*i]);
|
2024-12-25 01:48:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
</script>
|
|
|
|
|
|
2024-12-26 00:14:02 +01:00
|
|
|
<div class="wrap">
|
|
|
|
|
|
|
|
|
|
<form id="form_new_entry" method="POST" action="?/new_entry" onsubmit={validateForm}></form>
|
2024-12-25 01:48:49 +01:00
|
|
|
|
|
|
|
|
<table class="list">
|
|
|
|
|
<caption>Stundenliste</caption>
|
2024-12-26 00:14:02 +01:00
|
|
|
|
2024-12-25 01:48:49 +01:00
|
|
|
<thead>
|
|
|
|
|
<tr>
|
2024-12-26 00:14:02 +01:00
|
|
|
<th style:width="20ch">Datum</th>
|
|
|
|
|
<th style:width="25ch">Wochentag</th>
|
|
|
|
|
<th style:width="12ch">Beginn</th>
|
|
|
|
|
<th style:width="12ch">Ende</th>
|
|
|
|
|
<th style:width="12ch">Dauer</th>
|
2024-12-25 01:48:49 +01:00
|
|
|
<th>Anmerkung</th>
|
2024-12-26 00:14:02 +01:00
|
|
|
<th style:width="fit-content">Actions</th>
|
2024-12-25 01:48:49 +01:00
|
|
|
</tr>
|
|
|
|
|
</thead>
|
|
|
|
|
<tbody>
|
|
|
|
|
<tr>
|
|
|
|
|
<td>
|
|
|
|
|
<input
|
2024-12-26 00:14:02 +01:00
|
|
|
bind:this={dateInput}
|
2024-12-25 01:48:49 +01:00
|
|
|
class:form-invalid={!dateValid}
|
2024-12-26 00:14:02 +01:00
|
|
|
name="date"
|
2024-12-25 01:48:49 +01:00
|
|
|
type="text"
|
|
|
|
|
form="form_new_entry"
|
|
|
|
|
onfocusin={
|
2024-12-26 00:14:02 +01:00
|
|
|
(_) => {
|
|
|
|
|
dateInput.select();
|
2024-12-25 01:48:49 +01:00
|
|
|
dateValid = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
onfocusout={
|
2024-12-26 00:14:02 +01:00
|
|
|
(_) => {
|
|
|
|
|
dateValid = validateDate(dateInput);
|
|
|
|
|
if (dateValid) {
|
|
|
|
|
inWeekDay = WEEKDAYS[parseDate(dateInput.value)!.getDay()];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
required>
|
|
|
|
|
</td>
|
|
|
|
|
|
|
|
|
|
<td>
|
|
|
|
|
{inWeekDay}
|
|
|
|
|
</td>
|
|
|
|
|
|
|
|
|
|
<td>
|
|
|
|
|
<input
|
|
|
|
|
bind:this={startInput}
|
|
|
|
|
class:form-invalid={!startValid}
|
|
|
|
|
name="starttime"
|
|
|
|
|
type="text"
|
|
|
|
|
form="form_new_entry"
|
|
|
|
|
onfocusin={
|
|
|
|
|
(_) => {
|
|
|
|
|
startInput.select();
|
|
|
|
|
startValid = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
onfocusout={
|
|
|
|
|
(_) => {
|
|
|
|
|
startValid = validateTime(startInput);
|
|
|
|
|
inDuration = calculateDuration(startInput.value, endInput.value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
required>
|
|
|
|
|
</td>
|
|
|
|
|
|
|
|
|
|
<td>
|
|
|
|
|
<input
|
|
|
|
|
bind:this={endInput}
|
|
|
|
|
class:form-invalid={!endValid}
|
|
|
|
|
name="endtime"
|
|
|
|
|
type="text"
|
|
|
|
|
form="form_new_entry"
|
|
|
|
|
onfocusin={
|
|
|
|
|
(_) => {
|
|
|
|
|
endInput.select();
|
|
|
|
|
endValid = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
onfocusout={
|
|
|
|
|
(_) => {
|
|
|
|
|
endValid = validateTime(endInput);
|
|
|
|
|
inDuration = calculateDuration(startInput.value, endInput.value);
|
2024-12-25 01:48:49 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
required>
|
|
|
|
|
</td>
|
2024-12-26 00:14:02 +01:00
|
|
|
|
|
|
|
|
<td>
|
|
|
|
|
{inDuration}
|
|
|
|
|
</td>
|
|
|
|
|
|
|
|
|
|
<td>
|
|
|
|
|
<input
|
|
|
|
|
name="comment"
|
|
|
|
|
type="text"
|
|
|
|
|
form="form_new_entry">
|
|
|
|
|
</td>
|
|
|
|
|
|
|
|
|
|
<td>
|
|
|
|
|
<button
|
|
|
|
|
type="submit"
|
|
|
|
|
form="form_new_entry">
|
|
|
|
|
+
|
|
|
|
|
</button>
|
|
|
|
|
</td>
|
|
|
|
|
|
2024-12-25 01:48:49 +01:00
|
|
|
</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>
|
|
|
|
|
|
2024-12-26 00:14:02 +01:00
|
|
|
</div>
|
|
|
|
|
|
2024-12-25 01:48:49 +01:00
|
|
|
<style>
|
|
|
|
|
|
|
|
|
|
table {
|
2024-12-26 00:14:02 +01:00
|
|
|
width: 80%;
|
|
|
|
|
margin: auto;
|
2024-12-25 01:48:49 +01:00
|
|
|
|
|
|
|
|
border-collapse: collapse;
|
|
|
|
|
border: 1px solid;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
table caption {
|
|
|
|
|
font-size: 25px;
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tbody * {
|
|
|
|
|
border: 1px solid;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-26 00:14:02 +01:00
|
|
|
tbody tr:nth-child(even) {
|
2024-12-25 01:48:49 +01:00
|
|
|
background: gray;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-26 00:14:02 +01:00
|
|
|
tbody tr:nth-child(odd) {
|
2024-12-25 01:48:49 +01:00
|
|
|
background: lightgray;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-26 00:14:02 +01:00
|
|
|
td input {
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
width: 100%;
|
2024-12-25 01:48:49 +01:00
|
|
|
|
|
|
|
|
border: none;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-26 00:14:02 +01:00
|
|
|
.td-no-elements {
|
|
|
|
|
text-align: center;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-25 01:48:49 +01:00
|
|
|
.form-invalid {
|
|
|
|
|
background: #FF4444;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
</style>
|