Ember JS Playground

Developing my ToDos sample in Ember

HTML

<script src="http://cloud.github.com/downloads/emberjs/ember.js/ember-0.9.7.1.js"></script>
<h1>Another Ember.js ToDo App</h1>
<div class="app-container">
</div>

<script type="text/x-handlebars" data-template-name="app">
    <button {{action "onAdd" on="click"}} >Add another ToDo item</button>
    <span class="remaining">{{remaining}}</span>
    <ul class="container">
        {{#each content.todos}}
            {{#if isEditing}}
                {{#view ToDoApp.EditableListItemView contentBinding="this"}}
                    <span class="action">{{#view cancelLink class="cancel"}}{{text}}{{/view}}</span>
                    <span class="action">{{#view updateLink class="update"}}{{text}}{{/view}}</span>
                    {{#view lineEdit class="editing"}}{{/view}}
                {{/view}}
            {{else}}
                {{#view ToDoApp.ListItemView contentBinding="this"}}
                    <span class="action">{{#view removeLink class="remove"}}{{text}}{{/view}}</span>
                    <span class="action">{{#view editLink class="edit"}}{{text}}{{/view}}</span>
                    {{#view checkBox class="complete"}}{{/view}}
                    {{#view itemText classBinding="item completed"}}{{content}}{{/view}}
                {{/view}}
            {{/if}}
        {{/each}}
    </ul>
</script>

CSS

button {
    margin: 10px;
}

h1 {
    font: 2.1em sans-serif;
    padding: 10px;
    margin-bottom: 10px;
}

li {
    padding: 10px 20px;
    margin: 5px 20px;
    border-radius: 5px;
    background: #444;
    color: white;
    font: 1.3em sans-serif;
}

ul {
    background: lightgray;
    padding: 5px;
}


input.complete {
    margin-right: 10px;
}

input.editing {
    width: 65%;
}

span.action {
    float: right;
    margin-left: 10px;
    font-size: 0.8em;
}

span.item {
    text-shadow: 1px 0 3px black;
}

span.item.completed {
    text-decoration: line-through;
}

.app-container{
    position: relative;
}

.action a {
    text-decoration: none;
    color: orange;
}

.action a:hover {
    text-decoration: underline;
    color: orangered;
}

.remaining {
    font: 1.1em sans-serif;
    right: 25px;
    position: absolute;
    margin: 10px;
}

JavaScript

// Application namespace
window.ToDoApp = Ember.Application.create();

// The ToDo object - acts as a controller/model for the application
ToDoApp.ToDo = Ember.Object.extend({
    // Data
    isCompleted: false,
    isEditing: false,
    
    // Default text for a ToDo item
    listText: 'Edit this ToDo item',
    // When editing mirror the value in the view here
    tmpText: '',
    
    toDoText: Ember.computed(function(key, value) {
        // getter
        if (arguments.length === 1) {
            return this.get('isEditing') ? this.get('tmpText') : this.get('listText');
            
        // setter
        } else {
            this.set('tmpText', value);
            return value;
        }
    }).property('isEditing', 'tmpText', 'listText'),
    
    // Operations
    onEdit: function() {
        this.set('tmpText', this.get('listText'));
        this.set('isEditing', true);
    },
    
    onCommit: function() {
        this.set('listText', this.get('tmpText'));
        this.set('isEditing', false);
    },
    
    onCancel: function() {
        this.set('isEditing', false);
    }
});

// The collection of ToDo objects
ToDoApp.toDoList = Ember.Object.create({
    
    // Data
    todos: [
        ToDoApp.ToDo.create({ listText: 'Step one: Create great ToDos App', isCompleted: true }),
        ToDoApp.ToDo.create({ listText: 'Step two: ???' }),
        ToDoApp.ToDo.create({ listText: 'Step three: Profit' })
        ],
    
    // Calculate the remaining open items
    remaining: function() {
        var todos = this.get('todos');
        return todos.filterProperty('isCompleted', false).get('length');
    }.property('[email protected]'),
    
    // Operations
    addToDo: function() {
        this.get('todos').pushObject(ToDoApp.ToDo.create());
    },
    
    removeToDo: function(value) {
        var list = this.get('todos'),
            index = list.indexOf(value);
        
        list.removeAt(index);
    }
});

// The main app, loads the app...