Key Takeaways
- The tutorial demonstrates how to build a basic to-do list application using jQuery, jQuery UI, and Bootstrap. The application allows users to create tasks, categorize them into ‘pending’, ‘in progress’, and ‘completed’, and delete tasks.
- The tutorial covers the creation of a static HTML and CSS page, defining JavaScript constants, creating and deleting tasks, and saving tasks in local storage using HTML5’s local storage.
- The application also implements a drag and drop feature using jQuery UI, allowing users to move tasks between categories. The tutorial includes code for making each task draggable and each category droppable, and for deleting tasks when they are dropped in a designated delete area.
- The tutorial also includes a FAQ section that provides additional functionality such as adding a delete button to each item, editing an item, marking an item as completed, sorting items, filtering items, saving the to-do list to a file, loading the to-do list from a file, adding categories, due dates, and priorities to the to-do list.
Prerequisites
The following libraries are used in this project.- jQuery 1.10.2
- jQuery UI 1.10.3
- Bootstrap 2.2.2
Creating the Markup and CSS
Let’s create the basic look and feel of the application before adding the functionality via JavaScript.<div class="task-list" id="pending">
<h3>Pending</h3>
<!-- Sample task added manually to check look -->
<div class="todo-task">
<div class="task-header">Sample Header</div>
<div class="task-date">25/06/1992</div>
<div class="task-description">Lorem Ipsum Dolor Sit Amet</div>
</div>
</div>
<div class="task-list" id="inProgress">
<h3>In Progress</h3>
</div>
<div class="task-list" id="completed">
<h3>Completed</h3>
</div>
<div class="task-list">
<h3>Add a task</h3>
<form id="todo-form">
<input type="text" placeholder="Title" />
<textarea placeholder="Descrtipion"></textarea>
<input type="text" placeholder="Due Date (dd/mm/yyyy)" />
<input type="button" class="btn btn-primary" value="Add Task" />
</form>
<input type="button" class="btn btn-primary" value="Clear Data" />
<div id="delete-div">Drag Here to Delete</div>
</div>
Next, add some styling to the elements using the following CSS.
.task-list {
width: 250px;
float: left;
margin: 0 5px;
background-color: #e3e3e3;
min-height: 240px;
border-radius: 10px;
padding-bottom: 15px;
}
.task-list input, .task-list textarea {
width: 240px;
margin: 1px 5px;
}
.task-list input {
height: 30px;
}
.todo-task {
border-radius: 5px;
background-color: #fff;
width: 230px;
margin: 5px;
padding: 5px;
}
.task-list input[type="button"] {
width: 100px;
margin: 5px;
}
.todo-task > .task-header {
font-weight: bold;
}
.todo-task > .task-date {
font-size: small;
font-style: italic;
}
.todo-task > .task-description {
font-size: smaller;
}
h3 {
text-align: center;
}
#delete-div {
background-color: #fff;
border: 3px dotted #000;
margin: 10px;
height: 75px;
line-height: 75px;
text-align: center;
}
Our static to-do page should look like the following image.
Defining the JavaScript Constants
Throughout this tutorial, we will be referring to certain constants to avoid hard coding values. These constants are shown below.var defaults = {
// CSS selectors and attributes that would be used by the JavaScript functions
todoTask: "todo-task",
todoHeader: "task-header",
todoDate: "task-date",
todoDescription: "task-description",
taskId: "task-",
formId: "todo-form",
dataAttribute: "data",
deleteDiv: "delete-div"
}, codes = {
"1" : "#pending", // For pending tasks
"2" : "#inProgress",
"3" : "#completed"
};
Creating Tasks
Tasks are created using the following JavaScript function.// Add Task
var generateElement = function(params) {
var parent = $(codes[params.code]),
wrapper;
if (!parent) {
return;
}
wrapper = $("<div />", {
"class" : defaults.todoTask,
"id" : defaults.taskId + params.id,
"data" : params.id
}).appendTo(parent);
$("<div />", {
"class" : defaults.todoHeader,
"text": params.title
}).appendTo(wrapper);
$("<div />", {
"class" : defaults.todoDate,
"text": params.date
}).appendTo(wrapper);
$("<div />", {
"class" : defaults.todoDescription,
"text": params.description
}).appendTo(wrapper);
};
The following code sample shows how a single task is generated.
generateElement({
id: "123",
code: "1",
title: "My Uber Important Task",
date: "5/2/2014",
description: "I have to do a lot of steps to implement this task!"
});
Deleting Tasks
Removing tasks is fairly simple, and can be accomplished using the following function.var removeElement = function(params) {
$("#" + defaults.taskId + params.id).remove();
};
Saving Tasks in Local Storage
The tasks we create could be stored using a database, cookies, or a number of other technologies. However, in this application we’re going to use HTML5’s local storage for its simplicity. In JavaScript, the variablelocalStorage
stores all of this data. The following code sample shows how the to-do list data is retrieved from local storage.
var data = JSON.parse(localStorage.getItem("todoData"));
Each task would be stored within the data
variable. An example task object is shown below.
{
id : id, // Unique ID; timestamp is used here
code: "1", // Code identifying the category
title: title, // Title of the task
date: date, // Due date
description: description // Description of the task
}
We update the saved data in local storage using the following code.
localStorage.setItem("todoData", JSON.stringify(data));
Submitting the To-Do Form
When the to-do form is submitted, a new task is created and added to local storage, and the contents of the page are updated. The following function implements this functionality.var addItem = function() {
var inputs = $("#" + defaults.formId + " :input"),
errorMessage = "Title can not be empty",
id, title, description, date, tempData;
if (inputs.length !== 4) {
return;
}
title = inputs[0].value;
description = inputs[1].value;
date = inputs[2].value;
if (!title) {
generateDialog(errorMessage);
return;
}
id = new Date().getTime();
tempData = {
id : id,
code: "1",
title: title,
date: date,
description: description
};
// Saving element in local storage
data[id] = tempData;
localStorage.setItem("todoData", JSON.stringify(data));
// Generate Todo Element
generateElement(tempData);
// Reset Form
inputs[0].value = "";
inputs[1].value = "";
inputs[2].value = "";
};
Implementing Drag and Drop
jQuery UI provides drag and drop functionality. We need to make each task draggable and each of the three categories droppable. To delete a task, we need to hide the delete area by default, and show it during the time an item is being dragged. Therefore, we first modify thegenerateElement()
function slightly to first make the to-do list items draggable, and then make the delete area visible when the item is being drug.
$("." + defaults.todoTask).draggable();
// Add Task
var generateElement = function(params) {
wrapper.draggable({
start: function() {
$("#" + defaults.deleteDiv).show();
},
stop: function() {
$("#" + defaults.deleteDiv).hide();
}
});
...
};
Secondly, we need to add the droppable()
function to each of the categories as the elements are supposed to be dropped in any one of the three areas.
// Adding drop function to each category of task
$.each(codes, function(index, value) {
$(value).droppable({
drop: function(event, ui) {
var element = ui.helper,
css_id = element.attr("id"),
id = css_id.replace(options.taskId, ""),
object = data[id];
// Removing old element
removeElement(object);
// Changing object code
object.code = index;
// Generating new element
generateElement(object);
// Updating Local Storage
data[id] = object;
localStorage.setItem("todoData", JSON.stringify(data));
// Hiding Delete Area
$("#" + defaults.deleteDiv).hide();
}
});
});
Thirdly, we need to add some code to delete tasks when they are dropped in the delete area.
// Adding drop function to delete div
$("#" + options.deleteDiv).droppable({
drop: function(event, ui) {
var element = ui.helper,
css_id = element.attr("id"),
id = css_id.replace(options.taskId, ""),
object = data[id];
// Removing old element
removeElement(object);
// Updating local storage
delete data[id];
localStorage.setItem("todoData", JSON.stringify(data));
// Hiding Delete Area
$("#" + defaults.deleteDiv).hide();
}
});
Conclusion
The final code is available on GitHub. You can also check out the project’s live demo.Frequently Asked Questions (FAQs) about Building a List with jQuery and Local Storage
How can I add a delete button to each item in the to-do list?
Adding a delete button to each item in the to-do list can be achieved by appending a button element to each list item during its creation. You can use the jQuery append() method to add a button element with a class of ‘delete’. Then, you can use jQuery’s on() method to attach a click event handler to the delete button, which removes the parent list item when clicked. Remember to also remove the item from local storage.
How can I edit an item in the to-do list?
To edit an item in the to-do list, you can add an ‘edit’ button similar to the ‘delete’ button. When this button is clicked, you can replace the text of the list item with an input field containing the current text. The user can then edit the text and press ‘Enter’ to save the changes. Don’t forget to update the item in local storage as well.
How can I mark an item as completed?
Marking an item as completed can be done by toggling a ‘completed’ class on the list item. You can attach a click event handler to the list item that adds or removes the ‘completed’ class when clicked. You can use CSS to style completed items differently, such as striking through the text. Remember to update the item’s status in local storage.
How can I sort the items in the to-do list?
Sorting the items in the to-do list can be done using jQuery’s sort() method. You can sort the items based on their text, or based on their completed status. After sorting the items, you can clear the list and add the items back in the sorted order. Don’t forget to update the order of items in local storage.
How can I filter the items in the to-do list?
Filtering the items in the to-do list can be done by adding an input field that the user can type into. You can then use jQuery’s filter() method to hide the items that do not match the user’s input. Remember to update the visibility of items in local storage.
How can I save the to-do list to a file?
Saving the to-do list to a file can be done by converting the list to a JSON string using JSON.stringify(), and then using the download attribute of the anchor element to download the string as a file. The user can then load the list from the file by reading the file and parsing the JSON string using JSON.parse().
How can I load the to-do list from a file?
Loading the to-do list from a file can be done by using the FileReader API to read the file. The file can be selected using an input element of type ‘file’. After reading the file, you can parse the JSON string using JSON.parse() and add the items to the list and to local storage.
How can I add categories to the to-do list?
Adding categories to the to-do list can be done by adding a select element to the form used to add new items. The select element can contain option elements for each category. When a new item is added, the selected category can be stored as a data attribute on the list item. You can then filter the items based on their category.
How can I add due dates to the to-do list?
Adding due dates to the to-do list can be done by adding a date input field to the form used to add new items. When a new item is added, the selected date can be stored as a data attribute on the list item. You can then sort or filter the items based on their due date.
How can I add priorities to the to-do list?
Adding priorities to the to-do list can be done by adding a select element to the form used to add new items. The select element can contain option elements for each priority level. When a new item is added, the selected priority can be stored as a data attribute on the list item. You can then sort or filter the items based on their priority.
Shaumik is a data analyst by day, and a comic book enthusiast by night (or maybe, he's Batman?) Shaumik has been writing tutorials and creating screencasts for over five years. When not working, he's busy automating mundane daily tasks through meticulously written scripts!