Building a Task Management System with JavaScript

Knowledge Framework

  • Core Requirements: Daily task tracking, journal entries, and real-time clock
  • Technical Implementation

Key Technical Components

This project incorporates several fundaemntal web development concepts:

Date and Time Operaitons

function getCurrentDateTime() {
    const today = new Date();
    const yr = today.getFullYear();
    const mo = today.getMonth() + 1;
    const da = today.getDate();
    return `${yr}-${mo}-${da}`;
}

Real-Time Updates

setInterval(refreshClock, 1000);

Form Validation

Utilizing HTML5's built-in validation with the 'required' attribute

Responsive Design

@media screen and (max-width: 768px) {
    .main-container {
        flex-direction: column;
    }
}

Complete Implementation

HTML Structure


<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Task Manager</title>
</head>
<body>
    <header class="top-bar">
        <span id="clock-display" class="time-text"></span>
        <h1 class="app-title">Productivity Dashboard</h1>
    </header>
    
    <main class="content-wrapper">
        <nav class="sidebar-nav">
            <ul>
                <li><a href="#" onclick="switchView('daily')">Daily Goals</a></li>
                <li><a href="#" onclick="switchView('projects')">Project Log</a></li>
                <li><a href="#" onclick="switchView('learning')">Learning Track</a></li>
            </ul>
        </nav>
        
        <section class="task-section">
            <div class="section-header">
                <h2>Current Tasks</h2>
                <button id="new-task-btn" onclick="createTask('')">Add Task</button>
            </div>
            <table id="active-tasks" class="task-grid"></table>
            
            <div class="section-header">
                <h2>Completed Items</h2>
            </div>
            <table id="completed-tasks" class="task-grid"></table>
        </section>
        
        <aside class="journal-panel">
            <form>
                <label for="journal-entry">Journal Entry:</label>
                <textarea id="journal-entry" name="journal" rows="12" cols="45" required></textarea>
                <button type="submit" class="save-btn">Save Entry</button>
            </form>
        </aside>
    </main>
</body>
</html>

CSS Styling

<style>
    * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
    }
    
    body {
        font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
        min-height: 100vh;
    }
    
    .top-bar {
        background-color: #2c3e50;
        padding: 2rem;
        display: flex;
        justify-content: space-between;
        align-items: center;
        color: #ecf0f1;
    }
    
    .time-text {
        font-size: 1.2rem;
        font-style: italic;
        text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
    }
    
    .app-title {
        font-size: 2.5rem;
        text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
    }
    
    .content-wrapper {
        display: flex;
        height: calc(100vh - 100px);
    }
    
    .sidebar-nav {
        width: 15%;
        background-color: #34495e;
        padding: 1rem 0;
    }
    
    .sidebar-nav ul {
        list-style: none;
    }
    
    .sidebar-nav a {
        display: block;
        padding: 1rem 1.5rem;
        color: #bdc3c7;
        text-decoration: none;
        transition: all 0.3s;
    }
    
    .sidebar-nav a:hover {
        background-color: #2c3e50;
        color: #fff;
    }
    
    .task-section {
        width: 45%;
        padding: 2rem;
        background-color: #ffffff;
        overflow-y: auto;
    }
    
    .section-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin: 1.5rem 0;
        color: #2c3e50;
    }
    
    .task-grid {
        width: 100%;
        border-collapse: collapse;
        margin-bottom: 2rem;
    }
    
    .task-grid td {
        padding: 0.75rem;
        border: 1px solid #ddd;
        text-align: center;
    }
    
    .editable {
        background-color: #f8f9fa;
        cursor: text;
    }
    
    .remove-btn {
        background: none;
        border: none;
        color: #e74c3c;
        cursor: pointer;
        font-weight: bold;
    }
    
    .journal-panel {
        width: 40%;
        padding: 2rem;
    }
    
    #journal-entry {
        width: 100%;
        padding: 1rem;
        border: 2px solid #bdc3c7;
        border-radius: 4px;
        resize: vertical;
        font-family: inherit;
    }
    
    .save-btn {
        background-color: #27ae60;
        color: white;
        border: none;
        padding: 0.75rem 2rem;
        border-radius: 4px;
        cursor: pointer;
        float: right;
        margin-top: 1rem;
    }
    
    @media (max-width: 768px) {
        .content-wrapper {
            flex-direction: column;
        }
        .sidebar-nav, .task-section, .journal-panel {
            width: 100%;
        }
    }
