5.1 - Complément


Template

Template - MDN

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ" crossorigin="anonymous">
</head>

    <style>
        /* Make sure  error message always takes up space 
           to avoid list going down when error appears,
           also see inline style on .invalid-feedback div */
        .is-invalid + .invalid-feedback {
            visibility: visible !important;
        }
    </style>
<body>

    <div class="bg-white">
        <template id="item-template">
            <li class="mt-4">
                <span class="name"></span>
                <button class="btn btn-danger">X</button>
            </li>
        </template>

        <div class="container-fluid">
            <h1 class="mt-2">Tasks</h1>

            <form>
                <div class="row g-2 mt-4">
                    <div class="col-12 col-sm">
                        <input type="text" name="name" class="form-control">
                        <div class="invalid-feedback" style="display: block; visibility: hidden;">
                            Name is required
                        </div>
                    </div>
                    <div class="col-12 col-sm-auto">
                        <button type="submit" class="btn btn-primary w-100">+</button>
                    </div>
                </div>
            </form>

            <ul id="items" class="overflow-y-auto" style="height: calc(100vh - 184px);"></ul>
        </div>

        <script>
            const form = document.querySelector('form');
            const list = document.querySelector('#items');

            form.onsubmit = function(evt) {
               evt.preventDefault();

               if (form.name.value.trim() == '') { 
                    form.name.classList.add('is-invalid');

                    const removeInvalid = () => form.name.classList.remove('is-invalid');

                    form.name.oninput = removeInvalid
                    form.name.onblur = removeInvalid

                    return
               }

               const template = document.querySelector('#item-template').content.cloneNode(true);
               const item = template.querySelector('li');

               const span = item.querySelector('span');
               span.textContent = form.name.value;

               const button = item.querySelector('button');
               button.onclick = function() {
                    if (confirm(`Delete '${span.textContent}'?`)) {
                        item.remove();
                    }
               }

               list.appendChild(item); 
               form.name.value = '';
               form.name.classList.remove('is-invalid');
            }
        </script>
    </div>
</body>

Bootstrap

Bootstrap

UX Formulaire