AngularJS: Editable and Sortable To Do List

by Mahfuzul Haque

HTML

<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.20/angular.min.js"></script>
<script src="http://cdn.kendostatic.com/2013.1.319/js/kendo.all.min.js"></script>
<script src="http://kendo-labs.github.io/angular-kendo/angular-kendo.js"></script>
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.1.318/styles/kendo.common.min.css">
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.1.318/styles/kendo.silver.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap-theme.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-sortable/0.13.3/sortable.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.3/jquery-ui.min.js"></script>
<div ng-app="ToDoApp" class="container list-container" >
    <div ng-controller="ToDoController">
       
        <input type="text" placeholder="Add new item" class="form-control" 
            ng-model="newItem" ng-keypress="newItemKeyPress($event)" ng-disabled="items.length >= 100" />
   
        <h4><span>To Do </span><span ng-show="!isEmptyList()">({{getProgress()}}%)</span></h4>
        <div ng-show="isEmptyList()">
           No items in the list 
        </div>        
        
        
        <div ui-sortable ng-model="items" ng-show="!isEmptyList()">
            <div ng-repeat="item in items track by $index" class="list-item" ng-class="{'list-item-done': item.isDone}">
                <span><input type="checkbox" ng-model="item.isDone" />&nbsp;</span>
                <span ng-show="!item.editMode" ng-class="{'list-item-done': item.isDone}" >{{item.text}}&nbsp;</span> 
                <span ng-show="item.editMode"><input type="text" ng-model="item.text"...

CSS

.list-container
{
    padding:20px       
}

.list-item
{
    background-color: rgb(239,239,239);     
    padding: 5px;
    margin: 5px;  
    
    border-radius: 5px; 
    -moz-border-radius: 5px; 
    -webkit-border-radius: 5px;    
    border: 1px solid lightgray;  
    /*cursor: move;*/
    
}

.list-item-done 
{
    background-color: rgb(204, 255, 153);
    text-decoration: line-through;
}

JavaScript

var app = angular.module('ToDoApp', ['kendo.directives','ui.sortable']);
    
    function ToDoController($scope) {
        
        $scope.items = [
            {text: "Shopping", isDone: false, editMode: false},
            {text: "Book flight", isDone: false, editMode: false},
            {text: "Call Dad", isDone: false, editMode: false},
            {text: "Catchup with Mash", isDone: false, editMode: false},
            {text: "Create an angular app", isDone: true, editMode: false},
        ];     
            
        $scope.newItem = "";
            
        $scope.newItemKeyPress = function(keyEvent) {
            if (keyEvent.which === 13) {
                $scope.addItem();        
            }
        }

        $scope.addItem = function () {
            if($scope.newItem != "") {
                $scope.items.push({text: $scope.newItem, isDone: false}); 
            } 
        
            $scope.newItem = "";
        };

        $scope.editItem = function (index) {
            $scope.items[index].editMode = !$scope.items[index].editMode;
        };            
            
        $scope.editItemKeyPress = function(keyEvent,index) {
            if (keyEvent.which === 13) {
              $scope.items[index].editMode = false;      
            }
        }
    
        $scope.removeItem = function (index) {
            $scope.items.splice(index, 1);
        };
    
    
        $scope.isEmptyList = function() {
            return $scope.items.length == 0;
        };
    
        $scope.getProgress = function() {
            var completedCount = 0; 
            var listSize = $scope.items.length;  
            
            for(i = 0; i < listSize; i++) {
                if($scope.items[i].isDone) {
                    completedCount++;
                }
            } 
        
            return Math.round((completedCount*100)/listSize);
        };
    }