Curso JavaScript | Proyecto de seguimiento de tareas

Artículo anterior: Curso de JavaScript |
Introducción a los  objetos en el proyecto JavaScript
En este artículo final de este curso, aprenderemos cómo hacer una aplicación javascript simple donde podemos agregar tareas, eliminar tareas y editarlas también. Se ha utilizado JavaScript puro (vainilla) y también utilizaremos mucho la manipulación DOM, por lo que uno de los requisitos previos principales es HTML | DOM

Estructura del proyecto 

index.html 
estilos.css 
list.js

  • índice.html 

HTML

<!DOCTYPE html>
<html>
<head>
  <title>Task Tracker</title>
  <link rel="stylesheet" href="styles.css" type="text/css"
    media="screen" charset="utf-8">
</head>
 
<body>
  <div class="container">
     
 
<p>
      <label for="new-task" class="middle">Add Task</label>
    <input id="new-task" type="text"><button>Add Task</button>
    </p>
 
 
 
    <h3 class="middle">Todo</h3>
    <ul id="incomplete-tasks">
    </ul>
 
    <h3 class="middle">Completed Tasks</h3>
    <ul id="completed-tasks">
    </ul>
  </div>
 
  <script type="text/javascript" src="list.js"></script>
 
</body>
 
</html>

Explicación: 
El código HTML anterior contiene etiquetas de lista simples y un campo de texto que completaremos con texto cuando agreguemos o eliminemos tareas. Se asignan ciertas clases que utilizamos al obtener ese elemento en particular mediante DOM o al diseñarlo dentro del archivo styles.css. Todo el contenido anterior está dentro de un div con clase ‘contenedor’ que tiene su propio estilo y atributos. 
 

  • estilos.css 

CSS

/* Basic Style */
body {
  background: #ecf0f1;
  color: #333;
  font-family: Lato, sans-serif;
}
 
.container {
  display: block;
  width: 500px;
  margin: 50px auto 0;
}
 
ul {
  margin: 0;
  padding: 0;
}
 
li * {
  float: left;
}
 
li,
h3 {
  clear: both;
  list-style: none;
}
 
input,
button {
  outline: none;
}
 
button {
  background: none;
  border: 0px;
  color: #888;
  font-size: 15px;
  width: 100px;
  margin: 10px 0 0;
  font-family: Lato, sans-serif;
  cursor: pointer;
}
 
button:hover {
  color: #333;
}
 
/* Heading */
h3,
label[for='new-task'] {
  color: #333;
  font-weight: 700;
  font-size: 15px;
  border-bottom: 2px solid #333;
  padding: 30px 0 10px;
  margin: 0;
  text-transform: uppercase;
}
 
input[type="text"] {
  margin: 0;
  font-size: 18px;
  line-height: 18px;
  height: 18px;
  padding: 10px;
  border: 1px solid #ddd;
  background: #fff;
  border-radius: 6px;
  font-family: Lato, sans-serif;
  color: #888;
}
 
input[type="text"]:focus {
  color: #333;
}
 
.middle {
  text-align: center;
}
 
 
/* New Task */
label[for='new-task'] {
  display: block;
  margin: 0 0 20px;
}
 
input#new-task {
  float: right;
  width: 318px;
}
 
p>button:hover {
  color: #0FC57C;
}
 
/* Task list */
li {
  overflow: hidden;
  padding: 20px 0;
  border-bottom: 1px solid #eee;
}
 
li>input[type="checkbox"] {
  margin: 0 10px;
  position: relative;
  top: 15px;
}
 
li>label {
  font-size: 18px;
  line-height: 40px;
  width: 237px;
  padding: 0 0 0 11px;
}
 
li>input[type="text"] {
  width: 226px;
}
 
li>.delete:hover {
  color: #CF2323;
}
 
/* Completed */
#completed-tasks label {
  text-decoration: line-through;
  color: #888;
}
 
/* Edit Task */
ul li input[type=text] {
  display: none;
}
 
ul li.editMode input[type=text] {
  display: block;
}
 
ul li.editMode label {
  display: none;
}

Nota: Los archivos HTML y CSS anteriores son principalmente para la parte de presentación. 

  • lista.js 

Javascript

// Add a new task.
let taskInput = document.getElementById("new-task");
 
// first button
let addButton = document.getElementsByTagName("button")[0];
 
// ul of #incomplete-tasks
let incompleteTaskHolder = document.getElementById("incomplete-tasks");
 
// completed-tasks
let completedTasksHolder = document.getElementById("completed-tasks");
  
/*---- Part 1 ----*/
// function to create new task item
let createNewTaskElement = function (taskString) {
  
    let listItem = document.createElement("li");
  
    // input (checkbox)
    let checkBox = document.createElement("input"); // checkbox
    // label
    let label = document.createElement("label"); // label
    // input (text)
    let editInput = document.createElement("input"); // text
    // button.edit
    let editButton = document.createElement("button"); // edit button
  
    // button.delete
    let deleteButton = document.createElement("button"); // delete button
  
    label.innerText = taskString;
  
    // Each elements, needs appending
    checkBox.type = "checkbox";
    editInput.type = "text";
  
 
    // innerText encodes special characters, HTML does not.
    editButton.innerText = "Edit";    
    editButton.className = "edit";
    deleteButton.innerText = "Delete";
    deleteButton.className = "delete";
  
    // and appending.
    listItem.appendChild(checkBox);
    listItem.appendChild(label);
    listItem.appendChild(editInput);
    listItem.appendChild(editButton);
    listItem.appendChild(deleteButton);
    return listItem;
}
/*---- Part 2 ----*/
let addTask = function () {
    console.log("Add Task...");
  
    let listItem = createNewTaskElement(taskInput.value);
  
    if (taskInput.value == "") {
        return;
    }
  
    // Append listItem to incompleteTaskHolder
    incompleteTaskHolder.appendChild(listItem);
    bindTaskEvents(listItem, taskCompleted);
  
    taskInput.value = "";
  
}
  
