Skip to content

Commit

Permalink
Merge pull request tastejs#25 from goldledoigt/master
Browse files Browse the repository at this point in the history
ExtJS 4 Todo addition
  • Loading branch information
addyosmani committed Nov 10, 2011
2 parents be29fea + 839abc9 commit a3fd9c9
Show file tree
Hide file tree
Showing 9 changed files with 319 additions and 0 deletions.
107 changes: 107 additions & 0 deletions todo-example/extjs/css/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
body {
margin: 0;
padding: 0;
background-color: #EEEEEE;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}

div, h1, span {
outline: none;
}

#todo {
width: 480px;
padding: 20px;
color: #333333;
margin: 0 auto 40px;
background-color: white;
border-radius: 0 0 5px 5px;
box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.2);
}

h1 {
margin: 0;
line-height: 1;
font-size: 36px;
text-align: center;
padding: 20px 0 30px;
}

.credits {
color: #999;
font-size: 0.9em;
text-align: center;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.8);
}

.credits a, .credits a:visited {
color: #888;
}

input[type="text"] {
padding: 6px;
width: 466px !important;
margin: 0 auto;
font-size: 24px;
border: 1px solid #999999;
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.2) inset;
}

.row {
font-size: 1.7em;
padding: 20px 0 10px;
border-bottom: 1px solid #CCCCCC;
}

.row input[type="checkbox"] {
vertical-align: middle;
}

.row span {
cursor: pointer;
margin-left: 5px;
}

.row span.checked {
color: #777777;
text-decoration: line-through;
}

.x-toolbar {
color: #555555;
margin-top: 10px;
padding: 8px 20px;
background-color: #F4FCE8;
border-radius: 0 0 5px 5px;
border-top: 1px solid #EDEDED;
}

.x-toolbar .x-container {
height: 21px;
}

.x-toolbar button {
float: right;
width: 170px;
border: 0 none;
color: #555555;
cursor: pointer;
border-radius: 12px;
padding: 3px 10px 4px;
background: rgba(0, 0, 0, 0.1);
box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.2);
}

.x-toolbar .x-over button {
background: rgba(0, 0, 0, 0.15);
box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.3);
}

.x-toolbar .x-pressed button {
background: rgba(0, 0, 0, 0.1);
box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.2);
}

.x-clear {
clear: both;
}
25 changes: 25 additions & 0 deletions todo-example/extjs/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>ExtJS</title>

<link rel="stylesheet" href="css/style.css">
</head>

<body>
<div id="todo">
<h1>Todos</h1>
<input type="text" id="taskfield" placeholder="What needs to be done?" />
</div>
<div class="credits">
Credits:<br /><a href="http://revolunet.com/">Revolunet</a>
</div>

<script type="text/javascript" src="http://extjs.cachefly.net/ext-4.0.2a/bootstrap.js"></script>
<script src="js/app.js"></script>
</body>
</html>
22 changes: 22 additions & 0 deletions todo-example/extjs/js/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
Ext.Loader.setConfig({enabled:true});

Ext.application({
name: 'Todo',
appFolder: 'js',
controllers: ['Tasks'],
launch: function() {

Ext.create('Ext.container.Container', {
renderTo: 'todo',
items: [{
xtype: 'taskField',
contentEl: 'taskfield'
}, {
xtype: 'taskList'
}, {
xtype: 'taskToolbar'
}]
});

}
});
92 changes: 92 additions & 0 deletions todo-example/extjs/js/controller/Tasks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
Ext.define('Todo.controller.Tasks', {

models: ['Task'],

stores: ['Tasks'],

extend: 'Ext.app.Controller',

views: ['TaskField', 'TaskList', 'TaskToolbar'],

refs: [
{ref: 'taskList', selector: 'taskList'},
{ref: 'taskToolbar', selector: 'taskToolbar'}
],

init: function() {
this.control({
'taskField': {
keyup: this.onTaskFieldKeyup
},
'taskList': {
itemclick: this.onListItemClick
},
'taskToolbar > button': {
click: this.onClearButtonClick
}
});

this.getTasksStore().on({
scope: this,
update: this.onStoreDataChanged,
datachanged: this.onStoreDataChanged
});
},

onTaskFieldKeyup: function(field, event) {
var value = field.getValue();
if (event.keyCode === 13 && value !== '') {
var store = this.getTasksStore();
store.add({label: value, checked: false});
field.reset();
store.sync();
}
},

onListItemClick: function(list, record, el) {
record.set('checked', !record.get('checked'));
record.store.sync();
record.commit();
},

onClearButtonClick: function() {
var records = [],
store = this.getTasksStore();

store.each(function(record) {
if (record.get('checked')) {
records.push(record);
}
});
store.remove(records);
store.sync();
},

onStoreDataChanged: function() {
var info = '', text = '',
store = this.getTasksStore(),
totalCount = store.getCount(),
toolbar = this.getTaskToolbar(),
button = toolbar.items.first(),
container = toolbar.items.last(),
records = store.queryBy(function(record) {
return !record.get('checked');
}),
count = records.getCount(),
checkedCount = totalCount - count;

if (count) {
info = '<b>' + count + '</b> item' + (count > 1 ? 's' : '') + ' left.';
}

if (checkedCount) {
text = 'Clear '+ checkedCount +' completed item' + (checkedCount > 1 ? 's' : '');
}

container.update(info);
button.setText(text);
button.setVisible(checkedCount);
toolbar.setVisible(totalCount);
}

});
8 changes: 8 additions & 0 deletions todo-example/extjs/js/model/Task.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Ext.define('Todo.model.Task', {
extend: 'Ext.data.Model',
fields: ['id', 'label', {name: 'checked', type: 'boolean'}],
proxy: {
type: 'localstorage',
id: 'todo'
}
});
5 changes: 5 additions & 0 deletions todo-example/extjs/js/store/Tasks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Ext.define('Todo.store.Tasks', {
autoLoad: true,
model: 'Todo.model.Task',
extend: 'Ext.data.Store'
});
33 changes: 33 additions & 0 deletions todo-example/extjs/js/view/TaskField.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
Ext.define('Todo.view.TaskField' , {

enableKeyEvents: true,

alias : 'widget.taskField',

extend: 'Ext.Component',

emptyText: 'What needs to be done?',

afterRender: function() {
this.callParent(arguments);
this.field = this.el.first();
this.field.on('keyup', this.onKeyup, this);
},

onKeyup: function(event) {
this.fireEvent('keyup', this, event);
},

getValue: function() {
return this.field.dom.value;
},

setValue: function(value) {
this.field.dom.value = value;
},

reset: function() {
this.setValue('');
}

});
16 changes: 16 additions & 0 deletions todo-example/extjs/js/view/TaskList.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Ext.define('Todo.view.TaskList' , {
store: 'Tasks',
loadMask: false,
itemSelector: 'div.row',
extend: 'Ext.view.View',
alias : 'widget.taskList',
tpl: Ext.create('Ext.XTemplate',
'<tpl for=".">',
'<div class="row">',
'<input type="checkbox" {[values.checked ? "checked" : ""]} />',
'<span class="{[values.checked ? "checked" : ""]}">{label}</span>',
'</div>',
'</tpl>',
{compiled: true}
)
});
11 changes: 11 additions & 0 deletions todo-example/extjs/js/view/TaskToolbar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Ext.define('Todo.view.TaskToolbar' , {
hidden: true,
extend: 'Ext.Toolbar',
alias : 'widget.taskToolbar',
items: [{
xtype: 'button',
hidden: true
}, {
xtype: 'container'
}]
});

0 comments on commit a3fd9c9

Please sign in to comment.