JavaScript To-Do List Project Source Code

How To Create a To-Do List Application in JavaScript, HTML and CSS

How To Create a Task Manager Application in JavaScript, HTML and CSS


In this JavaScript Tutorial, we will see how to create a task management application using  JavaScript, HTML5, CSS3.
This Todo app include functionalities like filtering and sorting capabilities, pagination, data persistence, import/export, Priority levels, due dates, and completion tracking .

What We Are Gonna Use In This Project:

- JavaScript Programming Language.
- HTML and CSS.
- Font-awesome.
- Visual Studio Editor.




if you want the source code click on the download button below




Project Source Code:



     - Save Tasks

Saves the current tasks array to browser's localStorage to preserve data.


// Save tasks to the browser's memory
// so they don't disappear when you close the page
function saveTodos() {
// localStorage is like a mini database in your browser
// We convert our tasks array
// to a string format (JSON) that can be stored
localStorage.setItem('todos', JSON.stringify(todos));
}





     - Display Engine
    
Filters, sorts, paginates, and displays tasks on the screen with styling and controls.

// Show tasks on the screen
function renderTodos() {

// Step 1: Filter tasks based on whether they're done or not
let filteredTodos = todos; // Start with all tasks

// Check which filter option is selected (all, active, or completed)
if (filterOption.value === 'active') {
// Only keep tasks that are NOT completed
                // Only show unfinished tasks
filteredTodos = todos.filter(todo => !todo.completed);
} else if (filterOption.value === 'completed') {
// Only keep tasks that ARE completed
                // Only show finished tasks
filteredTodos = todos.filter(todo => todo.completed);
}

// If 'all' is selected, we keep all tasks (no filter needed)

// Step 2: Only show tasks that match what you typed in the search box
// Convert search to lowercase for easier matching
const searchTerm = searchBar.value.toLowerCase();

// Keep only tasks where the text contains what you searched for
filteredTodos = filteredTodos.filter(todo =>
// Check if task contains search term
todo.text.toLowerCase().includes(searchTerm)
);

// Step 3: Put tasks in order based on what sorting option you picked
filteredTodos.sort((a, b) => {
// sort() compares two items at a time to decide their order

if (sortOption.value === 'due-date') {
// Put earliest due dates first by comparing date values
// Smaller numbers (earlier dates) come first
return new Date(a.dueDate) - new Date(b.dueDate);
} else if (sortOption.value === 'priority') {
// Put highest priority tasks first
// We assign number values to priorities: high=3, medium=2, low=1
const priorityOrder = { high: 3, medium: 2, low: 1 };
// Compare priority numbers (higher number comes first)
return priorityOrder[b.priority] - priorityOrder[a.priority];
}

// If no special sorting, show oldest tasks first (by ID/creation time)
return a.id - b.id; // Smaller IDs (created earlier) come first

});

// Step 4: Only show tasks for the current page (not all at once)
// Calculate which tasks should appear on current page
// Where to start (e.g., page 1 starts at 0)
const startIndex = (currentPage - 1) * todosPerPage;
// Where to end (e.g., page 1 ends at 5)
const endIndex = startIndex + todosPerPage;
// Get just the chunk of tasks for this page
const currentTodos = filteredTodos.slice(startIndex, endIndex);

// Step 5: Clear the current list before showing new tasks
todoList.innerHTML = ''; // Remove all existing tasks from screen

// Step 6: Add each task to the page
currentTodos.forEach((todo) => {
// Create a new list item for each task
const li = document.createElement('li');

// Set classes for styling (different colors for completed tasks and priorities)
li.className = `todo-item ${todo.completed ? 'completed' : ''}
                                        priority-${todo.priority}`;

// Create colorful tag showing priority level (Low/Medium/High)
// Make the first letter uppercase for nicer display
const priorityBadge = `<span class="priority-badge ${todo.priority}">
${todo.priority.charAt(0).toUpperCase() +
todo.priority.slice(1)}</span>`;
// Create HTML for each task with its text, due date, and buttons
li.innerHTML = `
<div class="task-info">
<span class="task-text">${priorityBadge}${todo.text}</span>
<span class="due-date">Due: ${todo.dueDate}</span>
</div>
<div class="todo-actions">
<button class="complete-btn" onclick="toggleComplete(${todo.id})">
<i class="fas ${todo.completed ? 'fa-undo' : 'fa-check'}"></i>
<span class="button-text">${todo.completed ? ' Undo' : ' Complete'}</span>
</button>
<button class="edit-btn" onclick="editTodo(${todo.id})">
<i class="fas fa-edit"></i>
<span class="button-text"> Edit</span>
</button>
<button class="delete-btn" onclick="deleteTodo(${todo.id})">
<i class="fas fa-trash"></i>
<span class="button-text"> Delete</span>
</button>
</div>
`;

// Add the finished task item to our list
todoList.appendChild(li);
});

// Step 7: Update page buttons and stats at the bottom
updatePaginationButtons(filteredTodos.length); // Enable/disable page buttons
updateStats(); // Update the counts of tasks (total, active, completed)
}



     - Page Navigation Controller.