/*---- Part 3 ----*/
let editTask = function () {
    console.log("Edit Task...");
    console.log("Change 'edit' to 'save'");
  
  
    let listItem = this.parentNode;
  
    let editInput = listItem.querySelector('input[type=text]');
    let label = listItem.querySelector("label");
    let containsClass = listItem.classList.contains("editMode");
    // If class of the parent is .editmode
    if (containsClass) {
        label.innerText = editInput.value;
    } else {
        editInput.value = label.innerText;
    }
    listItem.classList.toggle("editMode");
}
  
/*---- Part 4 ----*/
let deleteTask = function () {
    console.log("Delete Task...");
  
    let listItem = this.parentNode;
    let ul = listItem.parentNode;
    // Remove the parent list item from the ul.
    ul.removeChild(listItem);
  
}
  
/*---- Part 5 ----*/
  
let taskCompleted = function () {
    console.log("Complete Task...");
  
    // Append the task list item to the #completed-tasks
    let listItem = this.parentNode;
    completedTasksHolder.appendChild(listItem);
    bindTaskEvents(listItem, taskIncomplete);
  
}
  
/*---- Part 6 ----*/
let taskIncomplete = function () {
    console.log("Incomplete Task...");
    // Mark task as incomplete.
    let listItem = this.parentNode;
    incompleteTaskHolder.appendChild(listItem);
    bindTaskEvents(listItem, taskCompleted);
}
  
/*---- Part 7 ----*/
addButton.onclick = addTask;
addButton.addEventListener("click", addTask);
  
let bindTaskEvents = function (taskListItem, checkBoxEventHandler) {
    console.log("bind list item events");
    // select ListItems children
    let checkBox = taskListItem.querySelector("input[type=checkbox]");
    let editButton = taskListItem.querySelector("button.edit");
    let deleteButton = taskListItem.querySelector("button.delete");
  
  
    // Bind editTask to edit button.
    editButton.onclick = editTask;
    // Bind deleteTask to delete button.
    deleteButton.onclick = deleteTask;
    // Bind taskCompleted to checkBoxEventHandler.
    checkBox.onchange = checkBoxEventHandler;
}
  
/*---- Part 8 ----*/
// cycle over incompleteTaskHolder ul list items
// for each list item
for (let i = 0; i < incompleteTaskHolder.children.length; i++) {
  
    // bind events to list items children(tasksCompleted)
    bindTaskEvents(incompleteTaskHolder.children[i], taskCompleted);
}
  
// cycle over completedTasksHolder ul list items
for (let i = 0; i < completedTasksHolder.children.length; i++) {
    // bind events to list items children(tasksIncompleted)
    bindTaskEvents(completedTasksHolder.children[i], taskIncomplete);
}

Explicación 

  1. Parte 1 
    • La forma en que funciona esta función es que toma la ‘string de entrada’, es decir, el texto que pasamos dentro del campo de texto HTML como una tarea y luego crea varios elementos usando las propiedades DOM y les agrega clases específicas. Después de agregar, insertamos todos los elementos dentro de la lista como listItems.
  2. Parte 2 
    • Esta función addTask se llama cuando hacemos clic en el botón ‘addButton’ (línea 115) y luego dentro creamos un elemento de lista con el valor que ingresó el usuario y luego verificamos el valor, ya que no debe ser una string vacía, simplemente agregamos el valor anterior dentro de ‘inputTaskHolder’ y finalmente establecer el valor dentro de él como una string vacía antes de llamar a ‘bindFunction’. 
       
  3. parte 3 
    • Esta función de código se usa para editar una tarea existente y lo hacemos haciendo un seguimiento del Node principal y luego un simple if-else verifica si se hace clic en el botón ‘editMode’ o no, si se hace clic, simplemente asigne el valor de la etiqueta texto interno al valor dentro de editInput, si no, viceversa. Luego, después de editar, alternamos el valor de ‘editMode’ como lo hemos editado. 
       
  4. parte 4 
    • En esta parte eliminamos una tarea y la forma en que lo hacemos haciendo uso del Node principal del Node actual y luego almacenando el principal del Node principal y luego simplemente eliminando el secundario de este Node. 
       
  5. Parte 5 
    • En esta función, marcamos la tarea como completa simplemente agregando el elemento secundario del Node principal dentro del elemento completeTaskHolder y luego llamando a bindFunction. 
       
  6. parte 6 
    • En esta función, marcamos la tarea como incompleta simplemente agregando el elemento secundario del Node principal dentro del elemento inCompleteTaskHolder y luego llamando a bindFunction. 
       
  7. Parte 7 
    • En esta parte llamamos BindFunction donde respondemos a las diversas actividades de interacción del usuario y hacemos que funcionen varios botones. 
       
  8. parte 8 
    • En esta sección final, iteramos sobre varias partes que vinculan a los niños con la ayuda del bucle for dentro del elemento TaskHolder incompleto y completo. 

Salida: (Antes de agregar cualquier tarea) 

Salida: (después de agregar la tarea) 

Salida: (después de completar la tarea) 

Artículo siguiente: Curso de JavaScript | Cuestionario de práctica-3
 

Publicación traducida automáticamente

Artículo escrito por immukul y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *