I wrote a todo app with JavaScript and want to have it reviewed to see if I can make it better.
I think my JavaScript is messy and can be improved a lot. Please share your thoughts and way to improve this (I think my JavaScript can be half of the code to do the exact same thing).
Here is my app.
var mainInput = document.getElementById("mainInput");
var totalTodo = document.getElementById('totalTodos');
// Set this to give unique id on each todo list
var todoid = '0';
var todoDone = '0';
// Add todos - Trigger on Enter
mainInput.addEventListener("keyup", function(e){
var key = e.which || e.keyCode;
if (key === 13) {
if (mainInput.value === ''){
// If empty value entered
//console.log('Empty value');
return false;
}else{
// If value passed
todoid++;
//console.log(todoid);
// Create element to hold new value
var node = document.createElement("LI");
// Add data attribute on li
node.setAttribute('id', 'todo_' + todoid);
// Greate i element - Check icon
var nodeTwo = document.createElement("I");
// Add i into li element
node.appendChild(nodeTwo);
// Add Classes into i
nodeTwo.className = 'ion-ios-circle-outline';
nodeTwo.setAttribute('id', 'child_todo_' + todoid);
// Save textnode from the value
var textnode = document.createTextNode(mainInput.value);
// Add that into li
node.appendChild(textnode);
// Greate i element - Remove icon
var nodeThree = document.createElement("I");
// Add i into li element
node.appendChild(nodeThree);
// Add Classes into i
nodeThree.className = 'ion-ios-close-empty';
nodeThree.setAttribute('id', 'close_child_todo_' + todoid);
// Add new list on the main div
document.getElementById('todoList').appendChild(node);
// Clear input
mainInput.value = '';
//console.log(mainInput.value);
// Update total todos
totalMsg(todoid, todoDone);
//console.log('Total ' + todoid + ' todos to do');
}
}
});
// Fuction to show total message
function totalMsg(todoid, todoDone){
if(todoid === 1){
return totalTodos.innerHTML = '<b>' + todoid + '</b> thing to do / <b>' + todoDone + '</b> completed';
}else{
return totalTodos.innerHTML = '<b>' + todoid + '</b> things to do / <b>' + todoDone + '</b> completed';
}
}
// Function to check Class name on elements
function hasClass(element, cls) {
return (' ' + element.className + ' ').indexOf(' ' + cls + ' ') > -1;
}
/* Completed todo
** http://jsfiddle.net/founddrama/ggMUn/
** http://stackoverflow.com/questions/646628/how-to-check-if-a-string-startswith-another-string
*/
document.querySelector('body').addEventListener('click', function(event) {
if (event.target.id.startsWith("child_todo_")) {
// Get clicked item's ID
var todoClicked = event.target.id;
//console.log(todoClicked);
var todoClickedElement = document.getElementById(todoClicked);
todoClickedElement.classList.toggle('completed');
var parent_tce = todoClickedElement.parentElement.id;
//console.log(parent_tce);
var completedList = document.getElementById(parent_tce);
completedList.classList.toggle('completedlist');
// if todoClickedElement has completed class add or substract
//console.log(hasClass(todoClickedElement, 'completed'));
if(hasClass(completedList, 'completedlist')){
todoDone++;
totalMsg(todoid, todoDone);
}else{
todoDone--;
totalMsg(todoid, todoDone);
}
}
});
// Remove todo
document.querySelector('body').addEventListener('click', function(event) {
// Select all elements have ID starts with "child_todo_close_"
if (event.target.id.startsWith("close_child_todo_")) {
var closeClicked = event.target.id;
//console.log(closeClicked);
var closeClickedElement = document.getElementById(closeClicked);
var parent_cce = closeClickedElement.parentElement.id;
// Update total todo number
var willBeRemoved = document.getElementById(parent_cce);
todoid--;
if(todoDone != 0 && hasClass(willBeRemoved, 'completedlist')){
todoDone--;
}
if(todoid === 0){
totalTodos.innerHTML = '';
}else{
totalMsg(todoid, todoDone);
}
// Remove clicked todo list
document.getElementById(parent_cce).remove();
}
});
*{
box-sizing: border-box;
-moz-box-sizing: border-box;
}
html, body{
font-family: 'Open Sans', sans-serif;
font-size: 16px;
color: #222;
}
.todoApp{
max-width: 400px;
margin: 0 auto;
}
.totalTodos{
font-size: 80%;
}
.todoList{
margin: 0;
padding: 0;
}
.todoApp li{
padding: 0;
list-style: none;
}
.todoApp i{
width: 30px;
height: 30px;
font-size: 24px;
text-align: center;
display: inline-block;
float: left;
color: #999;
padding: 0 4px;
cursor: pointer;
}
.completed:before{
content: "\f3fe" !important;
}
.completedlist{
text-decoration: line-through;
color: #12A74D;
}
.completedlist i:first-child{
color: #12A74D;
}
.todoInput li:first-child i{
display: none;
}
.todoApp i:last-child{
float: right;
}
.todoList{
margin-top: 10px;
}
.todoList > li{
background: #f8f8f8;
padding: 20px 5px;
border-bottom: 1px solid #eee;
}
/* Form elements */
.todoApp input{
width: 100%;
padding: 10px;
border: none;
border-bottom: 1px solid #ccc;
font-size: 16px;
font-weight: 300;
outline: none;
}
<html>
<!--
Todo app with Javascript
Created by O (Ohsik Park) Feb/2016
** http://www.OhsikPark.com
** Feel free to talk me! [email protected]
-------------------------------------------------------------
License: GNU General Public License
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Library used:
- Google Fonts (https://www.google.com/fonts)
- ionicons (http://ionicons.com/)
-->
<head>
<title>Todo app with Javascript</title>
<link type="text/css" rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="todoApp" id="todoApp">
<h1>Todo App with Javascript</h1>
<li id="todoInput">
<input type="text" name="mainInput" id="mainInput" placeholder="What needs to be done?" />
</li>
<p id="totalTodos" class="totalTodos"></p>
<ul id="todoList" class="todoList"></ul>
</div>
<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,700' rel='stylesheet' type='text/css'>
<link href='http://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css' rel='stylesheet' type='text/css'>
<script src="js/todo.js"></script>
</body>
</html>
totalMsg
doing the same thing regardless oftodoid
param value \$\endgroup\$todoid === 1
it should saything
instead ofthings
and that's working okay as far as I checked unless I'm misunderstanding your comment. \$\endgroup\$