First things first, when making a list, you should use the correct list elements. Your "To Do" list fits the definition of a description list (<dl>
) so you should use that instead of <div>
elements.
You can save a lot of lines of code by getting rid of the classes and creating an array of colors. Make sure that the colors are in the same order that you want them to be shown. We will use this array to set the background color based on an incremented counter.
var colors = ['#b2d8b2', '#ffffb2', '#ffe4b2', '#ffb2b2', '#fff'];
You can also greatly simplify your script by using a "factory" function which defines a scope and builds an event listener function, which it returns. This creates a "safe" scope for each listener function to reside in that we can define variables which will store information between events.
In the following snippet, we define a count
variable that we increment on each click. We use the incremented variables remainder when dividing by the length of the color array using the modulo operator %
. If the number is smaller than the length of the array, it will return the number, otherwise it will return the remainder when dividing by the length of the array, allowing us to loop through continuously.
function todoItemListener() {
var count = 0;
return function () {
$(this).css({ 'background-color': colors[count++ % colors.length] });
}
}
Then instead of assigning the function declaration as normal (without the parenthesis), we assign the result of the factory function, simply append the parenthesis and the function will execute and return the resulting listener function. This allows us to add as many listener functions as we want, so if you're adding new todo list items, we can simply build another listener function.
$('.todo-list dd').each(function () {
$(this).on('click', todoItemListener());
});
$('.add-item').on('click', function () {
var list = this.parentNode.parentNode;
$('<dd>To-do list item</dd>').appendTo(list).on('click', todoItemListener());
});
This method also allows you to easily change the array of colors at will. So say if an option is selected somewhere on the page, another color could become available, or not available.
Also, for some extra UX goodness, I added CSS to stop selection of the text on click (that can get annoying) and to change the cursor to a pointer to give it a more actionable feel.
Here is the full demo, I've included multiple to-do lists to show that it can be done.
var colors = ['#b2d8b2', '#ffffb2', '#ffe4b2', '#ffb2b2', '#fff'];
function todoItemListener() {
var count = 0;
return function () {
$(this).css({ 'background-color': colors[count++ % colors.length] });
}
}
$('.todo-list dd').each(function () {
$(this).on('click', todoItemListener());
});
$('.add-item').on('click', function () {
var list = this.parentNode.parentNode;
$('<dd>To-do list item</dd>').appendTo(list).on('click', todoItemListener());
});
.glyphicon-plus-sign {
font-size: 15px;
}
.todo-list {
background: #efefef;
padding: 3px;
}
.todo-list dd {
margin: 0;
text-align: left;
padding: 3px;
margin-bottom: 7px;
border: 1px solid;
border-color: #e8e7e7;
background-color: #fff;
}
.add-item, .todo-list dd {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
cursor: pointer;
}
.add-item {
float: right;
margin: 4px;
}
.todo-list dh::after {
content: "";
display: block;
clear: both;
}
.todo-list dh h3 {
float: left;
margin: 0px;
max-width: 100%;
overflow: hidden;
}
/* This rule is for the demo only */
.wrp {
float: left;
width: 33.33333333%;
padding: 1px;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<div class="wrp">
<dl class="todo-list" id="todo-list-1">
<dh>
<h3 class="center" contenteditable>To Do List 1</h3>
<span class="add-item glyphicon glyphicon-plus-sign"></span>
</dh>
<dd>To-do list item</dd>
<dd>To-do list item</dd>
<dd>To-do list item</dd>
</dl>
</div>
<div class="wrp">
<dl class="todo-list" id="todo-list-2">
<dh>
<h3 class="center">To Do List 2</h3>
<span class="add-item glyphicon glyphicon-plus-sign"></span>
</dh>
<dd>To-do list item</dd>
<dd>To-do list item</dd>
<dd>To-do list item</dd>
</dl>
</div>
<div class="wrp">
<dl class="todo-list" id="todo-list-3">
<dh>
<h3 class="center">To Do List 3</h3>
<span class="add-item glyphicon glyphicon-plus-sign"></span>
</dh>
<dd>To-do list item</dd>
<dd>To-do list item</dd>
<dd>To-do list item</dd>
</dl>
</div>
start voting to delete with a vengeance!
What?! – Flavour