Beispiel:JS-WebStorage-TodoList.html
Aus SELFHTML-Wiki
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0;" />
<link rel="stylesheet" media="screen" href="./Beispiel:SELFHTML-Beispiel-Grundlayout.css" />
<style>
main {
display: grid;
grid: "head head" auto
"liste form" 1fr / 1fr auto;
column-gap: 2em;
}
main > h2:first-of-type {
grid-area: head;
}
#todo {
grid-area: liste;
}
form {
width: 15em;
grid-area: form;
}
.todo-form button, label, input {
width: 90%;
padding: 0.2em;
margin: 0.2em;
}
input {
width: 86%;
margin-bottom: 2em;
}
ul.todo-list {
margin-top: 0.5em;
padding: 2px;
list-style-type: none;
background-color: #a9a9a9;
border-radius: 0.25em;
}
ul.todo-list.empty::before { display: block; text-align: center; content: "Die Liste ist leer"; }
ul.todo-list li {
margin: 0 0 2px 0;
}
ul.todo-list li button {
padding: 0.5em;
width: 100%;
text-align: left;
border:none;
}
ul.todo-list li:last-child {
margin-bottom: 0;
}
ul.todo-list li:first-child button {
border-radius: 0.25em 0.25em 0 0;
}
ul.todo-list li:last-child button {
border-radius: 0 0 0.25em 0.25em;
}
</style>
<script>
document.addEventListener("DOMContentLoaded", function() {
todoListe(document.forms[0], document.querySelector(".todo-list"));
});
const defaultOptions = {
entryClass: 'todo-entry',
createClass: 'todo-create',
clearClass: 'todo-clear',
idPrefix: 'todoItem-',
storageName: 'todoListe'
};
function todoListe(todoForm, domListe, options) {
let configuration = Object.create(defaultOptions);
for (let opt in options) {
if (defaultOptions.hasOwnPropertyName(opt))
configurations[opt] = options[opt];
}
if (!(todoForm instanceof HTMLFormElement) || !(isList(domListe)) )
throw new Error("Eingabe-Form und Anzeigeliste fehlen");
const entryField = todoForm.querySelector(`input[type=text].${configuration.entryClass}`);
const createButton = todoForm.querySelector(`button.${configuration.createClass}`);
const clearButton = todoForm.querySelector(`button.${configuration.clearClass}`);
if (!entryField || !createButton || !clearButton)
throw new Error("Eingabeformular der Todo-Liste inkorrekt oder unvollständig");
todoForm.addEventListener("submit", todoHinzufügen);
clearButton.addEventListener("click", todoListeLöschen);
domListe.addEventListener("click", todoEntfernen);
let todoListe;
ladeTodoListe();
todoListe.forEach(eintrag => todoInsDOM(eintrag));
markiereLeereListe();
entryField.focus();
function isList(element) {
return element && (element instanceof HTMLUListElement || element instanceof HTMLOListElement);
}
function todoHinzufügen(submitEvent) {
submitEvent.preventDefault();
const todo = erzeugeTodo(entryField.value.trim());
if (!todo) {
alert("Bitte geben Sie etwas ein!");
return; // Leerer Eintrag
}
if (todoListe.find(eintrag => eintrag.text == todo.text)) {
alert("Das steht schon auf der Liste!");
return; // Duplikat
}
todoListe.push(todo);
todoInsDOM(todo);
markiereLeereListe();
speichereTodoListe();
entryField.value = '';
entryField.focus();
}
function todoEntfernen(clickEvent) {
const domItem = clickEvent.target.closest("li");
if (!domItem.id.startsWith(configuration.idPrefix)) {
alert("Das ist kein Todo-Eintrag!");
return;
}
const todoId = parseInt(domItem.id.substring(configuration.idPrefix.length));
domItem.remove();
markiereLeereListe();
todoListe = todoListe.filter(eintrag => eintrag.id != todoId);
speichereTodoListe();
entryField.focus();
}
function todoListeLöschen() {
todoListe = [];
domListe.innerHTML = "";
markiereLeereListe();
speichereTodoListe();
entryField.focus();
}
function ladeTodoListe() {
let einträgeJson = localStorage.getItem(configuration.storageName);
todoListe = einträgeJson ? JSON.parse(einträgeJson) : [];
}
function speichereTodoListe() {
if (todoListe.length > 0)
localStorage.setItem(configuration.storageName, JSON.stringify(todoListe));
else
localStorage.removeItem(configuration.storageName);
}
function markiereLeereListe() {
domListe.classList.toggle("empty", todoListe.length == 0);
}
function erzeugeTodo(text) {
return text ? { id: Date.now(), text } : null;
}
function todoInsDOM(eintrag) {
const domItem = document.createElement("li");
domItem.id = `${configuration.idPrefix}${eintrag.id}`;
domItem.innerHTML = `<button type='button'>${eintrag.text}</button>`;
domListe.appendChild(domItem);
}
}
</script>
<title>Beispiel: localStorage</title>
</head>
<body>
<h1>HTML5 localStorage</h1>
<main>
<h2>ToDo-Liste</h2>
<form class="todo-form">
<label for="eingabe">neues Projekt hinzufügen:</label>
<input id="eingabe" class="todo-entry" value="" type="text">
<button class="todo-create" id="mehr">neuen Eintrag hinzufügen</button>
<button type="button" class="todo-clear" id="loeschen">alle Einträge löschen </button>
</form>
<section id="todo">
<p>Klicken Sie auf die Einträge, um sie zu entfernen.</p>
<ul class="empty todo-list"></ul>
</section>
</main>
</body>
</html>