<!DOCTYPE html>
<html ng-app="myApp">

<head>
  <script data-require="jquery@*" data-semver="2.0.3" src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
  <script data-require="bootstrap@3.1.1" data-semver="3.1.1" src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
  <script data-require="angular.js@1.2.13" data-semver="1.2.13" src="http://code.angularjs.org/1.2.13/angular.js"></script>
  <script data-require="angular.js@1.2.13" data-semver="1.2.13" src="http://code.angularjs.org/1.2.13/angular-animate.js"></script>
  <link data-require="bootstrap-css@3.1.1" data-semver="3.1.1" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" />
  <link rel="stylesheet" href="style.css" />
  <script src="script.js"></script>
</head>

<body>
  <div class="container">
    <div class="row">
      <div class="col-md-12">
        <h3 class="jumbotron">ToDo using IndexedDB</h3>

<div data-ng-app="indexDBSample" data-ng-controller="TodoController as vm">
    <div class="form-group">
        <input type="text" data-ng-model="vm.todoText" name="todo" placeholder="What's pending?" class="form-control" />
    </div>
    <div class="form-group">
        <button class="btn btn-primary btn-lg" data-ng-click="vm.addTodo()">Add</button>
        <button class="btn btn-secondary btn-lg" data-ng-click="vm.refreshList()">Refresh</button>
    </div>
    <table class="table table-striped">
        <tr data-ng-repeat="todo in vm.todos">
            <td>{{todo.text}}</td>
            <td><a href="#" data-ng-click="vm.deleteTodo(todo.id)"><span class="glyphicon glyphicon-trash"></span></a>

            </td>
        </tr>
    </table>
    <div class="footer text-muted">Jayesh</div>
</div>
      </div>
    </div>
  </div>

</body>

</html>
// Code goes here
var app = angular.module('myApp', []);

app.factory('indexedDBDataSvc', function ($window, $q) {
    var indexedDB = $window.indexedDB;
    var db = null;
    var lastIndex = 0;

    var open = function () {
        var deferred = $q.defer();
        var version = 1;
        var request = indexedDB.open("todoData", version);

        request.onupgradeneeded = function (e) {
            db = e.target.result;

            e.target.transaction.onerror = indexedDB.onerror;

            if (db.objectStoreNames.contains("todo")) {
                db.deleteObjectStore("todo");
            }

            var store = db.createObjectStore("todo", {
                keyPath: "id"
            });
        };

        request.onsuccess = function (e) {
            db = e.target.result;
            deferred.resolve();
        };

        request.onerror = function () {
            deferred.reject();
        };

        return deferred.promise;
    };

    var getTodos = function () {
        var deferred = $q.defer();

        if (db === null) {
            deferred.reject("IndexDB is not opened yet!");
        } else {
            var trans = db.transaction(["todo"], "readwrite");
            var store = trans.objectStore("todo");
            var todos = [];

            // Get everything in the store;
            var keyRange = IDBKeyRange.lowerBound(0);
            var cursorRequest = store.openCursor(keyRange);

            cursorRequest.onsuccess = function (e) {
                var result = e.target.result;
                if (result === null || result === undefined) {
                    deferred.resolve(todos);
                } else {
                    todos.push(result.value);
                    if (result.value.id > lastIndex) {
                        lastIndex = result.value.id;
                    }
                    result.
                    continue ();
                }
            };

            cursorRequest.onerror = function (e) {
                console.log(e.value);
                deferred.reject("Something went wrong!!!");
            };
        }

        return deferred.promise;
    };

    var deleteTodo = function (id) {
        var deferred = $q.defer();

        if (db === null) {
            deferred.reject("IndexDB is not opened yet!");
        } else {
            var trans = db.transaction(["todo"], "readwrite");
            var store = trans.objectStore("todo");

            var request = store.delete(id);

            request.onsuccess = function (e) {
                deferred.resolve();
            };

            request.onerror = function (e) {
                console.log(e.value);
                deferred.reject("Todo item couldn't be deleted");
            };
        }

        return deferred.promise;
    };

    var addTodo = function (todoText) {
        var deferred = $q.defer();

        if (db === null) {
            deferred.reject("IndexDB is not opened yet!");
        } else {
            var trans = db.transaction(["todo"], "readwrite");
            var store = trans.objectStore("todo");
            lastIndex++;
            var request = store.put({
                "id": lastIndex,
                    "text": todoText
            });

            request.onsuccess = function (e) {
                deferred.resolve();
            };

            request.onerror = function (e) {
                console.log(e.value);
                deferred.reject("Todo item couldn't be added!");
            };
        }
        return deferred.promise;
    };

    return {
        open: open,
        getTodos: getTodos,
        addTodo: addTodo,
        deleteTodo: deleteTodo
    };

});

app.controller('TodoController', function ($window, indexedDBDataSvc) {
    var vm = this;
    vm.todos = [];

    vm.refreshList = function () {
        indexedDBDataSvc.getTodos().then(function (data) {
            vm.todos = data;
        }, function (err) {
            $window.alert(err);
        });
    };

    vm.addTodo = function () {
        indexedDBDataSvc.addTodo(vm.todoText).then(function () {
            vm.refreshList();
            vm.todoText = "";
            vm.todoText.focus();
        }, function (err) {
            $window.alert(err);
        });
    };

    vm.deleteTodo = function (id) {
        indexedDBDataSvc.deleteTodo(id).then(function () {
            vm.refreshList();
        }, function (err) {
            $window.alert(err);
        });
    };

    function init() {
        indexedDBDataSvc.open().then(function () {
            vm.refreshList();
        });
    }

    init();
});
/* Styles go here */
body {
    margin: 10px;
    padding: 10px;
    font-family:'Palatino';
    font-size: 16px;
}

.footer {
    position:absolute;
    bottom:-20px;
    right:20px;
    font-size:12px;
}
#AngularJS and IndexedDB Demo

**Author**: Jayesh Chandrapal

Copyright © 2014-2015 [www.jayeshcp.com](www.jayeshcp.com) All rights Reserved.

Email: <me@jayeshcp.com>