f047_Edit-der-Namen #15
@@ -1,7 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Edit from '$lib/icons/Edit.svelte';
|
import Edit from '$lib/icons/Edit.svelte';
|
||||||
import Trash from '$lib/icons/Trash.svelte';
|
import Trash from '$lib/icons/Trash.svelte';
|
||||||
import { createEventDispatcher } from 'svelte';
|
|
||||||
import { validateInput } from '$lib/helper/error-utils';
|
import { validateInput } from '$lib/helper/error-utils';
|
||||||
|
|
||||||
interface ListItem {
|
interface ListItem {
|
||||||
@@ -10,39 +9,45 @@
|
|||||||
// add other properties as needed
|
// add other properties as needed
|
||||||
}
|
}
|
||||||
|
|
||||||
export let value: string = '';
|
type Variant = '' | 'casename' | 'crimename';
|
||||||
export let variant: '' | 'casename' | 'crimename' = ''; // casename | crimename
|
|
||||||
|
export let inputValue: string = '';
|
||||||
|
export let variant: Variant = '';
|
||||||
export let existings: ListItem[];
|
export let existings: ListItem[];
|
||||||
export let id: number;
|
export let id: number;
|
||||||
export let editable: boolean = true;
|
export let editable: boolean = true;
|
||||||
export let editing: boolean;
|
export let editing: boolean;
|
||||||
|
|
||||||
console.log('Debug editing', editing);
|
//CustomEvents:
|
||||||
|
export let editStart: (payload: {
|
||||||
|
id: number;
|
||||||
|
inputValue: string;
|
||||||
|
variant: Variant;
|
||||||
|
editing: boolean;
|
||||||
|
}) => void;
|
||||||
|
|
||||||
|
export let save: (payload: { newValue: string; oldValue: string; variant: Variant }) => void;
|
||||||
|
export let deleteItem: (payload: {
|
||||||
|
inputValue: string;
|
||||||
|
variant: Variant;
|
||||||
|
customEvent: Event;
|
||||||
|
}) => void;
|
||||||
|
export let cancel: () => void = () => {};
|
||||||
const existingNames = existings.map((item) => item.name);
|
const existingNames = existings.map((item) => item.name);
|
||||||
|
|
||||||
const dispatch = createEventDispatcher<{
|
export { classNames as class };
|
||||||
editSart: {};
|
|
||||||
save: {};
|
|
||||||
delete: {};
|
|
||||||
cancel: void;
|
|
||||||
}>();
|
|
||||||
|
|
||||||
let internalValue = value;
|
let internalValue = inputValue;
|
||||||
let oldValue = value;
|
let oldValue = inputValue;
|
||||||
let showWarning = false;
|
let showWarning = false;
|
||||||
let duplicate = false;
|
|
||||||
|
|
||||||
let errors: string[] = [];
|
|
||||||
let errorText = '';
|
|
||||||
|
|
||||||
$: errors = validateInput(oldValue, internalValue, { minLength: 3, existingNames });
|
$: errors = validateInput(oldValue, internalValue, { minLength: 3, existingNames });
|
||||||
|
|
||||||
function startEdit() {
|
function startEdit() {
|
||||||
oldValue = value;
|
oldValue = inputValue;
|
||||||
internalValue = value;
|
internalValue = inputValue;
|
||||||
editing = true;
|
editing = true;
|
||||||
dispatch('editSart', { id, value, variant, editing });
|
editStart({ id, inputValue, variant, editing });
|
||||||
}
|
}
|
||||||
|
|
||||||
function cancelEdit() {
|
function cancelEdit() {
|
||||||
@@ -52,7 +57,7 @@
|
|||||||
|
|
||||||
console.log('Abgebrochen');
|
console.log('Abgebrochen');
|
||||||
|
|
||||||
dispatch('cancel');
|
cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveEdit(ev?: MouseEvent | KeyboardEvent) {
|
function saveEdit(ev?: MouseEvent | KeyboardEvent) {
|
||||||
@@ -80,13 +85,7 @@
|
|||||||
|
|
||||||
editing = false;
|
editing = false;
|
||||||
showWarning = false;
|
showWarning = false;
|
||||||
duplicate = false;
|
save({ newValue: internalValue, oldValue, variant });
|
||||||
|
|
||||||
dispatch('save', { newValue: internalValue, oldValue, variant });
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteItem() {
|
|
||||||
dispatch('delete', { value, variant });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleKey(e: KeyboardEvent) {
|
function handleKey(e: KeyboardEvent) {
|
||||||
@@ -95,23 +94,27 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="" {...$$restProps}>
|
<div class="">
|
||||||
<div class="flex gap-x-2">
|
<div class="flex gap-x-2">
|
||||||
{#if editing}
|
{#if editing}
|
||||||
<input
|
<input
|
||||||
bind:value={internalValue}
|
bind:value={internalValue}
|
||||||
on:keydown={handleKey}
|
on:keydown|preventDefault={handleKey}
|
||||||
on:blur|preventDefault|stopPropagation={cancelEdit}
|
on:blur|preventDefault|stopPropagation={cancelEdit}
|
||||||
class=""
|
class=""
|
||||||
class:bg-red-200={(showWarning && editing) || errors.length !== 0}
|
class:bg-red-200={(showWarning && editing) || errors.length !== 0}
|
||||||
/>
|
/>
|
||||||
{:else}
|
{:else}
|
||||||
<span>{value}</span>
|
<span>{inputValue}</span>
|
||||||
{#if !editing && editable}
|
{#if !editing && editable}
|
||||||
<button on:click|preventDefault|stopPropagation={startEdit}>
|
<button on:click|preventDefault|stopPropagation={startEdit}>
|
||||||
<Edit />
|
<Edit />
|
||||||
</button>
|
</button>
|
||||||
<button on:click|preventDefault={deleteItem}>
|
<button
|
||||||
|
on:click|preventDefault={(e: Event) => {
|
||||||
|
deleteItem({ inputValue, variant, customEvent: e });
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Trash />
|
<Trash />
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -1,9 +1,27 @@
|
|||||||
export function validateInput(oldValue:string, value: string, options: { minLength?: number; existingNames?: string[] }) {
|
/**
|
||||||
|
*
|
||||||
|
* @param oldValue
|
||||||
|
* @param inputValue
|
||||||
|
* @param options
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function validateNameInput(oldValue:string, inputValue: string, options: { minLength?: number; existingNames?: string[] }) {
|
||||||
const errors: string[] = [];
|
const errors: string[] = [];
|
||||||
|
|
|||||||
|
|
||||||
if (!value.trim()) errors.push('Feld darf nicht leer sein');
|
if (!inputValue.trim()) errors.push('Feld darf nicht leer sein');
|
||||||
if (options.existingNames?.includes(value) && oldValue !== value)
|
if (options.existingNames?.includes(inputValue) && oldValue !== inputValue)
|
||||||
errors.push('Name existiert bereits');
|
errors.push('Name existiert bereits');
|
||||||
|
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// siehe suche: fail
|
||||||
|
|
||||||
|
// Button
|
||||||
|
// BaseInputField
|
||||||
|
|
||||||
|
// fetch siehe b038
|
||||||
|
|
||||||
|
// api/list/vorgang/tatort/server.ts
|
||||||
|
// api/list/vorgang/server.ts
|
||||||
|
|||||||
@@ -60,15 +60,17 @@
|
|||||||
<EditableItem
|
<EditableItem
|
||||||
class=""
|
class=""
|
||||||
id={i}
|
id={i}
|
||||||
value={item.name}
|
inputValue={item.name}
|
||||||
editing={editingId === i}
|
editing={editingId === i}
|
||||||
on:editStart={() => (editingId = i)}
|
editStart={() => (editingId = i)}
|
||||||
variant="casename"
|
variant="casename"
|
||||||
existings={caseList}
|
existings={caseList}
|
||||||
on:save={(e) => console.log('Gespeichert:', e.detail)}
|
save={(data) => {
|
||||||
on:delete={(e) => {
|
console.log('Gespeichert:', data);
|
||||||
console.log('Gelöscht:', e.detail);
|
}}
|
||||||
delete_item(e);
|
deleteItem={(data) => {
|
||||||
|
console.log('Gelöscht:', data);
|
||||||
|
delete_item(data.customEvent);
|
||||||
}}
|
}}
|
||||||
></EditableItem>
|
></EditableItem>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -134,13 +134,13 @@
|
|||||||
<EditableItem
|
<EditableItem
|
||||||
class="bg-lred-500"
|
class="bg-lred-500"
|
||||||
id={i}
|
id={i}
|
||||||
value={item.name}
|
inputValue={item.name}
|
||||||
editing={editingId === i}
|
editing={editingId === i}
|
||||||
on:editStart={() => (editingId = i)}
|
editStart={() => (editingId = i)}
|
||||||
variant="crimename"
|
variant="crimename"
|
||||||
existings={crimesList}
|
existings={crimesList}
|
||||||
on:save={(e) => console.log('Gespeichert:', e.detail)}
|
save={(e) => console.log('Gespeichert:', e)}
|
||||||
on:delete={(e) => console.log('Gelöscht:', e.detail)}
|
deleteItem={(e) => console.log('Gelöscht:', e)}
|
||||||
></EditableItem>
|
></EditableItem>
|
||||||
{:else}
|
{:else}
|
||||||
<span class="text-sm font-semibold leading-6 text-gray-900 inline-block min-w-1"
|
<span class="text-sm font-semibold leading-6 text-gray-900 inline-block min-w-1"
|
||||||
|
|||||||
Reference in New Issue
Block a user
Grundsätzlich wird hier der Value in diesem Fall ein Name validiert. Es ist keine generische validateInput Funktion. Daher sollte sie entsprechend benannt werden. Darüber hinaus wird sie nur in EditableItem verwendet. Daher ist ggf. ein Auslagern nicht sinnvoll, oder soll sie noch wo anders verwendet werden?
Werde ich nochmal überarbeiten