简体   繁体   中英

Dynamically generating elements out of a dynamically generated form with Vanilla JS

I working on a to-do list that is able to create projects and can also add tasks inside these projects. For the moment I'm able to generate the new project element and a form to create tasks inside these projects.

This is the markup I'm using:

<div class="wrapper">
    <ul class="navigation">
        <li class="link">Projects</li>
        <li class="link">Due today</li>
        <li class="link">Priority</li>
    </ul>
    <button class="add-item">+ New Project</button>
    <div class="new-project">
        <form class="add-project">
            <h3>New Project</h3>
            <label for="project-name">Project Name: </label><br>
            <input class="project-input" type="text" name="project-name" required><br>
            <label for="project-desc">Description: </label><br>
            <input class="project-input" type="text-area" name="project-desc" required><br>
            <input class="submit-project"type="submit" value="+ Add Project">
        </form>
    </div>
    <div class="projects">
        <div class="to-do">
            <h2 class="to-do-title">Title</h2>
            <p class="to-do-description">Description</p>
            <form class="new-task">
                <h3>New Task</h3>

                <label for="task-name">Task Name: </label><br>
                <input class="task-input" type="text" name="task-name"> 
                <br>

                <label for="task-date">Due-Date: </label><br>
                <input class="task-input" type="date" name="task-date"> 
                <br>

                <label for="priority">Priority: </label><br>
                <select class="task-input-dd" name="priority">
                    <option value="high">high</option>
                    <option value="medium">medium</option>
                    <option value="low">low</option>
                </select><br>
                <input id="btn" class="add-task" type="submit" value="+ Add Task">
            </form>
            <button class="dlt-prjct">Delete Project</button>
            <div class="task-list">
                <span class="task-text">
                    <p class="task-desc">Finish Math Assignment</p>
                    <p class="due-date">23/22/21</p>
                    <div class="check-form">
                        <div class="task-footer">
                            <i class="far fa-check-circle"></i>
                            <input type="checkbox" class="done-task">
                        </div>
                        <div class="task-footer">
                            <i class="far fa-flag"></i>
                            <span class="task-priority">HIGH</span>
                        </div>
                    </div>
                </span>
                <button class="delete-task"><i class="fas fa-trash-alt"></i></button>
            </div>
        </div>
    </div>
</div>

This is the function that I'm using to create the project elements:

const projectForm = document.querySelector('.add-project')
projectForm.addEventListener('submit', function(e){
    e.preventDefault();
    const projectName = projectForm.querySelector('input[name="project-name"]').value;
    const projectDesc = projectForm.querySelector('input[name="project-desc"]').value;

    const addProject = document.querySelector('.projects');
    const newProject = document.createElement('div');
    newProject.className += 'to-do';
    const h2 = document.createElement('h2');
    h2.className += 'to-do-title';
    const p = document.createElement('p');
    p.className += 'to-do-description';
    h2.innerHTML = `${projectName}`;
    p.innerHTML = `${projectDesc}`;
    const deleteProject = document.createElement('button');
    deleteProject.className += 'dlt-prjct';
    deleteProject.innerHTML = 'Delete Project';

    addProject.appendChild(newProject);
    newProject.appendChild(h2);
    newProject.appendChild(p);
    createNewProjectForm(newProject);
    newProject.appendChild(deleteProject);
});

And this is the function I'm using to create the form that goes inside the project element:

