3
\$\begingroup\$

The app is a todo list with a three-day calendar. Users can add and remove lists and it's all stored in local storage. My aim was to use vanilla JS but I did use jQuery for the date picker.

I'm just looking for some feedback on my code. This is my first app I have coded and I'm looking for some constructive criticism on my JavaScript code structure and how I could improve it so I can improve future apps.

http://jsfiddle.net/Fa8Xx/3858/

(function(){

var today = new Date();
today.setHours(0,0,0,0);

var yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
yesterday.setHours(0,0,0,0);

var tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
tomorrow.setHours(0,0,0,0);


var elems = document.querySelectorAll("nav li");

var listElems = document.querySelectorAll("div > ul");

var itemBox = document.getElementById("item");

var dateBox = document.getElementById("date");

var id;

var json ={

};

var retrivedObject = localStorage.getItem('json');

if( retrivedObject !== null && Object.keys(retrivedObject).length >= 1){

    json = JSON.parse(retrivedObject);

}

var num = 0;

var addButton = document.getElementById("addButton");
addButton.addEventListener("click", objectTask); 

var removeButton = document.getElementById('removeButton');
removeButton.addEventListener("click", removeList);

$('#date').datepicker({dateFormat: "dd/mm/yy"});

function onLoad(){

    if(json !== null || Object.keys(json).length !== 0){

            var loadDate;
            var loadTodo;
            var jsonLength = Object.keys(json).length;

        for (var i = 0; i < jsonLength; i++) {
             loadDate = json[i].date;
             loadTodo = json[i].todo;

             selectId(loadDate);

             makeList(id, loadTodo, num);

             num++
        }

         num = jsonLength++;
    }
    return
} 

onLoad(); 

function objectTask(){

    var itemTask = itemBox.value;

    var dateee = dateBox.value;
    var dateSplit = dateBox.value.split('/'),
    dateTask = new Date(dateSplit[2],dateSplit[1]-1,dateSplit[0], 0, 0, 0, 0);


    if (validate(itemTask, dateee) === false){
        return
    }

    dateTask = dateTask.getTime();

    addToDataB(itemTask, dateTask);

    newDate = json[num].date;

    selectId(newDate);

    makeList(id, itemTask, num);

    num++
    clear();
    localStorage.setItem('json' , JSON.stringify(json));

}

var validate = function(itemTask, dateee){

    var ex = /^(\d{1,2})\/(\d{1,2})\/(\d{4})$/;

    if(itemTask == "" || itemTask == null){
            alert("help");
            return false;
    }

    if(dateee != '' && dateee.match(ex)){
        if(regs = dateee.match(ex)) {

            if(regs[1] < 1 || regs[1] > 31) {
                alert("invalid day");
                return false;
            }
            if(regs[2] < 1 || regs[2] > 12) {
                alert("Invalid value for month: " + regs[2]);
                return false;
             }
            // year value between 1902 and 2016
            if(regs[3] < 1902 || regs[3] > (new Date()).getFullYear()) {
                alert("Invalid value for year: " + regs[3] + " - must be between 1902 and " + (new Date()).getFullYear());
                return false;
            }
            else if (!dateee.match(ex)){
            alert("date ssss");
            return false;
            }
        }
     }else {
        alert("date help");
                return false;
     };

 }

 var makeActive = function (){
    for (var i = 0; i < elems.length; i++) {
        elems[i].classList.remove('active');
            }
    this.classList.add('active');
 };

 var getList = function (){
    for (var i = 0; i < listElems.length; i++) {
        listElems[i].classList.remove('listActive');
    }
    var rel = this.getAttribute('rel');
    var ulNode = document.getElementById(rel);
        ulNode.classList.add('listActive'); 
 };


 var addToDataB = function(list, date){

    var settings = {
        "todo":list,
        "date":date
    };

    json[num] = settings;

 }


 function selectId(date){

    if(today.getTime() === date){
        id = 'today';
        return
    } else if (yesterday.getTime() === date){
        id ='yesterday';
        return
    } else if (tomorrow.getTime() === date){
        id = 'tomorrow';
        return
    } else{
        id ='';
        clear();
        return
    }
 }

  function makeList(id, itemTask, num) {

   var itemText = document.createTextNode(itemTask);

    var itemLabel = document.createElement('label')
    itemLabel.setAttribute("for", "cbox");

    var itemInput = document.createElement('input');
    itemInput.type = "checkbox";
    itemInput.id = "cbox";

    var liText = document.createElement('li');
    liText.className = num;
    liText.appendChild(itemInput);
    liText.appendChild(itemLabel);
    liText.appendChild(itemText);   

    var ulText = document.getElementById(id);
    ulText.appendChild(liText);

 }

function removeList() {
    var ul = document.querySelectorAll('.list');
        // ul selected
    var li;

    var classId;

    for (var k = 0; k < ul.length; k++){
        // all li selected in ul
          li = ul[k].children;

        for(var j = 0; j < li.length; j++){
            while(li[j] && li[j].children[0].checked){
                classId = li[j].className;
                ul[k].removeChild(li[j]);
                delete json[classId];
                localStorage.setItem('json' , JSON.stringify(json));

            }   
        }
    }
} 

function clear() {
    itemBox.value = '';
    dateBox.value = '';

}

for (var i = 0; i < elems.length; i++){
    elems[i].addEventListener('click', function(){
        makeActive.call(this);
        getList.call(this);
    });
}
})();
body{
    margin: 0;
    padding: 0;
    background-color: darkgrey; 
    font-family: Ariel, Charcoal, sans-serif;
}

#container{
    width: 500px;
    height: 525px;
    background-color: #f8f7f5;
    margin: 50px auto;
}

header{
background: rgba(18,136,255,1);
background: -moz-linear-gradient(top, rgba(18,136,255,1) 0%, rgba(8,182,245,1) 100%);
background: -webkit-gradient(left top, left bottom, color-stop(0%, rgba(18,136,255,1)), color-stop(100%, rgba(8,182,245,1)));
background: -webkit-linear-gradient(top, rgba(18,136,255,1) 0%, rgba(8,182,245,1) 100%);
background: -o-linear-gradient(top, rgba(18,136,255,1) 0%, rgba(8,182,245,1) 100%);
background: -ms-linear-gradient(top, rgba(18,136,255,1) 0%, rgba(8,182,245,1) 100%);
background: linear-gradient(to bottom, rgba(18,136,255,1) 0%, rgba(8,182,245,1) 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#b7deed', endColorstr='#08b6f5', GradientType=0 );
margin: 0;
height: 60px;
line-height: 60px;
color: white;
text-align: center;
}

nav{
    background-color: white;
}

nav ul{
    list-style: none;
    margin: 0;
    padding: 0;
    background-color: white;
    overflow: hidden;
}

nav li{
    float: left;
    width: 33.1%;
    border-right: 1px solid ;
}

nav li:last-child{
border: none;
}

nav li a {
    display: block;
    text-align: center;
    padding: 14px 16px;
    text-decoration: none;
    color: black;

}

.active{
    background-color: #f8f7f5;
}

h1{
    margin: 0;
}

.list{
    height: 250px;
    overflow: hidden;
    list-style: none;
    display: none;
}



.input{
    padding-left: 30px;

}

.listActive {
    display: block;
}



input[type=checkbox] {

}
/*

input[type=checkbox] + label:before {
    content: "";  
    display: inline-block;  
    width: 15px;  
    height: 15px;  
    vertical-align:middle;
    margin-right: 8px;  
    background-color: #aaa;  
    box-shadow: inset 0px 2px 2px rgba(0, 0, 0, .3);
    border-radius: 4px;  
}
input[type=checkbox]:checked + label:before {
    content:"\2713"; /* Tick 
    color:white;
    background-color: #666; 
    text-align:center;
    line-height:15px;
    text-shadow:0px 0px 3px #eee;
}

*/

.menu{
    border-top: 2px solid grey;
    width: 500px;
}


.menu label, .menu input{
    display: block;
    width: 150px;
    float: left;
    margin: 10px 0px;

}

.menu label{
    text-align: right;
    padding-right: 20px;
    font-size: 20px;
}

br{
    clear: left;
}

.list  {
    padding: 0px;
}

.list li {
    font-size: 1.25em;
    margin-top: 10px;
    padding: 0 0 10px 0;
    border-bottom: 1px solid black;
}

#cbox {
    margin-left: 30px;
    margin-right: 40px;
}
<!DOCTYPE html>
<html>
    <head>
        <title>To Do List</title>
        <link rel="stylesheet" type="text/css" href="style.css">
        <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
    </head>
<body>
    <div id="container">
        <header><h1>TO DO LIST</h1></header>
        <nav>
            <ul>
                <li class="navButton" rel="yesterday"><a href="#">Yesterday</a></li>
                <li class= "navButton active" rel="today"><a href="#">Today</a></li>
                <li class="navButton" rel="tomorrow"><a href="#">Tomorrow</a></li>
            </ul>
        </nav>
        <div class = "yesterday">
            <ul class="list" id="yesterday">
                <li><input type = "checkbox" id="cbox"><label for="cbox"></label>first</li>
            </ul>
        </div>
        <div class = "today">
            <ul class="list listActive " id="today">
                <li><input type= "checkbox" id="cbox"><label for="cbox"></label>second</li>
            </ul>
        </div>
        <div class = "tomorrow">
            <ul class="list" id="tomorrow">
                <li><input type= "checkbox" id="cbox"><label for="cbox"></label>third</li>
            </ul>
        </div>
        <div class = "menu">
            <label> Add Task:</label><input type="text" id="item"><br>
            <label> Date complete:</label><input type="date" id="date"><br>
            <input type="button" value="Add" id="addButton" >
            <input type="button" value="remove" id="removeButton" >
        </div>

    </div>

    <script type="text/javascript" src="todo.js"></script>
</body>
</html>

\$\endgroup\$
  • \$\begingroup\$ Hey, nice first post. It would also be helpful if you post a jsfiddle so we can see it in action \$\endgroup\$ – Jonah Jan 24 '16 at 23:43
  • \$\begingroup\$ I've made it a Stack Snippet (hit Ctrl-M in the question editor), arbitrarily picking jQuery version 1.11.3. \$\endgroup\$ – 200_success Jan 24 '16 at 23:55
  • \$\begingroup\$ @Jonah thanks please see the link, jsfiddle.net/Fa8Xx/3858 \$\endgroup\$ – monkeyman905 Jan 25 '16 at 21:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.