Commit add71117 authored by Alex Kit's avatar Alex Kit

Atma.js: update and refactor (closes GH-816)

parent 935aed05
{
"name": "todomvc-atmajs",
"version": "0.1.0",
"dependencies": {
"todomvc-common": "~0.1.4",
"jquery": "~2.0.2"
}
"name": "todomvc-atmajs",
"version": "0.1.0",
"dependencies": {
"todomvc-common": "~0.1.4",
"jquery": "~2.0.2",
"maskjs": "~0.10.1",
"includejs": "~0.9.10",
"ruta": "~0.1.11",
"atma-class": "~1.0.68"
}
}
......@@ -6,88 +6,47 @@
<link rel="stylesheet" href="bower_components/todomvc-common/base.css">
</head>
<body>
<script type="mask/template" id="layout">
/*
TodoMVC Atma.js Application
1. Read readme.md - you will get basic information about the libraries
2. Hint: Viewing *.mask files enable javascript or less syntax highlighting in your IDE
The application structure guide:
Controls Overview:
todo:input;
Components Overview:
:app\
:filter;
:todoList\
:todoTask;
Scripts overview (sorted from the most atomic parts up to the application component):
js/
model/Todos.js
cntrl/input.js
filter/filter.js
todoList/
todoTask/todoTask.js
todoList.js
app.js
_If the controller loads a template, do not forget to review that._
*/
// Application Template
section #todoapp {
header #header {
h1 > 'todos'
todo:input #new-todo
autofocus
x-signal = 'enter: newTask'
placeholder = 'What needs to be done?'
;
}
section #main >
:todoList;
footer #footer xx-visible = 'status.count' {
span #todo-count {
strong > '~[bind: status.todoCount]'
span > ' item~[bind: status.todoCount != 1 ? "s"] left'
}
:filter;
button #clear-completed
xx-visible = 'status.completedCount > 0'
x-signal = 'click: removeAllCompleted' {
'Clear completed (~[bind:status.completedCount])'
}
}
}
footer #info {
p { 'Double-click to edit a todo' }
p { 'Created by ' a href='http://github.com/tenbits' > 'tenbits' }
p { 'Part of ' a href='http://todomvc.com' > 'TodoMVC' }
}
</script>
<!--
TodoMVC Atma.js Application
1. Read readme.md - you will get basic information about the libraries
2. Hint: Viewing *.mask files enable javascript or less syntax highlighting in your IDE
The application structure guide:
- Controls
todo:input;
- Components
:app\
:filter;
:todoList\
:todoTask;
Scripts overview (sorted from the most atomic parts up to the application component):
js/
model/Todos.js
cntrl/input.js
filter/filter.js
todoList/
todoTask/todoTask.js
todoList.js
app.js
_If the controller loads a template, do not forget to review that._
-->
<script src="bower_components/todomvc-common/base.js"></script>
<script src="bower_components/jquery/jquery.js"></script>
<script src="lib/atma-globals-dev.js"></script>
<script src="bower_components/includejs/lib/include.js"></script>
<script src="bower_components/atma-class/lib/class.js"></script>
<script src="bower_components/maskjs/lib/mask.js"></script>
<script src="bower_components/ruta/lib/ruta.js"></script>
<script src="js/app.js"></script>
</body>
......
/*jshint newcap:false */
/*global include, Compo */
/*global include, mask, Compo, ruta */
'use strict';
......@@ -31,32 +31,41 @@ include
compo: ['todoList', 'filter']
})
.ready(function (resp) {
.load('./app.mask::Template')
/* Initialize and load the model from the Store */
var todos = resp.Todos.fetch();
.ready(function (resp) {
var Application = Compo({
template: '#layout',
mask.registerHandler(':app', Compo({
template: resp.load.Template,
model: resp.Todos.fetch(),
scope: {
action: ''
},
slots: {
newTask: function (event, title) {
if (title) {
this.model.create(title);
}
},
removeAllCompleted: function () {
this
.model
.del(function (x) {
return x.completed === true;
});
this.model.del(function (x) {
return x.completed === true;
});
}
},
onRenderStart: function () {
// (RutaJS) Default router is the History API,
// but for this app spec enable hashes
ruta
.setRouterType('hash')
.add('/?:action', this.applyFilter.bind(this))
.notifyCurrent()
;
},
applyFilter: function (route, params) {
this.scope.action = params.action || '';
}
});
}));
Compo.initialize(Application, todos, document.body);
});
Compo.initialize(':app', document.body);
});
\ No newline at end of file
section #todoapp {
header #header {
h1 > 'todos'
todo:input #new-todo
autofocus
placeholder = 'What needs to be done?'
x-signal = 'enter: newTask'
;
}
+if (status.count) {
section #main >
:todoList;
footer #footer {
span #todo-count {
strong > '~[bind: status.todoCount]'
span > ' item~[bind: status.todoCount != 1 ? "s"] left'
}
:filter;
+if (status.completedCount > 0) {
button #clear-completed x-signal = 'click: removeAllCompleted' >
'Clear completed (~[bind:status.completedCount])'
}
}
}
}
footer #info {
p { 'Double-click to edit a todo' }
p { 'Created by ' a href='http://github.com/tenbits' > 'tenbits' }
p { 'Part of ' a href='http://todomvc.com' > 'TodoMVC' }
}
\ No newline at end of file
......@@ -48,24 +48,22 @@
},
'blur': 'save'
},
focus: function focus() {
focus: function () {
this.$.focus();
},
cancel: function cancel() {
cancel: function () {
this.$.trigger('cancel');
this.afterEdit();
},
save: function save() {
save: function () {
var value = this.$.val().trim();
this.$.trigger('enter', value);
this.afterEdit();
},
afterEdit: function () {
this.$.val(this.attr.preserve ? this.model.title : '');
}
......
......@@ -12,61 +12,7 @@ include
.done(function (resp) {
'use strict';
// `Compo` function creates components constructor,
// but it doesnt have ClassJS features, like inhertince and
// others. With `Compo.createClass`(_if ClassJS is used_) we
// can use those features in components constructor
mask.registerHandler(':filter', Compo.createClass({
template: resp.load.Template,
onRenderStart: function () {
ruta
// (RutaJS) Default router is the History API,
// but for this APP use hashes
.setRouterType('hash')
// Note: we do not bind to `this` compo instance,
// as applyFilter is already bound to it.
.add('/?:action', this.applyFilter)
;
// Define filters model
this.model = [{
title: 'All',
action: ''
}, {
title: 'Active',
action: 'active'
}, {
title: 'Completed',
action: 'completed'
}];
this.applyFilter(ruta.current());
},
Self: {
applyFilter: function (route) {
this.action = _setSelectedFilter(route.current, this.model);
// Emit a signal 'action' in a 'filter' pipe
Compo.pipe('filter').emit('action', this.action);
}
}
template: resp.load.Template
}));
function _setSelectedFilter(route, filters) {
var action = route.params.action || '';
// Update View via Binding
filters.forEach(function (filter) {
filter.selected = action === filter.action ? 'selected' : '';
});
return action;
}
});
var filters = {
'' : 'All',
'active': 'Active',
'completed': 'Completed'
};
ul #filters >
// take each filter item from the array model
% each = '.' >
for ((key, val) in filters) {
// compare with the scoped value `action`
li >
a.~[bind:selected] href = '#~[action]' >
'~[title]'
\ No newline at end of file
a .~[bind: action == key ? 'selected' ] href = '#~[key]' >
'~[val]'
}
\ No newline at end of file
input#toggle-all
type = 'checkbox'
input #toggle-all
type = checkbox
checked = '~[bind: status.todoCount == 0 ? "checked" ]'
x-signal = 'click: toggleAll'
// bind and hide/show accordingly
xx-visible = 'status.count'
;
label for = 'toggle-all' >
'Mark all as complete'
ul#todo-list {
// binded todos array
%% each = '.' >
:todoTask;
label for='toggle-all' > 'Mark all as complete'
ul #todo-list {
// bind todos collection
+each (.) > :todoTask;
}
\ No newline at end of file
......@@ -109,7 +109,7 @@ navigate to ``` http://localhost:5777/ ```
### Build
To build the application for release, run ``` $ atma ```. We provide also a compiled version in 'build/' directory, so you
To build the application for release, run ``` $ atma build --file index.html --output release/```. We provide also a compiled version in 'build/' directory, so you
can see how the application looks like for production.
......
......@@ -217,6 +217,9 @@
}, {
"name": "Atma.js on GitHub",
"url": "https://github.com/atmajs"
}, {
"name": "Atma.js DevTool",
"url": "https://chrome.google.com/webstore/detail/atmajs-devtool/bpaepkmcmoablpdahclhdceapndfhdpo"
}]
}, {
"heading": "Overview",
......
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