Enables/disables Previous and Next buttons based on current page and total task count.


// Turn on/off Previous and Next buttons depending on which page you're on
function updatePaginationButtons(totalTodos) {
// Calculate how many pages we need based on total tasks
// Round up to include partial pages
const totalPages = Math.ceil(totalTodos / todosPerPage);

// Disable Previous button if we're on the first page
// Can't go back if on first page
prevPageBtn.disabled = currentPage === 1;

// Disable Next button if we're on the last page or have no tasks
// Can't go forward if on last page
nextPageBtn.disabled = currentPage === totalPages || totalPages === 0;

}



     - Task Creation.

Creates a new task from form input with unique ID, priority, due date, and adds it to the list.


// Add a new task to the list
function addTodo(e) {
// Stop the form from refreshing the page (default behavior)
e.preventDefault();

// Get the task text and remove any extra spaces
const todoText = todoInput.value.trim();

// Get the selected due date and priority
const dueDate = dueDateInput.value;
const priority = priorityInput.value;

// Only add task if there's actual text (not empty)
if (todoText) {
// Create a new task object with all its details
const newTodo = {
id: Date.now(), // Use current time as a unique ID number (milliseconds since 1970)
text: todoText, // The actual task description
completed: false, // New tasks always start as not completed
// Format the date nicely, or use "No due date" if none selected
dueDate: dueDate ? new Date(dueDate).toLocaleDateString() : 'No due date',
priority: priority, // The importance level (low/medium/high)
dateAdded: new Date().toISOString() // Store when this task was created
};

// Add task to our list of tasks
todos.push(newTodo);

// Save to browser storage so tasks remain after page refresh
saveTodos();

// Clear the form fields after adding
todoInput.value = ''; // Empty the task input
dueDateInput.value = ''; // Reset due date
priorityInput.value = 'low'; // Reset priority to default

// Jump to the page where the new task will appear (the last page)
currentPage = Math.ceil(todos.length / todosPerPage);

// Refresh the task display to show the new task
renderTodos();
}
}




     - Status Toggle.

Switches a task between completed and active status by finding it by ID and flipping its boolean.


// Mark a task as done or not done
function toggleComplete(id) {
// Find the specific task with this ID
const todo = todos.find(t => t.id === id);

// If we found it, update its status
if (todo) {
// Switch between done and not done (true/false)
todo.completed = !todo.completed;
saveTodos(); // Save the updated task list
renderTodos(); // Refresh the display
}
}




     - In-Place Task Editor.

Allows editing of task text, due date, and priority using browser prompt dialogs.


// Change the text or details of a task
function editTodo(id) {
// Find the specific task with this ID
const todo = todos.find(t => t.id === id);

// If we found it, show prompts to edit it
if (todo) {
// Ask for new task text in a popup
const newText = prompt('Edit task:', todo.text);

// Only proceed if user didn't click Cancel
if (newText !== null) {

// Update the task text (removing any extra spaces)
todo.text = newText.trim();

// Ask for new due date in a popup
const newDueDate = prompt('Edit due date (YYYY-MM-DD):', todo.dueDate);
// Only proceed if user didn't click Cancel
if (newDueDate !== null) {
// Update due date or use "No due date" if empty
todo.dueDate = newDueDate || 'No due date';
}

// Ask for new priority in a popup
const newPriority = prompt('Edit priority (low/medium/high):', todo.priority);
// Only update priority if valid and user didn't click Cancel
if (newPriority !== null && ['low', 'medium', 'high'].includes(newPriority)) {
todo.priority = newPriority;
}

saveTodos(); // Save changes to browser storage
renderTodos(); // Refresh the display

}

}

}





     - Task Removal.

Removes a task from the list after user confirmation and handles page adjustment if needed.


// Remove a task from the list
function deleteTodo(id) {
// Ask user to confirm deletion to prevent accidents
if (confirm('Are you sure you want to delete this task?')) {
// Keep all tasks EXCEPT the one with this ID (effectively removing it)
todos = todos.filter(t => t.id !== id);

// Save the updated list
saveTodos();

// If we deleted the last task on this page, go back a page
// (This happens when tasks per page divides evenly into total tasks)
if (todos.length % todosPerPage === 0 && currentPage > 1) {
currentPage--;
}
// Refresh the display
renderTodos();

}
}




     - Pagination Navigation.