</style>

JavaScript Functionality

<script>
    function formatDate() {
        const currentDate = new Date();
        const year = currentDate.getFullYear();
        const month = String(currentDate.getMonth() + 1).padStart(2, '0');
        const day = String(currentDate.getDate()).padStart(2, '0');
        const weekdays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
        const weekday = weekdays[currentDate.getDay()];
        return `${year}-${month}-${day} (${weekday})`;
    }
    
    function updateClock() {
        const clockElement = document.getElementById('clock-display');
        clockElement.textContent = formatDate();
    }
    
    setInterval(updateClock, 1000);
    updateClock();
    
    function createTask(defaultText = '') {
        const taskRow = document.createElement('tr');
        
        const checkboxCell = document.createElement('td');
        const taskCheckbox = document.createElement('input');
        taskCheckbox.type = 'checkbox';
        taskCheckbox.className = 'task-status';
        
        taskCheckbox.addEventListener('change', function() {
            const targetTable = this.checked ? 
                document.getElementById('completed-tasks') : 
                document.getElementById('active-tasks');
            targetTable.appendChild(taskRow);
        });
        
        checkboxCell.appendChild(taskCheckbox);
        
        const textCell = document.createElement('td');
        textCell.className = 'editable';
        textCell.contentEditable = true;
        textCell.textContent = defaultText || 'New task...';
        
        const actionCell = document.createElement('td');
        const deleteButton = document.createElement('button');
        deleteButton.className = 'remove-btn';
        deleteButton.textContent = 'Remove';
        deleteButton.onclick = () => taskRow.remove();
        actionCell.appendChild(deleteButton);
        
        taskRow.appendChild(checkboxCell);
        taskRow.appendChild(textCell);
        taskRow.appendChild(actionCell);
        
        document.getElementById('active-tasks').appendChild(taskRow);
    }
    
    function loadCompletedTask(taskText) {
        const taskRow = document.createElement('tr');
        
        const checkboxCell = document.createElement('td');
        const taskCheckbox = document.createElement('input');
        taskCheckbox.type = 'checkbox';
        taskCheckbox.checked = true;
        taskCheckbox.className = 'task-status';
        
        taskCheckbox.addEventListener('change', function() {
            const targetTable = this.checked ? 
                document.getElementById('completed-tasks') : 
                document.getElementById('active-tasks');
            targetTable.appendChild(taskRow);
        });
        
        checkboxCell.appendChild(taskCheckbox);
        
        const textCell = document.createElement('td');
        textCell.className = 'editable';
        textCell.contentEditable = true;
        textCell.textContent = taskText;
        
        const actionCell = document.createElement('td');
        const deleteButton = document.createElement('button');
        deleteButton.className = 'remove-btn';
        deleteButton.textContent = 'Remove';
        deleteButton.onclick = () => taskRow.remove();
        actionCell.appendChild(deleteButton);
        
        taskRow.appendChild(checkboxCell);
        taskRow.appendChild(textCell);
        taskRow.appendChild(actionCell);
        
        document.getElementById('completed-tasks').appendChild(taskRow);
    }
    
    // Initialize with sample tasks
    createTask('Review project documentation');
    createTask('Team meeting at 2 PM');
    createTask('Update progress report');
    createTask('Code review for feature branch');
</script>

Posted on Sat, 13 Jun 2026 16:21:42 +0000 by starsol