Beispiel:JS-DOM-Tut-8.html

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche
<!DOCTYPE html>
<html lang="de">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>ToDo-Liste - 3</title>
  <link rel="stylesheet" media="screen" href="./Beispiel:SELFHTML-Beispiel-Grundlayout.css">  
<style>
ul {list-style-type:none;}
li {
	width: 20em;
	display: grid;
	grid-template-columns: 1.5em 1fr 2em;
	margin: 0;
	
	input {width: 0; height: 0; font-size:0; margin:0;}
	label {
	  background: gainsboro;
	  border: thin solid grey;
	  grid-column: 1/-1;
	  grid-row: 1/2;
	  padding:0.5em;
	  display:grid;
	  grid-template-columns: 1.5em 1fr;
	}	
	input:checked ~ label {background: #d4e3b5;}
	input:checked ~ label:before {
		font-size:1.5em; line-height: 1.15rem;
		content: "✓ ";
		color:green;
	  grid-column: 1/2;
	  grid-row: 1/2;		
	}
	.text {	  
		grid-column: 2/3;
		grid-row: 1/2;	
	}
	button {
		background: transparent;
		background-repeat: no-repeat;
		background-size: contain;
		border: none;
		padding: 0;
		margin: 0;
		width: 2rem;
		aspect-ratio: 1/1;
		font-size: 0;
		color:transparent;
		grid-column: -2/-1;
		grid-row: 1/2;
	}
	[commandfor=editSettings]{
		background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='-98 -98 196 196'%3E%3Cpath id='cog' d='m-17,-55 l5-17 h20 l5,17z' style='fill:steelblue;stroke:steelBlue; stroke-width:15;stroke-linejoin:round;'/%3E%3Cuse href='%23cog' transform='rotate(60)' /%3E%3Cuse href='%23cog' transform='rotate(120)' /%3E%3Cuse href='%23cog' transform='rotate(180)' /%3E%3Cuse href='%23cog' transform='rotate(240)' /%3E%3Cuse href='%23cog' transform='rotate(300)' /%3E%3Ccircle r='45' style='fill:none;stroke:steelblue; stroke-width:30'/%3E%3C/svg%3E");	
	}	
}

dialog {
	position: relative;
	padding: 2em 2em 1em 1em;
	button {
		font-size: 0;
		color: transparent;
		width: 2rem;
		aspect-ratio: 1 / 1;	
	}
	
.save-button {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 480 499' style='fill:none; stroke:steelBlue;stroke-width:25' %3E%3Crect x='150' y='60' rx='10' width='180' height='100' /%3E%3Crect x='130' y='280' rx='10' width='220' height='175' /%3E%3Cpath id='outer' d='m40,80 a20,20 1,0,1 20-20 h280 a20,20 1,0,1 15,10 l90,90 v275 a 20,20 1,0,1 -20,20 h-365 a 20,20 1,0,1 -20-20 z'/%3E%3C/svg%3E");
}	
.delete-button {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 499 499' style='fill:none; stroke:steelBlue;stroke-width:25' %3E%3Crect width='100%25' height='100%25' style='fill:none;stroke:%23132c39; stroke-width:1' /%3E%3Cpath id='handle' d='m169,70 v-40 h150 v40'/%3E%3Crect x='64' y='100' rx='10' width='365' height='80'/%3E%3Cpath d='m99,180 l40,280 h220 l40,-280 m-235,75 l15,160 m70,0 v-160 m80,0 l-15,160'/%3E%3C/svg%3E");
	}
	p {text-align: right;}
} 
dialog::backdrop { 
  background: hsl(201 50% 40% /.5) ;
}

.planned label {
  background: LightYellow ;
}
.in-work label {
  background: salmon;
}
.finished label {
  background: #d4e3b5;;
}

li:first-of-type {
  border-radius: 0.5em 0.5em 0 0;
}
li:last-of-type {
  border-bottom-left-radius: 0.5em;
	border-bottom-right-radius: 0.5em;
}
</style>
<script>
  'use strict';
document.addEventListener('DOMContentLoaded', function () {
    const taskList = document.querySelector('#taskList');
    const newTaskInput = document.querySelector('#newtask');
    const addButton = document.querySelector('#add');
    const editDialog = document.querySelector('#editSettings');
    const editTextInput = document.querySelector('#editText');
    const saveButton = document.querySelector('.save-button');
    const deleteButton = document.querySelector('.delete-button');
    const statusDropdown = document.querySelector('.status-dropdown');
    let selectedTask = null;
    let taskIdCounter = 0;

    // Add new task
    addButton.addEventListener('click', function () {
        const taskText = newTaskInput.value.trim();
        if (!taskText) {
            alert('Bitte gib eine Aufgabe ein.');
            return;
        }

        const taskId = `todo-${taskIdCounter++}`;
        taskList.insertAdjacentHTML('beforeend', `
            <li class="planned"> <!-- Default to "planned" -->
                <input type="checkbox" id="${taskId}">
                <label for="${taskId}">
                    <span class="text">${taskText}</span>
                </label>
                <button aria-label="Edit task: ${taskText}" command="show-modal" commandfor="editSettings">Bearbeiten</button>
            </li>
        `);
        newTaskInput.value = '';
    });

    // Open edit dialog & load data
    document.addEventListener('click', function (event) {
        const editButton = event.target.closest('[commandfor="editSettings"]');
        if (!editButton) return;

        selectedTask = editButton.closest('li');
        if (selectedTask) {
            const taskText = selectedTask.querySelector('.text').textContent;
            editTextInput.value = taskText;

            // Load current status
            const currentStatus = selectedTask.classList.contains('in-work')
                ? 'in-work'
                : selectedTask.classList.contains('finished')
                ? 'finished'
                : 'planned';

            statusDropdown.value = currentStatus;
            statusDropdown.disabled = selectedTask.classList.contains('finished'); // Disable if finished
        }
    });

    // Save edited text and status
    saveButton.addEventListener('click', function () {
        if (selectedTask) {
            selectedTask.querySelector('.text').textContent = editTextInput.value;

            // Update task status
            selectedTask.classList.remove('planned', 'in-work', 'finished');
            selectedTask.classList.add(statusDropdown.value);
        }
        editDialog.close();
    });

    // Confirm delete
    deleteButton.addEventListener('click', function () {
        if (selectedTask) {
            const confirmDelete = confirm('Bist du sicher, dass du diese Aufgabe löschen möchtest?');
            if (confirmDelete) {
                selectedTask.remove();
                selectedTask = null;
                editDialog.close();
            }
        }
    });

    // Handle checkbox toggle for "Finished"
    document.addEventListener('change', function (event) {
        const checkbox = event.target.closest('input[type="checkbox"]');
        if (!checkbox) return;

        const taskItem = checkbox.closest('li');
        if (!taskItem) return;

        if (checkbox.checked) {
            taskItem.classList.remove('planned', 'in-work');
            taskItem.classList.add('finished');
        } else {
            taskItem.classList.remove('finished');
            taskItem.classList.add('planned'); // Default back to "Planned"
        }
    });

    // Polyfill for command / Close dialog manually
    document.addEventListener('click', (event) => {
        if ('CommandEvent' in window) return; // Exit if native support exists

        const commandTarget = event.target.closest('[command]');
        if (commandTarget) {
            const dialogId = commandTarget.getAttribute('commandfor');
            const dialog = document.getElementById(dialogId);
            if (dialog instanceof HTMLDialogElement) {
                dialog.showModal();
            }
        }
    });
});

</script>

 
</head>
 
<body>
  <h1>ToDo-Liste - 3</h1>

<form id="controls"> 
	<label for="newtask">Neues Vorhaben:</label>
	<input id="newtask">

	<button type="button" id="add">Hinzufügen!</button>
</form>	
<ul id="taskList">
          <li class="planned">
            <input type="checkbox" checked id="${taskId}">
            <label for="${taskId}">
              <span class="text">Im Wiki aktiv werden!</span>
            </label>
            <button aria-label="Edit ${taskId}" command="show-modal" commandfor="editSettings">Bearbeiten</button>
          </li>
</ul>

<dialog id="editSettings" closedby="any">
  <form method="dialog">
    <label for="editText">Ändere den Text:</label><br>
    <input type="text" id="editText">
    <button type="button" class="save-button">Speichern</button>
    <p><button aria-label="Delete task: ${task}" class="delete-button">Löschen</button></p>

    <select class="status-dropdown" size="3" >
      <option value="planned">Planned</option>
      <option value="in-work">In Work</option>
      <option value="finished">Finished</option>
    </select>
  </form>
</dialog>

</body>
</html>