Moves between pages of tasks by incrementing or decrementing the current page number.


// Move between pages of tasks
function changePage(direction) {
// Increase or decrease page number
currentPage += direction; // Add 1 to go forward, subtract 1 to go back
// Refresh display to show the new page
renderTodos();
}






     - Real-time Statistics.

Calculates and displays total, active, and completed task counts in the stats section.


// Show how many tasks are total, active, and done
function updateStats() {
// Count all tasks
const totalTasks = todos.length;

// Count how many are marked as done
const completedTasks = todos.filter(t => t.completed).length;

// Calculate how many are still active (not done)
const activeTasks = totalTasks - completedTasks;

// Update the stats display with these numbers
statsDisplay.innerHTML = `
<strong>${totalTasks}</strong> Total Tasks |
<strong>${activeTasks}</strong> Active |
<strong>${completedTasks}</strong> Completed
`;
}







     - Data Export.

Creates and downloads a JSON file containing all tasks for backup purposes.


// Save tasks to a file you can download
function exportTodos() {
// Convert the tasks array to a string format (JSON)
const tasksJSON = JSON.stringify(todos);

// Create a special URL that represents this data as a file
const dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(tasksJSON);

// Create a fake download button in memory (not visible on screen)
const downloadLink = document.createElement('a');
downloadLink.setAttribute("href", dataStr); // Set the file data
downloadLink.setAttribute("download", "tasks.json"); // Set the filename
document.body.appendChild(downloadLink); // Add to page temporarily

// Click this fake button to start the download
downloadLink.click();
// Remove the fake button after download starts
downloadLink.remove();

}





     - Data Import

Reads an uploaded JSON file and replaces current tasks with the imported data.


// Load tasks from a file on your computer
function importTodos(event) {
// Get the file the user selected
const file = event.target.files[0];

// Only proceed if a file was actually selected
if (file) {
// Create a tool to read the file contents
const reader = new FileReader();

// Set up what happens when the file is loaded
reader.onload = function(e) {

try {

// Try to convert the file content to a tasks array
const importedTodos = JSON.parse(e.target.result);

// Replace our current tasks with the imported ones
todos = importedTodos;

// Save to browser storage
saveTodos();

// Refresh the display
renderTodos();

// Let the user know it worked
alert("Tasks imported successfully!");

} catch (error) {
// If anything goes wrong (like invalid file format)
alert("Error importing tasks. Please make sure the file is valid.");
}

};

// Start reading the file content
reader.readAsText(file);

}

}





Java - Create Custom Toggle Buttons

How to Create a Custom JToggleButton in Java Netbeans

How to Create a Custom JToggleButton in Java Netbeans


In this Java Tutorial we will see How To Create a custom toggle button component with sliding animation, Gradient backgrounds, Multiple color themes and Status indicator dot when activated In Java Using Netbeans.


What We Are Gonna Use In This Project:

- Java Programming Language.
- NetBeans Editor.





Project Source Code:



/**
 *
 * @author 1BestCsharp
 * 
 */
public class CustomToggleButton extends JToggleButton {
    // Current position of the toggle button (0 = off, 1 = on)
    private float position = 0;
    // Position used for the glow animation effect
    private float glowPosition = 0;
    // Default background color when the toggle is off
    private Color toggleColor = new Color(200, 200, 220);
    // Default color when the toggle is active/on
    private Color activeColor = new Color(130, 90, 255);
    // Timer for handling smooth animations
    private Timer animationTimer;
    // Duration of the toggle animation in milliseconds
    private static final int ANIMATION_DURATION = 200;
    
    
    public CustomToggleButton(){
        
        setPreferredSize(new Dimension(70*2, 35*2));
        setContentAreaFilled(false);
        setBorderPainted(false);
        setFocusPainted(false);
        setCursor(new Cursor(Cursor.HAND_CURSOR));
        
        // Initialize animation timer that updates every 16ms
        animationTimer = new Timer(16, e ->{
            // Determine target position based on selected state
            float targetPosition = isSelected() ? 1 : 0;
            // Calculate step size for smooth animation
            float step = 1.0f / (ANIMATION_DURATION / 16.0f);
            
            // Animate toggle position
            if(position < targetPosition){
                // Move position towards 1 (on state)
                position = Math.min(position + step, 1);
                // Apply easing function to smooth the movement
                glowPosition = easeInOut(position);
                repaint();
            }
            else if(position > targetPosition){
                // Move position towards 0 (off state)
                position = Math.max(position - step, 0);
                // Apply easing function to smooth the movement
                glowPosition = easeInOut(position);
                repaint();
            }
        });
        
        // Start animation when the toggle state changes
        addItemListener(e -> {
            
            if(!animationTimer.isRunning()){
                animationTimer.start();
            }
        
        });
        
        
    }
    
