Commit 037052bc authored by Sindre Sorhus's avatar Sindre Sorhus

Remove Angular+Persistencejs as discussed in #201

Will be linked to in the wiki
parent a35531a1
<!doctype html>
<html lang="en" ng-app="todomvc">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>AngularJS - TodoMVC</title>
<link rel="stylesheet" href="../../assets/base.css">
<!--[if IE]>
<script src="../../assets/ie.js"></script>
<![endif]-->
</head>
<body>
<section id="todoapp" ng-controller="TodoController">
<header id="header">
<h1>todos</h1>
<form id="todo-form" ng-submit="addTodo()">
<input id="new-todo" placeholder="What needs to be done?" type="text" name="newTodo" ng-model="newTodo">
</form>
</header>
<section id="main" ng-show="todos.length">
<input id="toggle-all" type="checkbox" ng-model="allChecked" ng-change="markAllDone()" ng-checked="remainingTodos().length == 0">
<label for="toggle-all">Mark all as complete</label>
<ul id="todo-list">
<li ng-repeat="todo in todos | filter:statusFilter" ng-dblclick="editTodo(todo)" ng-class="{done: todo.completed, editing: todo.editing}">
<div class="view">
<input class="toggle" type="checkbox" name="todo.completed" ng-model="todo.completed" ng-change="toggleDone(todo)">
<label ng-bind="todo.title">Loading...</label>
<button class="destroy" ng-click="removeTodo(todo)"></button>
</div>
<form ng-submit="finishEditing(todo)">
<input class="edit" type="text" name="todo.title" ng-model="todo.title" todo-blur="finishEditing(todo)" todo-focus="todo.editing">
</form>
</li>
</ul>
</section>
<footer id="footer" ng-show="todos.length">
<span id="todo-count"><strong>{{remainingTodos().length}}</strong> <ng-pluralize count="remainingTodos().length" when="todoForms"></ng-pluralize></span>
<ul id="filters">
<li>
<a ng-class="{selected: location.path() == '/'} " href="#/">All</a>
</li>
<li>
<a ng-class="{selected: location.path() == '/active'}" href="#/active">Active</a>
</li>
<li>
<a ng-class="{selected: location.path() == '/completed'}" href="#/completed">Completed</a>
</li>
</ul>
<button id="clear-completed" ng-click="clearDoneTodos()" ng-show="doneTodos().length" ng-bind-template="Clear completed ({{doneTodos().length}})"></button>
</footer>
</section>
<footer id="info">
<p>Double-click to edit a todo.</p>
<p>Created by <a href="http://twitter.com/cburgdorf">Christoph Burgdorf</a>.</p>
<p>Extended to use PersistenceJS for local storage by <a href="http://jacobmumm.com">Jacob Mumm</a>.</p>
</footer>
<script src="../../assets/base.js"></script>
<script src="js/libs/angular/angular.min.js"></script>
<script src="js/libs/persistencejs/persistence.js"></script>
<script src="js/libs/persistencejs/persistence.store.sql.js"></script>
<script src="js/libs/persistencejs/persistence.store.websql.js"></script>
<script src="js/controllers/todo.js"></script>
<script src="js/modules/persistence-service.js"></script>
<script src="js/directives/todo-directives.js"></script>
</body>
</html>
/* App Controllers */
var todomvc = angular.module('todomvc', []);
function TodoController($scope, $location, persistencejs) {
$scope.todos = []; loadTodos();
$scope.newTodo = "";
$scope.editTodoStartContent = "";
if($location.path()=='') $location.path('/');
$scope.location = $location;
$scope.$watch(function() {return $location.path(); }, function(path) {
$scope.statusFilter = path == '/active' ?
{ completed: false } : path == '/completed' ?
{ completed: true } : null;
});
function loadTodos() {
persistencejs.fetchAll($scope);
};
$scope.refresh = function(){ $scope.$apply(); }
$scope.todoForms = {
one: 'item left',
other: 'items left'
};
$scope.addTodo = function() {
if (this.newTodo.trim().length === 0) {
return;
}
$scope.todos.push({
title: this.newTodo,
completed: false,
editing: false
});
persistencejs.add(this.newTodo);
this.newTodo = '';
};
$scope.editTodo = function(todo) {
$scope.todos.forEach(function(val) {
val.editing = false;
});
todo.editing = true;
$scope.editTodoStartContent = todo.title;
};
$scope.finishEditing = function(todo) {
if (todo.title.trim().length === 0) {
$scope.removeTodo(todo);
persistencejs.remove(todo);
} else {
todo.editing = false;
persistencejs.edit($scope.editTodoStartContent, todo.title);
}
};
$scope.removeTodo = function(todo) {
for (var i = 0, len = $scope.todos.length; i < len; ++i) {
if (todo === $scope.todos[i]) {
$scope.todos.splice(i, 1);
}
}
persistencejs.remove(todo);
};
$scope.remainingTodos = function() {
return $scope.todos.filter(function(val) {
return !val.completed;
});
};
$scope.completedTodos = function() {
return $scope.todos.filter(function(val) {
return val.completed;
});
}
$scope.clearDoneTodos = function() {
$scope.todos = $scope.remainingTodos();
persistencejs.clearCompletedItems();
};
$scope.toggleDone = function(todo){
persistencejs.changeStatus(todo);
}
$scope.markAllDone = function() {
var markDone = true;
if (!$scope.remainingTodos().length) {
markDone = false;
}
$scope.todos.forEach(function(todo) {
if(todo.completed !== markDone){
persistencejs.changeStatus(todo);
}
todo.completed = markDone;
});
};
};
todomvc.directive('todoBlur', function() {
return function( scope, elem, attrs ) {
elem.bind('blur', function() {
scope.$apply( attrs.todoBlur );
});
};
});
todomvc.directive('todoFocus', function( $timeout ) {
return function( scope, elem, attrs ) {
scope.$watch( attrs.todoFocus, function( newval ) {
if ( newval ) {
$timeout(function() {
elem[0].focus();
elem[0].select();
}, 0 );
}
});
};
});
try {
if(!window) {
window = {};
//exports.console = console;
}
} catch(e) {
window = {};
exports.console = console;
}
var persistence = (window && window.persistence) ? window.persistence : {};
if(!persistence.store) {
persistence.store = {};
}
persistence.store.websql = {};
persistence.store.websql.config = function(persistence, dbname, description, size) {
var conn = null;
/**
* Create a transaction
*
* @param callback,
* the callback function to be invoked when the transaction
* starts, taking the transaction object as argument
*/
persistence.transaction = function (callback) {
if(!conn) {
throw new Error("No ongoing database connection, please connect first.");
} else {
conn.transaction(callback);
}
};
////////// Low-level database interface, abstracting from HTML5 and Gears databases \\\\
persistence.db = persistence.db || {};
persistence.db.implementation = "unsupported";
persistence.db.conn = null;
// window object does not exist on Qt Declarative UI (http://doc.trolltech.org/4.7-snapshot/declarativeui.html)
if (window && window.openDatabase) {
persistence.db.implementation = "html5";
} else if (window && window.google && google.gears) {
persistence.db.implementation = "gears";
} else {
try {
if (openDatabaseSync) {
// TODO: find a browser that implements openDatabaseSync and check out if
// it is attached to the window or some other object
persistence.db.implementation = "html5-sync";
}
} catch(e) {
}
}
persistence.db.html5 = {};
persistence.db.html5.connect = function (dbname, description, size) {
var that = {};
var conn = openDatabase(dbname, '1.0', description, size);
that.transaction = function (fn) {
return conn.transaction(function (sqlt) {
return fn(persistence.db.html5.transaction(sqlt));
});
};
return that;
};
persistence.db.html5.transaction = function (t) {
var that = {};
that.executeSql = function (query, args, successFn, errorFn) {
if(persistence.debug) {
console.log(query, args);
}
t.executeSql(query, args, function (_, result) {
if (successFn) {
var results = [];
for ( var i = 0; i < result.rows.length; i++) {
results.push(result.rows.item(i));
}
successFn(results);
}
}, errorFn);
};
return that;
};
persistence.db.html5Sync = {};
persistence.db.html5Sync.connect = function (dbname, description, size) {
var that = {};
var conn = openDatabaseSync(dbname, '1.0', description, size);
that.transaction = function (fn) {
return conn.transaction(function (sqlt) {
return fn(persistence.db.html5Sync.transaction(sqlt));
});
};
return that;
};
persistence.db.html5Sync.transaction = function (t) {
var that = {};
that.executeSql = function (query, args, successFn, errorFn) {
if (args == null) args = [];
if(persistence.debug) {
console.log(query, args);
}
var result = t.executeSql(query, args);
if (result) {
if (successFn) {
var results = [];
for ( var i = 0; i < result.rows.length; i++) {
results.push(result.rows.item(i));
}
successFn(results);
}
}
};
return that;
};
persistence.db.gears = {};
persistence.db.gears.connect = function (dbname) {
var that = {};
var conn = google.gears.factory.create('beta.database');
conn.open(dbname);
that.transaction = function (fn) {
fn(persistence.db.gears.transaction(conn));
};
return that;
};
persistence.db.gears.transaction = function (conn) {
var that = {};
that.executeSql = function (query, args, successFn, errorFn) {
if(persistence.debug) {
console.log(query, args);
}
var rs = conn.execute(query, args);
if (successFn) {
var results = [];
while (rs.isValidRow()) {
var result = {};
for ( var i = 0; i < rs.fieldCount(); i++) {
result[rs.fieldName(i)] = rs.field(i);
}
results.push(result);
rs.next();
}
successFn(results);
}
};
return that;
};
persistence.db.connect = function (dbname, description, size) {
if (persistence.db.implementation == "html5") {
return persistence.db.html5.connect(dbname, description, size);
} else if (persistence.db.implementation == "html5-sync") {
return persistence.db.html5Sync.connect(dbname, description, size);
} else if (persistence.db.implementation == "gears") {
return persistence.db.gears.connect(dbname);
}
};
///////////////////////// SQLite dialect
persistence.store.websql.sqliteDialect = {
// columns is an array of arrays, e.g.
// [["id", "VARCHAR(32)", "PRIMARY KEY"], ["name", "TEXT"]]
createTable: function(tableName, columns) {
var tm = persistence.typeMapper;
var sql = "CREATE TABLE IF NOT EXISTS `" + tableName + "` (";
var defs = [];
for(var i = 0; i < columns.length; i++) {
var column = columns[i];
defs.push("`" + column[0] + "` " + tm.columnType(column[1]) + (column[2] ? " " + column[2] : ""));
}
sql += defs.join(", ");
sql += ')';
return sql;
},
// columns is array of column names, e.g.
// ["id"]
createIndex: function(tableName, columns, options) {
options = options || {};
return "CREATE "+(options.unique?"UNIQUE ":"")+"INDEX IF NOT EXISTS `" + tableName + "__" + columns.join("_") +
"` ON `" + tableName + "` (" +
columns.map(function(col) { return "`" + col + "`"; }).join(", ") + ")";
}
};
// Configure persistence for generic sql persistence, using sqliteDialect
persistence.store.sql.config(persistence, persistence.store.websql.sqliteDialect);
// Make the connection
conn = persistence.db.connect(dbname, description, size);
if(!conn) {
throw new Error("No supported database found in this browser.");
}
};
try {
exports.persistence = persistence;
} catch(e) {}
todomvc.factory('persistencejs', function(){
persistence.store.websql.config(persistence, 'todos-angularjs', 'todo database', 5*1024*1024);
var Todo = persistence.define('todo', {
title: 'TEXT',
completed: 'BOOL'
});
persistence.schemaSync();
return {
add: function(item){
var t = new Todo();
t.title = item;
t.completed = false;
persistence.add(t);
persistence.flush();
},
edit: function(oldTitle, newTitle){
Todo.all().filter('title','=',oldTitle).one(function(item){
if(item){
item.title = newTitle;
persistence.flush();
}
});
},
changeStatus: function(item){
Todo.all().filter('title','=',item.title).one(function(todo){
todo.completed = item.completed;
persistence.flush();
});
},
clearCompletedItems: function(){
Todo.all().filter('completed','=',true).destroyAll();
},
remove: function(item){
Todo.all().filter('title','=',item.title).destroyAll();
},
fetchAll: function(controller){
Todo.all().list(function(items){
var itemCount = items.length;
var todos = [];
items.forEach(function(item){
todos.push({
title: item.title,
completed: item.completed,
editing: false
});
if(--itemCount == 0){
controller.todos = todos;
controller.refresh();
}
});
});
},
};
});
......@@ -65,11 +65,11 @@
<li>
<a href="architecture-examples/dojo/index.html" data-source="http://dojotoolkit.org/" data-content="Dojo saves you time and scales with your development process, using web standards as its platform. It’s the toolkit experienced developers turn to for building high quality desktop and mobile web applications.">Dojo</a>
</li>
</ul>
<ul class="nav nav-pills">
<li>
<a href="architecture-examples/closure/index.html" data-source="http://code.google.com/closure/library/" data-content="The Closure Library is a broad, well-tested, modular, and cross-browser JavaScript library. You can pull just what you need from a large set of reusable UI widgets and controls, and from lower-level utilities for DOM manipulation, server communication, animation, data structures, unit testing, rich-text editing, and more.">Closure</a>
</li>
</ul>
<ul class="nav nav-pills">
<li>
<a href="architecture-examples/yuilibrary/index.html" data-source="http://yuilibrary.com/" data-content="YUI's lightweight core and modular architecture make it scalable, fast, and robust. Built by frontend engineers at Yahoo!, YUI powers the most popular websites in the world.">YUILibrary</a>
</li>
......@@ -80,9 +80,6 @@
<a href="architecture-examples/angularjs/index.html" data-source="http://angularjs.org/" data-content="What HTML would have been
had it been designed for web apps">AngularJS</a>
</li>
<li>
<a href="architecture-examples/angularjs_persistencejs/index.html" data-source="http://persistencejs.org/" data-content="persistence.js is an asynchronous Javascript object-database mapper. It has database-independent abstractions and can therefore easily be ported to new databases.">Angular + PersistenceJS</a>
</li>
<li>
<a href="architecture-examples/extjs/index.html" data-source="http://www.sencha.com/products/extjs" data-content="Ext JS 4 is the next major advancement in our JavaScript framework. Featuring expanded functionality, plugin-free charting, and a new MVC architecture it's the best Ext JS yet. Create incredible web apps for every browser.">Ext.js</a>
</li>
......
......@@ -22,7 +22,6 @@ To help solve this problem, TodoMVC was created - a project which offers the sam
- [Closure](http://code.google.com/closure/library/)
- [YUI](http://yuilibrary.com)
- [AngularJS](http://angularjs.org)
- [AngularJS](http://angularjs.org) + [PersistenceJS](http://persistencejs.org)
- [Ext.js](http://www.sencha.com/products/extjs)
- [Agility.js](http://agilityjs.com)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment