Simple starting point for Ember.js fiddles

by MikeAski

HTML

<script src="http://mike.aski.free.fr/js/ember.js"></script>
<script src="http://mike.aski.free.fr/js/ember-data.js"></script>
<h1>Todos</h1>
  <script type="text/x-handlebars">
  {{view Todos.CreateTodoView id="new-todo" placeholder="What needs to be done?"}}

  <!-- Insert this after the CreateTodoView and before the collection. -->
  {{#view Todos.StatsView id="stats"}}
    {{#view Em.Button classBinding="isActive"
      target="Todos.todosController"
      action="clearCompletedTodos"}}
      Clear Completed Todos
    {{/view}}
    {{remainingString}} remaining
  {{/view}}

  {{view Em.Checkbox class="mark-all-done"
    title="Mark All as Done"
    valueBinding="Todos.todosController.allAreDone"}}

  {{#collection contentBinding="Todos.todosController" tagName="ul" itemClassBinding="content.isDone"}}
    {{view Em.Checkbox titleBinding="content.title"
        valueBinding="content.isDone"}}
  {{/collection}}
  </script>

CSS

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  font: inherit;
  vertical-align: baseline; }

body {
  line-height: 1; }

ol, ul {
  list-style: none; }

table {
  border-collapse: collapse;
  border-spacing: 0; }

caption, th, td {
  text-align: left;
  font-weight: normal;
  vertical-align: middle; }

q, blockquote {
  quotes: none; }
  q:before, q:after, blockquote:before, blockquote:after {
    content: "";
    content: none; }

a img {
  border: none; }

article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
  display: block; }

/* CSS Reset */
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  font: inherit;
  vertical-align: baseline; }

body {
  line-height: 1; }

ol, ul {
  list-style: none; }

table {
  border-collapse: collapse;
  border-spacing: 0; }

caption, th, td {
  text-align: left;
  font-weight: normal;
  vertical-align: middle; }

q, blockquote {
  quotes: none; }
  q:before, q:after, blockquote:before,...

JavaScript

Todos = Ember.Application.create();

Todos.Todo = Em.Object.extend({
  title: null,
  isDone: false
});

Todos.todosController = Em.ArrayProxy.create({
  content: [],

  createTodo: function(title) {
    var todo = Todos.Todo.create({ title: title });
    this.pushObject(todo);
  },

  clearCompletedTodos: function() {
    this.filterProperty('isDone', true).forEach(this.removeObject, this);
  },

  remaining: function() {
    return this.filterProperty('isDone', false).get('length');
  }.property('@each.isDone'),

  allAreDone: function(key, value) {
    if (value !== undefined) {
      this.setEach('isDone', value);

      return value;
    } else {
      return !!this.get('length') && this.everyProperty('isDone', true);
    }
  }.property('@each.isDone')
});

Todos.StatsView = Em.View.extend({
  remainingBinding: 'Todos.todosController.remaining',

  remainingString: function() {
    var remaining = this.get('remaining');
    return remaining + (remaining === 1 ? " item" : " items");
  }.property('remaining')
});

Todos.CreateTodoView = Em.TextField.extend({
  insertNewline: function() {
    var value = this.get('value');

    if (value) {
      Todos.todosController.createTodo(value);
      this.set('value', '');
    }
  }
});