5 Javascript Projects with Source Code

In this tutorial, I’ll introduce 5 Javascript projects with source code tailored to different skill levels, from beginner to advanced. Each project will include an overview of the features and a brief guide to the creation process. By working on these projects, you can choose the one that best suits your current skill level and interests.

We have already published a 30 Javascript Projects in 30 Days article, which will help you learn more about JavaScript.”

1. Todo List App

Todo List App

A Todo List App is a great starting project for beginners learning JavaScript. It helps you grasp basic concepts such as DOM manipulation, event handling, and local storage. In this tutorial, I’ll guide you through creating a simple yet functional Todo List App from scratch.

Features:

  • Add new tasks.
  • Mark tasks as completed.
  • Edit tasks.
  • Delete tasks.
  • Save tasks in the browser’s local storage.

Creation Process

Here’s a step-by-step guide to building your Todo List App:

Step 1: Set Up Your HTML

Start by creating a basic HTML structure for your Todo List.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Todo List App</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div class="container">
        <h1>Todo List</h1>
        <form id="todo-form">
            <input type="text" id="new-todo" placeholder="Enter a new task" required>
            <button type="submit">Add Task</button>
        </form>
        <ul id="todo-list"></ul>
    </div>
    <script src="scripts.js"></script>
</body>
</html>
Step 2: Style Your App with CSS

Create a styles.css file to style your Todo List App.

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

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

h1 {
    margin-top: 0;
    font-size: 24px;
    text-align: center;
}

#todo-form {
    display: flex;
    margin-bottom: 10px;
}

#new-todo {
    flex: 1;
    padding: 10px;
    font-size: 16px;
    border: 1px solid #ccc;
    border-radius: 3px;
}

button {
    padding: 10px;
    font-size: 16px;
    background-color: #5cb85c;
    color: white;
    border: none;
    border-radius: 3px;
    cursor: pointer;
}

button:hover {
    background-color: #4cae4c;
}

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

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

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

li button {
    background: none;
    border: none;
    color: #d9534f;
    cursor: pointer;
}
Step 3: Add JavaScript for Functionality

Create a scripts.js file for the functionality of your Todo List App. Using methods like createElement, appendChild, and event listeners to dynamically update the webpage. Utilizing localStorage to persist data between page reloads. Writing and organizing functions for specific tasks like adding, editing, or deleting items.

document.addEventListener('DOMContentLoaded', () => {
    const form = document.getElementById('todo-form');
    const input = document.getElementById('new-todo');
    const todoList = document.getElementById('todo-list');

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

    // Function to render the todo list
    function renderTodos() {
        todoList.innerHTML = '';
        todos.forEach((todo, index) => {
            const li = document.createElement('li');
            li.className = todo.completed ? 'completed' : '';
            li.innerHTML = `
                <span>${todo.text}</span>
                <div>
                    <button onclick="editTask(${index})">Edit</button>
                    <button onclick="toggleTask(${index})">${todo.completed ? 'Undo' : 'Complete'}</button>
                    <button onclick="deleteTask(${index})">Delete</button>
                </div>
            `;
            todoList.appendChild(li);
        });
    }

    // Function to add a new task
    form.addEventListener('submit', (event) => {
        event.preventDefault();
        const newTodo = {
            text: input.value,
            completed: false
        };
        todos.push(newTodo);
        localStorage.setItem('todos', JSON.stringify(todos));
        renderTodos();
        input.value = '';
    });

    // Edit task function
    window.editTask = (index) => {
        const newText = prompt('Edit task:', todos[index].text);
        if (newText !== null) {
            todos[index].text = newText;
            localStorage.setItem('todos', JSON.stringify(todos));
            renderTodos();
        }
    };

    // Toggle task completion status
    window.toggleTask = (index) => {
        todos[index].completed = !todos[index].completed;
        localStorage.setItem('todos', JSON.stringify(todos));
        renderTodos();
    };

    // Delete task function
    window.deleteTask = (index) => {
        todos.splice(index, 1);
        localStorage.setItem('todos', JSON.stringify(todos));
        renderTodos();
    };

    // Initial render
    renderTodos();
});

2. Simple Stopwatch

Simple Stopwatch

In this project, we’ll create a Simple Stopwatch using HTML, CSS, and JavaScript. The stopwatch will have basic controls to start, stop, and reset the timer. It will display the elapsed time in a clear and easy-to-read format, making it an excellent beginner project to practice fundamental JavaScript skills.

Features:

  • Start, stop, and reset a stopwatch.
  • Display elapsed time.

Creation Process:

  1. Setup: Create an HTML layout with buttons to start, stop, and reset the stopwatch, and an area to display the time.
  2. Styling: Use CSS to style the buttons and time display.
  3. Functionality: Use JavaScript to track time and update the display, handling start, stop, and reset actions. Implement the start(), stop(), and reset() functions. Use setInterval to update the time every second when the stopwatch is running. Format the time in HH:MM:SS using toISOString().
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Simple Stopwatch</title>
    <style>
        body, html {
            height: 100%;
            display: flex;
            justify-content: center;
            align-items: center;
            flex-direction: column;
            font-family: Arial, sans-serif;
        }
        .time {
            font-size: 48px;
            margin-bottom: 20px;
        }
        button {
            padding: 10px 20px;
            margin: 5px;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <div class="time" id="time">00:00:00</div>
    <button onclick="start()">Start</button>
    <button onclick="stop()">Stop</button>
    <button onclick="reset()">Reset</button>
    <script>
        let timer;
        let seconds = 0;
        function start() {
            if (!timer) {
                timer = setInterval(() => {
                    seconds++;
                    document.getElementById('time').innerText = new Date(seconds * 1000).toISOString().substr(11, 8);
                }, 1000);
            }
        }
        function stop() {
            clearInterval(timer);
            timer = null;
        }
        function reset() {
            stop();
            seconds = 0;
            document.getElementById('time').innerText = '00:00:00';
        }
    </script>
</body>
</html>

3. Unit Converter

Unit Converter

The Unit Converter is a basic yet practical JavaScript project that allows users to convert between different units of measurement. This project covers essential JavaScript concepts like event handling, mathematical operations, and DOM manipulation.

Features

  • Convert Units: Select units to convert from and to.
  • Interactive Input: Enter a value and get the converted result instantly.
  • Supports Multiple Units: Convert between various units for length, weight, and temperature.

How it Works

  1. Setup the HTML:
    • Two input fields for values.
    • Dropdowns for units.
    • A dropdown for selecting the unit type (length, weight, temperature).
  2. JavaScript Logic:
    • updateUnits() populates unit dropdowns based on the selected type.
    • convert() handles the conversion process:
      • Length: Converts to meters first, then to the target unit.
      • Weight: Converts to grams first, then to the target unit.
      • Temperature: Direct conversion using appropriate formulas.
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Basic Unit Converter</title>
    <style>
        body, html {
            height: 100%;
            display: flex;
            justify-content: center;
            align-items: center;
            font-family: Arial, sans-serif;
            flex-direction: column;
            margin: 0;
        }
        .converter {
            text-align: center;
            margin-top: 20px;
        }
        input, select {
            padding: 10px;
            margin: 5px;
            font-size: 16px;
            width: 200px;
        }
    </style>
</head>
<body>
    <div class="converter">
        <h2>Unit Converter</h2>
        <div>
            <input type="number" id="inputValue1" placeholder="Enter value" oninput="convert('inputValue1', 'inputValue2', 'fromUnit', 'toUnit')">
            <select id="fromUnit"></select>
        </div>
        <div>
            <input type="number" id="inputValue2" placeholder="Converted value" oninput="convert('inputValue2', 'inputValue1', 'toUnit', 'fromUnit')">
            <select id="toUnit"></select>
        </div>
        <div>
            <label for="unitType">Unit Type:</label>
            <select id="unitType" onchange="updateUnits()">
                <option value="length">Length</option>
                <option value="weight">Weight</option>
                <option value="temperature">Temperature</option>
            </select>
        </div>
    </div>
    <script>
        const unitOptions = {
            length: ['Meters', 'Kilometers', 'Miles', 'Feet'],
            weight: ['Grams', 'Kilograms', 'Pounds'],
            temperature: ['Celsius', 'Fahrenheit']
        };

        function updateUnits() {
            const unitType = document.getElementById('unitType').value;
            const fromUnit = document.getElementById('fromUnit');
            const toUnit = document.getElementById('toUnit');

            fromUnit.innerHTML = '';
            toUnit.innerHTML = '';

            unitOptions[unitType].forEach(unit => {
                fromUnit.add(new Option(unit, unit.toLowerCase()));
                toUnit.add(new Option(unit, unit.toLowerCase()));
            });

            // Reset input fields when unit type changes
            document.getElementById('inputValue1').value = '';
            document.getElementById('inputValue2').value = '';
        }

        function convert(inputId, outputId, fromUnitId, toUnitId) {
            const inputValue = parseFloat(document.getElementById(inputId).value);
            const fromUnit = document.getElementById(fromUnitId).value;
            const toUnit = document.getElementById(toUnitId).value;
            const unitType = document.getElementById('unitType').value;

            if (isNaN(inputValue)) {
                document.getElementById(outputId).value = '';
                return;
            }

            let result;

            if (unitType === 'length') {
                result = convertLength(inputValue, fromUnit, toUnit);
            } else if (unitType === 'weight') {
                result = convertWeight(inputValue, fromUnit, toUnit);
            } else if (unitType === 'temperature') {
                result = convertTemperature(inputValue, fromUnit, toUnit);
            }

            document.getElementById(outputId).value = result;
        }

        function convertLength(value, from, to) {
            const conversions = {
                meters: 1,
                kilometers: 1000,
                miles: 1609.34,
                feet: 0.3048
            };

            const inMeters = value * conversions[from];
            return inMeters / conversions[to];
        }

        function convertWeight(value, from, to) {
            const conversions = {
                grams: 1,
                kilograms: 1000,
                pounds: 453.592
            };

            const inGrams = value * conversions[from];
            return inGrams / conversions[to];
        }

        function convertTemperature(value, from, to) {
            if (from === 'celsius' && to === 'fahrenheit') {
                return (value * 9 / 5) + 32;
            } else if (from === 'fahrenheit' && to === 'celsius') {
                return (value - 32) * 5 / 9;
            } else {
                return value;
            }
        }

        // Initialize unit options
        updateUnits();
    </script>
</body>
</html>

4. Expense Tracker

Expense Tracker

An Expense Tracker is a practical JavaScript project for those with intermediate coding skills. This project helps users manage their finances by allowing them to log and categorize their expenses. It involves dynamic DOM manipulation, local storage, and basic data handling.

Features

  • Add Expenses: Users can add expenses with details such as name, amount, date and category.
  • Expense List: View a list of all logged expenses.
  • Delete Expenses: Remove expenses from the list.
  • Total Calculation: Automatically calculate and display the total expenses.
  • Persist Data: Save expenses to local storage so they persist across sessions.

How It Works

  1. Unique ID for Each Expense:
    • When adding a new expense, a unique ID is generated using the current timestamp (new Date().getTime().toString()). This ensures each expense has a unique identifier.
  2. HTML and JavaScript Updates:
    • addExpenseToDOM(expense): Assigns the unique ID to each list item using a data-id attribute.
    • deleteExpense(id): Filters expenses by id to remove the correct expense. It also removes the corresponding DOM element using the data-id attribute.
  3. Improved Deletion Functionality:
    • The deleteExpense(id) function ensures that the correct expense is removed from both the DOM and local storage by matching the unique id.
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Expense Tracker</title>
    <style>
        body, html {
            display: flex;
            justify-content: center;
            align-items: center;
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
            height: 100vh;
            background-color: #f4f4f4;
        }
        .tracker {
            width: 400px;
            background: white;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
            padding: 20px;
            border-radius: 10px;
        }
        h2 {
            text-align: center;
        }
        input, select, button {
            width: calc(100% - 20px);
            padding: 10px;
            margin: 10px;
            border: 1px solid #ccc;
            border-radius: 5px;
            font-size: 16px;
        }
        button {
            background-color: #5cb85c;
            color: white;
            cursor: pointer;
        }
        button:hover {
            background-color: #4cae4c;
        }
        ul {
            list-style: none;
            padding: 0;
        }
        li {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin: 10px 0;
            padding: 10px;
            background: #f8f8f8;
            border: 1px solid #ddd;
            border-radius: 5px;
        }
        .delete {
            background: #d9534f;
            color: white;
            border: none;
            padding: 5px 10px;
            cursor: pointer;
            border-radius: 5px;
          width:100px;
        }
        .delete:hover {
            background: #c9302c;
        }
        .expense-date {
            color: #666;
            font-size: 14px;
        }
    </style>
</head>
<body>
    <div class="tracker">
        <h2>Expense Tracker</h2>
        <input type="text" id="expenseName" placeholder="Expense Name">
        <input type="number" id="expenseAmount" placeholder="Amount">
        <input type="date" id="expenseDate">
        <select id="expenseCategory">
            <option value="food">Food</option>
            <option value="entertainment">Entertainment</option>
            <option value="transportation">Transportation</option>
            <option value="other">Other</option>
        </select>
        <button onclick="addExpense()">Add Expense</button>
        <h3>Total: $<span id="totalAmount">0</span></h3>
        <ul id="expenseList"></ul>
    </div>

    <script>
        let expenses = JSON.parse(localStorage.getItem('expenses')) || [];
        updateTotal();

        function addExpense() {
            const name = document.getElementById('expenseName').value;
            const amount = parseFloat(document.getElementById('expenseAmount').value);
            const date = document.getElementById('expenseDate').value;
            const category = document.getElementById('expenseCategory').value;
            const id = new Date().getTime().toString();  // Unique ID based on timestamp

            if (name && !isNaN(amount) && date) {
                const expense = { id, name, amount, date, category };
                expenses.push(expense);
                localStorage.setItem('expenses', JSON.stringify(expenses));
                addExpenseToDOM(expense);
                updateTotal();
                clearInputs();
            } else {
                alert('Please enter a valid expense name, amount, and date.');
            }
        }

        function addExpenseToDOM(expense) {
            const list = document.getElementById('expenseList');
            const listItem = document.createElement('li');

            listItem.innerHTML = `
                ${expense.name} - $${expense.amount.toFixed(2)} <span>(${expense.category})</span>
                <div class="expense-date">${formatDate(expense.date)}</div>
                <button class="delete" onclick="deleteExpense('${expense.id}')">Delete</button>
            `;
            listItem.setAttribute('data-id', expense.id);

            list.appendChild(listItem);
        }

        function deleteExpense(id) {
            expenses = expenses.filter(expense => expense.id !== id);
            localStorage.setItem('expenses', JSON.stringify(expenses));
            document.querySelector(`li[data-id='${id}']`).remove();
            updateTotal();
        }

        function updateTotal() {
            const total = expenses.reduce((sum, expense) => sum + expense.amount, 0);
            document.getElementById('totalAmount').innerText = total.toFixed(2);
        }

        function formatDate(dateStr) {
            const date = new Date(dateStr);
            return date.toLocaleDateString('en-US', {
                year: 'numeric',
                month: 'short',
                day: 'numeric'
            });
        }

        function clearInputs() {
            document.getElementById('expenseName').value = '';
            document.getElementById('expenseAmount').value = '';
            document.getElementById('expenseDate').value = '';
        }

        expenses.forEach(addExpenseToDOM);
    </script>
</body>
</html>

5. Project Management Tool

Project Management Tool

Creating an advanced Project Management Tool involves handling tasks, deadlines, team assignments, and progress tracking. Below is a structured outline and implementation of such a tool using HTML, CSS, and JavaScript. This project assumes a more complex structure compared to beginner or intermediate levels, integrating more interactive features and data management capabilities.

Features:

  • Comprehensive Task and Team Management: Includes task addition, deletion, assignment, and real-time deadline countdown, alongside team member addition, deletion, and role assignment.
  • Persistent Data Storage: Utilizes local storage to save and retrieve task and team data, ensuring continuity across sessions.
  • User-Friendly Interface: Offers an interactive and visually appealing design with modern CSS styling for a seamless user experience.

Work Process

localStorage Usage: Loads tasks and team data from localStorage or initializes them as empty arrays if no data exists. addTask(): Adds a new task to the tasks array with provided name, deadline, assignee, and initializes it as incomplete. renderTasks(): Renders all tasks in the tasks array dynamically on the webpage. Displays task details, completion status checkbox, and delete button. Starts a countdown timer for each task’s deadline.

toggleTaskStatus(id): Toggles the completion status of a task based on its id. saveToLocalStorage(): Saves the current state of tasks and team arrays to localStorage. clearInputs(...ids): Clears input fields with specified IDs.

startCountdown(taskId, deadline): Initiates a countdown timer for a task’s deadline, updating the remaining time dynamically. initialize(): Initializes the application by rendering tasks and team members on page load.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Enhanced Project Management Tool</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            background-color: #f0f2f5;
            margin: 0;
            padding: 20px;
            display: flex;
            justify-content: center;
        }
        .container {
            max-width: 800px;
            width: 100%;
            background: #ffffff;
            border-radius: 12px;
            box-shadow: 0 0 15px rgba(0, 0, 0, 0.1);
            overflow: hidden;
        }
        .header {
            background: #007bff;
            color: white;
            text-align: center;
            padding: 10px;
            font-size: 24px;
        }
        .section {
            margin: 20px;
        }
        .section-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 15px;
        }
        .section-header h3 {
            margin: 0;
            font-size: 20px;
            color: #333;
        }
        .section-header button {
            padding: 10px 20px;
            background-color: #28a745;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            font-size: 16px;
        }
        .section-header button:hover {
            background-color: #218838;
        }
        .input-group {
            display: flex;
            align-items: center;
            margin-bottom: 10px;
        }
        .input-group input, .input-group select {
            padding: 10px;
            margin-right: 10px;
            border: 1px solid #ccc;
            border-radius: 5px;
            font-size: 16px;
            flex: 1;
        }
        .input-group button {
            padding: 10px 20px;
            background-color: #007bff;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            font-size: 16px;
        }
        .input-group button:hover {
            background-color: #0069d9;
        }
        .task-list, .team-list {
            list-style: none;
            padding: 0;
        }
        .task-item, .team-member {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 15px;
            background: #f8f9fa;
            border-radius: 8px;
            margin-bottom: 10px;
            box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
        }
        .task-item .details, .team-member .details {
            flex: 1;
        }
        .task-item .details div, .team-member .details div {
            margin-bottom: 5px;
        }
        .task-item .actions, .team-member .actions {
            display: flex;
            align-items: center;
        }
        .task-item .actions button, .team-member .actions button {
            margin-left: 10px;
            padding: 8px 12px;
            background-color: #dc3545;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
        }
        .task-item .actions button:hover, .team-member .actions button:hover {
            background-color: #c82333;
        }
        .countdown {
            font-size: 14px;
            color: #666;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            Project Management Tool
        </div>
        <div class="section">
            <div class="section-header">
                <h3>Tasks</h3>
                <button onclick="saveProject()">Save Project</button>
            </div>
            <div class="input-group">
                <input type="text" id="taskName" placeholder="Task Name">
                <input type="date" id="taskDeadline">
                <select id="taskAssignee">
                    <option value="">Assign to...</option>
                </select>
                <button onclick="addTask()">Add Task</button>
            </div>
            <ul class="task-list" id="taskList"></ul>
        </div>

        <div class="section">
            <div class="section-header">
                <h3>Team</h3>
            </div>
            <div class="input-group">
                <input type="text" id="memberName" placeholder="Member Name">
                <input type="text" id="memberRole" placeholder="Role">
                <button onclick="addMember()">Add Member</button>
            </div>
            <ul class="team-list" id="teamList"></ul>
        </div>
    </div>

    <script>
        let tasks = JSON.parse(localStorage.getItem('projectTasks')) || [];
        let team = JSON.parse(localStorage.getItem('projectTeam')) || [];

        function addTask() {
            const name = document.getElementById('taskName').value;
            const deadline = document.getElementById('taskDeadline').value;
            const assignee = document.getElementById('taskAssignee').value;

            if (name && deadline && assignee) {
                const task = { id: Date.now().toString(), name, deadline, assignee, completed: false };
                tasks.push(task);
                renderTasks();
                saveToLocalStorage();
                clearInputs('taskName', 'taskDeadline', 'taskAssignee');
            } else {
                alert('Please enter task name, deadline, and assignee.');
            }
        }

        function renderTasks() {
            const taskList = document.getElementById('taskList');
            taskList.innerHTML = '';

            tasks.forEach(task => {
                const taskItem = document.createElement('li');
                taskItem.classList.add('task-item');
                taskItem.innerHTML = `
                    <div class="details">
                        <div><strong>${task.name}</strong></div>
                        <div>Deadline: ${task.deadline}</div>
                        <div>Assigned to: ${task.assignee}</div>
                        <div class="countdown" id="countdown-${task.id}"></div>
                    </div>
                    <div class="actions">
                        <input type="checkbox" onchange="toggleTaskStatus('${task.id}')" ${task.completed ? 'checked' : ''}>
                        <button onclick="deleteTask('${task.id}')">Delete</button>
                    </div>
                `;
                taskList.appendChild(taskItem);
                startCountdown(task.id, task.deadline);
            });
        }

        function toggleTaskStatus(id) {
            tasks = tasks.map(task => {
                if (task.id === id) {
                    task.completed = !task.completed;
                }
                return task;
            });
            renderTasks();
            saveToLocalStorage();
        }

        function deleteTask(id) {
            tasks = tasks.filter(task => task.id !== id);
            renderTasks();
            saveToLocalStorage();
        }

        function addMember() {
            const name = document.getElementById('memberName').value;
            const role = document.getElementById('memberRole').value;

            if (name && role) {
                const member = { id: Date.now().toString(), name, role };
                team.push(member);
                renderTeam();
                saveToLocalStorage();
                clearInputs('memberName', 'memberRole');
            } else {
                alert('Please enter member name and role.');
            }
        }

        function renderTeam() {
            const teamList = document.getElementById('teamList');
            teamList.innerHTML = '';

            team.forEach(member => {
                const memberItem = document.createElement('li');
                memberItem.classList.add('team-member');
                memberItem.innerHTML = `
                    <div class="details">
                        <div><strong>${member.name}</strong></div>
                        <div>${member.role}</div>
                    </div>
                    <div class="actions">
                        <button onclick="deleteMember('${member.id}')">Remove</button>
                    </div>
                `;
                teamList.appendChild(memberItem);
            });

            const assigneeSelect = document.getElementById('taskAssignee');
            assigneeSelect.innerHTML = '<option value="">Assign to...</option>';
            team.forEach(member => {
                const option = document.createElement('option');
                option.value = member.name;
                option.textContent = member.name;
                assigneeSelect.appendChild(option);
            });
        }

        function deleteMember(id) {
            team = team.filter(member => member.id !== id);
            renderTeam();
            saveToLocalStorage();
        }

        function saveToLocalStorage() {
            localStorage.setItem('projectTasks', JSON.stringify(tasks));
            localStorage.setItem('projectTeam', JSON.stringify(team));
        }

        function saveProject() {
            saveToLocalStorage();
            alert('Project saved successfully.');
        } 
          function clearInputs(...ids) {
            ids.forEach(id => document.getElementById(id).value = '');
        }

        function startCountdown(taskId, deadline) {
            const countdownElement = document.getElementById(`countdown-${taskId}`);
            const endDate = new Date(deadline).getTime();

            function updateCountdown() {
                const now = new Date().getTime();
                const distance = endDate - now;

                if (distance <= 0) {
                    countdownElement.textContent = "Deadline passed";
                    return;
                }

                const days = Math.floor(distance / (1000 * 60 * 60 * 24));
                const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
                const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
                const seconds = Math.floor((distance % (1000 * 60)) / 1000);

                countdownElement.textContent = `Time left: ${days}d ${hours}h ${minutes}m ${seconds}s`;
            }

            updateCountdown();
            setInterval(updateCountdown, 1000);
        }

        function initialize() {
            renderTasks();
            renderTeam();
        }

        initialize();
    </script>
</body>
</html>

Conclusion

Whether you’re just starting out or looking to expand your skills, these projects provide a solid foundation and a stepping stone towards more complex web development challenges. Choose a project that aligns with your current skill level and interests, and enjoy the process of learning and creating with JavaScript!

Leave a Comment