    @Override
    protected void paintComponent(Graphics g){
        // Create a new Graphics2D object with anti-aliasing enabled
        Graphics2D g2d = (Graphics2D) g.create();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        
        // Calculate dimensions for the toggle button
        int width = getWidth();
        int height = getHeight();
        int toggleWidth = width - 4;
        int toggleHeight = height - 4;
        int diameter = toggleHeight - 4;
        
        // Create rounded rectangle for button background
        RoundRectangle2D background = new RoundRectangle2D.Float(
                2, 2, toggleWidth, toggleHeight, toggleHeight, toggleHeight
        );
        
        // Create gradient for glass effect
        GradientPaint gradientBackground = new GradientPaint(
                0, 0, new Color(255, 255, 255, 50),
                0, height, new Color(255, 255, 255, 10)
        );
        
        // Draw main background
        g2d.setColor(isSelected() ? activeColor : toggleColor);
        g2d.fill(background);
         // Apply glass effect gradient
        g2d.setPaint(gradientBackground);
        g2d.fill(background);
        
        // Add subtle inner shadow to background
        g2d.setColor(new Color(0,0,0,10));
        g2d.setStroke(new BasicStroke(1.5f));
        g2d.draw(background);
        
        // Calculate position of the toggle circle
        float circleX = 4 + (toggleWidth - diameter - 4) * glowPosition;
        float circleY = 4;
        
        // Draw the main toggle circle 
        g2d.setColor(Color.WHITE);
        Ellipse2D circle = new Ellipse2D.Float(circleX, circleY, diameter, diameter);
        g2d.fill(circle);
        
        // Add gradient to the toggle circle
        GradientPaint gradientKnob = new GradientPaint(
                circleX, circleY, new Color(255, 255, 255),
                circleX, circleY + diameter, new Color(240, 240, 240)
        );
        
        g2d.setPaint(gradientKnob);
        g2d.fill(circle);
        
        // Add border to toggle circle
        g2d.setColor(new Color(0, 0 , 0, 30));
        g2d.setStroke(new BasicStroke(1f));
        g2d.draw(circle);
        
        // Draw status indicator dot when selected
        if(isSelected()){
            float dotSize = diameter * 0.5f;
            float dotX = circleX + (diameter - dotSize) / 2;
            float dotY = circleY + (diameter - dotSize) / 2;
            g2d.setColor(activeColor);
            g2d.fill(new Ellipse2D.Float(dotX, dotY, dotSize, dotSize));
        }
        
        // Clean up graphics resources
        g2d.dispose();
                
        
    }
    
    
    
    // Easing function to create smooth acceleration and deceleration
    private float easeInOut(float t){
        
        return t < 0.5f ? 2 * t * t : -1 + (4 - 2 * t) * t;
        
    }
    
    // Method to change the active color of the toggle
    public void setActiveColor(Color color){
        this.activeColor = color;
        repaint();
    }
    
    
    public static void main(String[] args) {
        
        JFrame frame = new JFrame("Toggle Buttons");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setBackground(Color.WHITE);
        frame.setSize(600, 250);
        frame.setLayout(new FlowLayout(FlowLayout.CENTER, 20, 20));
        
        CustomToggleButton cbtn = new CustomToggleButton();
        CustomToggleButton toggleBlue = new CustomToggleButton();
        CustomToggleButton toggleGreen = new CustomToggleButton();
        CustomToggleButton toggleRed = new CustomToggleButton();
        CustomToggleButton toggleBlack = new CustomToggleButton();
        CustomToggleButton toggleYellow = new CustomToggleButton();
        
        toggleBlue.setActiveColor(new Color(64, 150, 255));
        toggleGreen.setActiveColor(new Color(75, 210, 140));
        toggleRed.setActiveColor(new Color(239, 68, 68));
        toggleBlack.setActiveColor(new Color(20, 5, 5));
        toggleYellow.setActiveColor(new Color(241, 196, 15));
        
        
        frame.add(cbtn);
        frame.add(toggleBlue);
        frame.add(toggleGreen);
        frame.add(toggleRed);
        frame.add(toggleBlack);
        frame.add(toggleYellow);
        
        
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        
    }

}


 

The Final Result:

Custom Toggle Buttons In Java

Create Custom Toggle Buttons In Java