Ember Latest

The latest build of Ember.

HTML

<script src="http://builds.emberjs.com/handlebars-1.0.0.js"></script>
<script src="http://builds.emberjs.com/ember-latest.js"></script>

<title>Ember Starter Kit</title>
  <link rel="stylesheet" href="css/normalize.css" type="text/css">
  <link rel="stylesheet" href="css/style.css" type="text/css">
  <link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.no-icons.min.css" rel="stylesheet" type="text/css">
</head>
<body>

  <script type="text/x-handlebars">
    <div class="navbar">
      <div class="navbar-inner">
        <a class="brand" href="#">Bloggr</a>
        <ul class="nav">
          <li>{{#link-to 'posts'}}Posts{{/link-to}}</li>
          <li>{{#link-to 'about'}}About{{/link-to}}</li>
        </ul>
      </div>
    </div>
    {{outlet}}
  </script>

  <script type="text/x-handlebars" id="posts">
    <div class="container-fluid">
      <div class="row-fluid">
        <div class="span3">
          <table class='table'>
          <thead>
          <tr><th>Recent Posts</th></tr>
          </thead>
          {{#each}}
          <tr><td>
          {{#link-to 'post' this}}
            {{{title}}} <small class='muted'>by {{author.name}}</small>
          {{/link-to}}
          </td></tr>
          {{/each}}
          </table>
        </div>
        <div class='span9'>
          {{outlet}}
        </div>
      </div>
    </div>
  </script>

  <script type="text/x-handlebars" id="post">

    {{#if isEditing}}
      {{partial 'post/edit'}}
      <button {{action 'doneEditing'}}>Done</button>
    {{else}}
      <button {{action 'edit'}}>Edit</button>
    {{/if}}

    <h1>{{{title}}}</h1>
    <h2>by {{author.name}} <small class='muted'>({{format-date date}})</small></h2>
    <hr>
    <div class="intro">
      {{format-markdown excerpt}}
    </div>

    <div class="below-the-fold">
      {{format-markdown body}}
    </div>
  </script>

  <script type="text/x-handlebars" id="post/_edit">
    <p>{{{input type="text" value=title}}}</p>
...

CSS

h1 {
    font-size: 1.6em;
    padding-bottom: 10px;
}
h2 {
    font-size: 1.4em;
}
ul {
    padding: 15px;
    font-size: 1.4em;
    color: green;
}

JavaScript

App = Ember.Application.create({});

App.ValidatorView = Ember.View.extend({
    tagName: 'i',
    templateName: 'ValidationView',
    validatorBinding: undefined,
    init: function(){
        Ember.addObserver(this.get('validator').get('model'), 'someProperty', this, this.validate);
    },
    validate: function() {
        this.get('validator').validate();
    },
    text: function () {
        var val = '';
        if (this.get('validator.errors')) {
            this.get('validator.errors').forEach(function (item) {
                val += item + '<br/>';
            });
        }
        return val;
    }.property('validator.errors.@each'),
});

Validator = Ember.Object.extend({
    functions: [],
    errors: Ember.A(),
    model: undefined,
    
    init: function(){
        this.get('functions').addObject(function(somePropertyValue) { 
            return parseInt(somePropertyValue) > 10 ? 'someProperty must be 10 or less' : ''; 
        });
        this.validate();
    },
    
    validate: function(){
        this.get('errors').clear();
        
        // for this sample we'll only concern ourselves with a single function
        var result = this.get('functions')[0].call(this, this.get('model.someProperty'));
        
        if (result.length > 0){
            this.get('errors').addObject(result);
        }
    }
});

App.IndexRoute = Ember.Route.extend({
    setupController: function(controller, model){
        controller.get('validators')['someValidatorName'] = Validator.create({
            model: controller.get('data')
        });
    }
});

App.IndexController = Ember.Controller.extend({
    data: {
        someProperty: 10
    },
    validators: [],
    actions: {
        newModel: function () {
            this.set('data', {
                someProperty: 5
            })
        }
    }
})