En esta sección, vamos a poner en práctica todo lo que hemos aprendido a lo largo del curso construyendo un proyecto completo en JavaScript. Este proyecto servirá como una excelente oportunidad para consolidar tus conocimientos y habilidades. Vamos a seguir un enfoque paso a paso para asegurarnos de que cada parte del proyecto esté bien entendida y funcional.

  1. Definición del Proyecto

Objetivo del Proyecto

Vamos a construir una aplicación web de gestión de tareas (To-Do List). La aplicación permitirá a los usuarios:

  • Añadir nuevas tareas.
  • Marcar tareas como completadas.
  • Eliminar tareas.
  • Filtrar tareas por estado (todas, completadas, pendientes).

Tecnologías Utilizadas

  • HTML y CSS para la estructura y el diseño de la interfaz.
  • JavaScript para la lógica de la aplicación.
  • LocalStorage para el almacenamiento de datos en el navegador.

  1. Estructura del Proyecto

Estructura de Archivos

Vamos a organizar nuestro proyecto de la siguiente manera:

todo-list/
│
├── index.html
├── styles/
│   └── styles.css
└── scripts/
    └── app.js

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>To-Do List</title>
    <link rel="stylesheet" href="styles/styles.css">
</head>
<body>
    <div class="container">
        <h1>To-Do List</h1>
        <form id="task-form">
            <input type="text" id="task-input" placeholder="Add a new task" required>
            <button type="submit">Add Task</button>
        </form>
        <ul id="task-list"></ul>
        <div class="filters">
            <button id="all">All</button>
            <button id="completed">Completed</button>
            <button id="pending">Pending</button>
        </div>
    </div>
    <script src="scripts/app.js"></script>
</body>
</html>

styles/styles.css

body {
    font-family: Arial, sans-serif;
    background-color: #f4f4f4;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
}

.container {
    background: #fff;
    padding: 20px;
    border-radius: 5px;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
    width: 300px;
}

h1 {
    text-align: center;
}

form {
    display: flex;
    justify-content: space-between;
}

input[type="text"] {
    width: 70%;
    padding: 10px;
    border: 1px solid #ccc;
    border-radius: 5px;
}

button {
    padding: 10px;
    border: none;
    background: #28a745;
    color: #fff;
    border-radius: 5px;
    cursor: pointer;
}

button:hover {
    background: #218838;
}

ul {
    list-style: none;
    padding: 0;
}

li {
    display: flex;
    justify-content: space-between;
    padding: 10px;
    border-bottom: 1px solid #ccc;
}

li.completed {
    text-decoration: line-through;
    color: #888;
}

.filters {
    display: flex;
    justify-content: space-around;
    margin-top: 20px;
}

.filters button {
    background: #007bff;
    color: #fff;
    border: none;
    padding: 5px 10px;
    border-radius: 5px;
    cursor: pointer;
}

.filters button:hover {
    background: #0056b3;
}

scripts/app.js

document.addEventListener('DOMContentLoaded', () => {
    const taskForm = document.getElementById('task-form');
    const taskInput = document.getElementById('task-input');
    const taskList = document.getElementById('task-list');
    const filters = document.querySelectorAll('.filters button');

    let tasks = JSON.parse(localStorage.getItem('tasks')) || [];

    const renderTasks = (filter = 'all') => {
        taskList.innerHTML = '';
        const filteredTasks = tasks.filter(task => {
            if (filter === 'all') return true;
            if (filter === 'completed') return task.completed;
            if (filter === 'pending') return !task.completed;
        });

        filteredTasks.forEach(task => {
            const li = document.createElement('li');
            li.className = task.completed ? 'completed' : '';
            li.innerHTML = `
                <span>${task.text}</span>
                <div>
                    <button class="complete-btn">${task.completed ? 'Undo' : 'Complete'}</button>
                    <button class="delete-btn">Delete</button>
                </div>
            `;
            taskList.appendChild(li);

            li.querySelector('.complete-btn').addEventListener('click', () => {
                task.completed = !task.completed;
                saveTasks();
                renderTasks(filter);
            });

            li.querySelector('.delete-btn').addEventListener('click', () => {
                tasks = tasks.filter(t => t !== task);
                saveTasks();
                renderTasks(filter);
            });
        });
    };

    const saveTasks = () => {
        localStorage.setItem('tasks', JSON.stringify(tasks));
    };

    taskForm.addEventListener('submit', (e) => {
        e.preventDefault();
        const newTask = {
            text: taskInput.value,
            completed: false
        };
        tasks.push(newTask);
        saveTasks();
        renderTasks();
        taskInput.value = '';
    });

    filters.forEach(button => {
        button.addEventListener('click', () => {
            filters.forEach(btn => btn.classList.remove('active'));
            button.classList.add('active');
            renderTasks(button.id);
        });
    });

    renderTasks();
});

  1. Explicación del Código

HTML

  • Estructura Básica: El archivo index.html contiene la estructura básica de nuestra aplicación, incluyendo un formulario para añadir tareas, una lista para mostrar las tareas y botones para filtrar las tareas.
  • Formulario: El formulario tiene un campo de entrada para añadir nuevas tareas y un botón para enviar el formulario.
  • Lista de Tareas: La lista de tareas (<ul id="task-list">) es donde se mostrarán las tareas.
  • Filtros: Los botones de filtro permiten al usuario ver todas las tareas, solo las completadas o solo las pendientes.

CSS

  • Estilos Básicos: Los estilos en styles.css proporcionan una apariencia limpia y moderna a nuestra aplicación.
  • Estilos de Tareas: Las tareas completadas se muestran con un texto tachado y un color gris.
  • Estilos de Filtros: Los botones de filtro tienen estilos para diferenciarse y cambiar de color al pasar el cursor sobre ellos.

JavaScript

  • Carga Inicial: Al cargar la página, se obtienen las tareas almacenadas en localStorage y se renderizan.
  • Añadir Tareas: Al enviar el formulario, se añade una nueva tarea a la lista y se guarda en localStorage.
  • Completar/Eliminar Tareas: Cada tarea tiene botones para marcarla como completada o eliminarla. Estos botones actualizan el estado de las tareas y vuelven a renderizar la lista.
  • Filtrar Tareas: Los botones de filtro permiten al usuario ver tareas según su estado (todas, completadas, pendientes).

  1. Ejercicios Prácticos

Ejercicio 1: Añadir una Funcionalidad de Edición de Tareas

Descripción: Añade la funcionalidad para editar el texto de una tarea existente.

Pistas:

  • Añade un botón "Editar" junto a cada tarea.
  • Al hacer clic en "Editar", convierte el texto de la tarea en un campo de entrada.
  • Permite al usuario guardar los cambios y actualiza la tarea en localStorage.

Ejercicio 2: Añadir una Funcionalidad de Búsqueda de Tareas

Descripción: Añade una barra de búsqueda que permita al usuario buscar tareas por texto.

Pistas:

  • Añade un campo de entrada de búsqueda en el HTML.
  • Filtra las tareas en función del texto introducido en el campo de búsqueda.
  • Actualiza la lista de tareas mostradas en tiempo real mientras el usuario escribe.

Conclusión

En esta sección, hemos construido una aplicación completa de gestión de tareas utilizando JavaScript, HTML y CSS. Este proyecto ha cubierto una amplia gama de conceptos y técnicas, desde la manipulación del DOM hasta el almacenamiento de datos en localStorage. Los ejercicios adicionales proporcionan oportunidades para expandir y mejorar la funcionalidad de la aplicación, reforzando aún más tus habilidades en JavaScript. ¡Felicidades por llegar hasta aquí y buen trabajo!

JavaScript: De Principiante a Avanzado

Módulo 1: Introducción a JavaScript

Módulo 2: Estructuras de Control

Módulo 3: Funciones

Módulo 4: Objetos y Arrays

Módulo 5: Objetos y Funciones Avanzadas

Módulo 6: El Modelo de Objetos del Documento (DOM)

Módulo 7: APIs del Navegador y Temas Avanzados

Módulo 8: Pruebas y Depuración

Módulo 9: Rendimiento y Optimización

Módulo 10: Frameworks y Librerías de JavaScript

Módulo 11: Proyecto Final

© Copyright 2024. Todos los derechos reservados