</> Code Review
The application manages tasks using the following function groups:
- Data Management
- Build Checklist
- Business Logic
- Add Tasks
- Mark Tasks as Complete / Incomplete
- Delete Tasks
- Data Display
Click the section links below to learn more about the code.
Build Checklist
This function is the trigger point of the application. Helper functions (getLocalStorage, setLocalStorage) are used to access local storage.
Lines 8 - 10 Return seed data for testing purposes
Line 13 The variable modelData is the focal point of the application as it the holding space for display data.
// Build Checklist
function buildList() {
// Change source to LocalStorage
// Use seed data if local storage is empty (for testing only)
let local = getLocalStorage();
// This for TESTING PURPOSE (Comment out later)
if (local.length === 0) {
setLocalStorage(seedData);
local = getLocalStorage();
}
modelData = local;
displayData(modelData);
}
// Get Local Storage
function getLocalStorage() {
return JSON.parse(localStorage.getItem('taskArray')) || [];
}
// Set Local Storage
function setLocalStorage(array) {
localStorage.setItem('taskArray', JSON.stringify(array));
}
Add Task
The Add Task function creates an object which is then pushed to the task array. The array is then saved to local storage.
Lines 20 - 23 Both date fields use a helper function (setDateTime) to adjust for the impact of time.
// Add Task
function addTask() {
// Get array from local storage
const tasks = getLocalStorage();
// Task Object
const task = {};
// Set complete to false
task['complete'] = false;
// Get UUID
task['id'] = getUUID();
// Retrieve task from modal form
task['task'] = document.getElementById('newTask').value;
// Generate Today's Date - https://stackoverflow.com/questions/3894048/what-is-the-best-way-to-initialize-a-javascript-date-to-midnight
task['createdDate'] = setDateTime(new Date());
// Retrieve Due Date from Form
task['dueDate'] = setDateTime(document.getElementById('newDueDate').value);
// Push to array
tasks.push(task);
// Set array in local storage
setLocalStorage(tasks);
// Set modelData to new data
modelData = getLocalStorage();
// Reset form
document.getElementById('newTaskForm').reset();
// Display Data
displayData(modelData);
}
// Set Date and Time
function setDateTime(dateInput) {
let date = dateInput;
let mthAdjust = 1;
if (typeof dateInput === 'string') {
let [year, month, day] = dateInput.split('-');
mthAdjust = 0;
date = new Date(year, month, day);
}
const day = date.getDate(); // Returns the date
const month = date.getMonth() + mthAdjust; // Returns the month (adjusted based on type - string or object)
const year = date.getFullYear(); // Returns the year
return `${month}/${day}/${year}`;
}
Mark Task as Complete / Incomplete
Using the helper function (getId) the array object is retrieved. It is then updated and returned to local storage.
Line 15 The object id is retrieved.
Line 21 The object id is updated.
// Mark as Complete / Incomplete
function toggleComplete(e) {
let isComplete;
if (e.checked) {
isComplete = true;
} else {
isComplete = false;
}
// Get Tasks
let tasks = getLocalStorage();
// Task Id
let taskId = getId(e);
// Find where id matches Task ID
let task = tasks.find((t) => t.id === taskId);
// Update object element
task.complete = isComplete;
// Set Array
setLocalStorage(tasks);
displayData(getLocalStorage());
}
// Helper function
function getId(e) {
return e.parentElement.parentElement.children[1].innerText;
}
Delete Tasks
Similar to Mark Task as Complete, the getId was used to retrieve the task selected.
Line 12 The array filter method is used to retrieve all tasks, excluding the selected task. These tasks are then returned to the array in local storage.
// Delete Tasks
function deleteTask(e) {
console.log('Delete me!');
// Get Tasks
let tasks = getLocalStorage();
// Task Id
let taskId = getId(e);
// Find where id matches Task ID
let tasksfiltered = tasks.filter((t) => t.id !== taskId);
// Set Array
setLocalStorage(tasksfiltered);
displayData(getLocalStorage());
}
Display Data
Templates are used to pull the data and dynamically populate the HTML. This technique is particularly powerful as it keeps the HTML out of the Javascript. In addition, a helper function (formatDate) is used for date clean-up
Lines 3 and 4 Identifies the template and the code destination.
Line 10 In the for loop a copy of the template is populated with data then appended to the target destination.
// Display task data
function displayData(checklistArray) {
const myTemplate = document.getElementById('Data-Template');
const resultsBody = document.getElementById('resultsBody');
// clear table first
resultsBody.innerHTML = '';
// Number format reference https://www.w3schools.com/jsref/jsref_tolocalestring_number.asp
for (let i = 0; i < checklistArray.length; i++) {
const dataRow = document.importNode(myTemplate.content, true);
// Checkbox
let isChecked = checklistArray[i].complete;
let chkValue = isChecked ? 'checked' : '';
let checkbox = ``;
dataRow.getElementById('complete').innerHTML = checkbox;
dataRow.getElementById('id').textContent = checklistArray[i].id;
dataRow.getElementById('task').textContent = checklistArray[i].task;
dataRow.getElementById('createdDate').textContent = formatDate(
checklistArray[i].createdDate
);
dataRow.getElementById('dueDate').textContent = formatDate(
checklistArray[i].dueDate
);
// dataRow.getElementById('controls').textContent = checklistArray[i].controls;
resultsBody.appendChild(dataRow);
}
}
// formatDate
function formatDate(strDate) {
const date = new Date(strDate);
const day = date.getDate(); // Returns the date
const month = date.getMonth(); // Returns the month
const year = date.getFullYear(); // Returns the year
return `${month}/${day}/${year}`;
}