function createNewProjectForm(attatchTo){
    const createForm = document.createElement('form')
    createForm.className += 'new-task';
    const h3 = document.createElement('h3')
    h3.innerText = 'New Task'

    // label plus input field for TASK-NAME: 
    const taskInputLabel = document.createElement('label');
    taskInputLabel.setAttribute('for', 'task-name');
    taskInputLabel.innerHTML = 'Task Name: ';

    const taskInput = document.createElement('input');
    taskInput.className += 'task-input';
    taskInput.setAttribute('type', 'text');
    taskInput.setAttribute('name', 'task-name');

    // label plus input field for DUE-DATE:
    const dateInputLabel = document.createElement('label');
    dateInputLabel.setAttribute('for', 'task-date');
    dateInputLabel.innerHTML = 'Due Date: ';

    const dateInput = document.createElement('input');
    dateInput.className += 'task-input';
    dateInput.setAttribute('type', 'date');
    dateInput.setAttribute('name', 'task-date');

    //create the SELECT menu
    const selectLabel = document.createElement('label');
    selectLabel.setAttribute('for', 'priority');
    selectLabel.innerHTML = 'Priority: ';

    const select = document.createElement('select');
    select.className += 'task-input-dd';
    select.setAttribute('name', 'priority');

    //create OPTIONS for the select menu
    const optionOne = document.createElement("option");
    optionOne.setAttribute('value', 'high')
    optionOne.text = "high";
    const optionTwo = document.createElement("option");
    optionTwo.setAttribute('value', 'medium')
    optionTwo.text = "medium";
    const optionThree = document.createElement("option");
    optionThree.setAttribute('value', 'low')
    optionThree.text = "low";

    //add OPTIONS to the SELECT menu
    select.add(optionOne)
    select.add(optionTwo)
    select.add(optionThree)

    //add the SUBMIT button
    const submitBtn = document.createElement('input');
    submitBtn.className += 'add-task';
    submitBtn.setAttribute('type', 'submit');
    submitBtn.setAttribute('value', '+ Add Task');

    //FINALLY, APPEND the elements Together to the form
    createForm.appendChild(h3)
    createForm.appendChild(taskInputLabel);
    createForm.appendChild(taskInput);
    createForm.appendChild(dateInputLabel);
    createForm.appendChild(dateInput);
    createForm.appendChild(selectLabel);
    createForm.appendChild(select);
    createForm.appendChild(submitBtn);
    attatchTo.appendChild(createForm);
};

What I'm having trouble with is that when I'm trying to append a new task inside the project element, the whole page reloads and nothing gets generated.

This is the code that I have so far:

const taskForm = document.querySelector('.new-task')
taskForm.addEventListener('submit', (e) => {
    const taskName = taskForm.querySelector('input[name="task-name"]').value
    const taskDate = taskForm.querySelector('input[name="task-date"]').value
    const taskPriority = taskForm.querySelector('select[name="priority"]').value
    const addTask = document.querySelector('.to-do');
    const newTask = document.createElement('div');
    newTask.className += 'task-list'
    const span = document.createElement('span');
    span.className += 'task-text';
    const p1 = document.createElement('p');
    p1.className += 'task-desc';
    p1.innerHTML = `${taskName}`;
    const p2 = document.createElement('p');
    p2.className += 'due-date';
    p2.innerHTML = `${taskDate}`;
    const div1 = document.createElement('div');
    div1.className += 'check-form';
    const divTask1 = document.createElement('div');
    divTask1.className += 'task-footer';
    const check1 = document.createElement('i');
    check1.className += 'far fa-check-circle';
    const checkbox1 = document.createElement('input');
    checkbox1.className += 'done-task'
    checkbox1.setAttribute('type', 'checkbox');
    const divTask2 = document.createElement('div');
    divTask2.className += 'task-footer';
    const check2 = document.createElement('i');
    check2.className += 'far fa-flag';
    const spanFooter = document.createElement('span');
    spanFooter.className += 'task-priority';
    spanFooter.innerHTML = `${taskPriority}`;
    const deleteButton = document.createElement('button');
    deleteButton.className += 'delete-task';
    const trashBin = document.createElement('i');
    trashBin.className += 'fas fa-trash-alt';
    addTask.appendChild(newTask);
    newTask.appendChild(span);
    span.appendChild(p1);
    span.appendChild(p2);
    span.appendChild(div1);
    div1.appendChild(divTask1);
    divTask1.appendChild(check1);
    divTask1.appendChild(checkbox1);
    div1.appendChild(divTask2);
    divTask2.appendChild(check2);
    divTask2.appendChild(spanFooter);
    newTask.appendChild(deleteButton);
    deleteButton.appendChild(trashBin);
});

I've been reading and I think that I'm dealing with a problem of DOM event delegation but so far I haven't been able to figure out how to apply that in this project. I've also seen some JQuery possible solutions but I'm trying to solve this with pure JavaScript.

I think You can use e.preventDefault(); on the submit event

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM