Your browser doesn't support the features required by impress.js, so you are presented with a simplified version of this presentation.

For the best experience please use the latest Chrome or Safari browser. Firefox 10 (to be released soon) will also handle it.

Interactive YouTube search with Ember.js

by Aleksey Gureiev

 

http://alg.github.com/talks/emberjs/

Ember.js

Ember is a JavaScript framework for creating ambitious web applications by eliminating boilerplate and providing a standard application architecture. http://emberjs.com/

Demo

Let's build the bloody thing!

Application


  <html>
    <body>
      <div id="app">
        ...
      </div>
    </body>
  </html>
        


  App = Em.Application.create({

    rootElement:  "#app",

    selectedVideo: null

  });
        

Models



  App.Video = Em.Object.extend({

    title: null,

    yid: null

  });

        

Results controller


  App.searchResultsController =
    Em.ArrayController.create({

      isSearching: false,

      search: function(query) {
        this.set('isSearching', true);

        // search logic

        this.set('isSearching', false);
      }
  });

        

Search box


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

    {{view App.SearchBox
           placeholder="What you want to watch today?"}}

  </script>
        

  App.SearchBox = Em.TextField.extend({

    insertNewline: function() {
      var query = this.get('value');
      App.searchResultsController.search(query);
    }

  });
        

  search: function(query) {
    var self = this;

    this.set('isSearching', true);
    this.set('content', []);

    var c = $.getJSON(
      "http://gdata.youtube.com/feeds/api/videos",
      { alt: 'json', 'max-results': 7, v: 2, q: query });

    c.success(function(data) {
      self.set('content', dataToVideos(data.feed.entry);
    });

    c.complete(function() {
      self.set('isSearching', false);
    });
  }
        

  dataToVideos: function(entries) {
    var results = [];

    for (var i = 0; i < entries.length; i++) {
      var e = entries[i];
      results.push(App.Video.create({
        yid: e.id.$t.split(':')[3],
        title: e.title.$t
      }));
    }

    return results;
  }
        

Showing results


  <table>
    {{#each App.searchResultsController}}
      <tr>
        <td class="title">{{title}}</td>
      </tr>
    {{/each}}
  </table>
         

Selecting video


  App.ResultRow = Em.View.extend({
    video: null,
    click: function(evt) {
      App.set('selectedVideo', this.get('video'));
    }
  });
        

  <table>
    {{#each App.searchResultsController}}
      {{#view App.ResultRow
            videoBinding="this" tagName="tr"}}

        <td class="title">{{video.title}}</td>

      {{/view}}
    {{/each}}
  </table>
         

Playing video


  <script type="text/x-handlebars">
    {{#view App.Player}}
      <h3>{{videoTitle}}</h3>
      <iframe {{bindAttr src="videoUrl"}}></iframe>
    {{/view}}
  </script>
        

  App.Player = Em.View.extend({
    videoBinding: "App.selectedVideo",

    videoTitle: function() {
      var video = this.get('video');
      return video ? video.get('title') : "Play video";
    }.property('video'),

    videoUrl: function() {
      return "http://www.youtube.com/embed/" +
              this.getPath('.video.yid');
    }.property("video")
  });
        

Loading state


  {{#if App.searchResultsController.isSearching}}
    Searching. Please wait…
  {{/if}}
        

  App.searchResultsController =
    Em.ArrayController.create({

      isSearching: false,

      search: function(query) {
        var self = this;

        this.set('isSearching', true);

        var c = $.getJSON(...);

        c.complete(function() {
          self.set('isSearching', false);
        });
      }
  });
        

That's all folks!

Aleksey Gureiev

Use a spacebar or arrow keys to navigate