JSFiddle - React, Tailwind, and code Playground

by Nick Iaconis

HTML

<script src="http://cloud.github.com/downloads/emberjs/ember.js/ember-0.9.6.min.js"></script>
<script type="text/x-handlebars">
    <div id="frm">
      <b>Load Tweets for: </b>{{view App.SearchTextField placeholder="Twitter username" valueBinding="App.tweetsController.username"}}
      <button {{action "loadTweets" target="App.tweetsController"}}>Go!</button>
    </div>
    <div id="content">
      <div id="recent">
        <h3>Recent Searches</h3>
        <ol>
          {{#each App.recentSearchesController.reverse}}
            <li>
              <a href="#" title="view again" {{action "searchAgain" target="App.recentSearchesController"}}>{{ this }}</a> -
              <a href="#" title="remove" {{action "removeUser" target="App.recentSearchesController"}}>X</a>
            </li>
          {{/each}}
        </ol>
      </div>
      <div id="tweets">
        <h3>Tweets</h3>
        <ul>
          {{#each App.tweetsController}}
            <li>
              <img {{bindAttr src="avatar"}} />
              <span>{{date}}</span>
              <h3>{{screen_name}}</h3>
              <p>{{text}}</p>
            </li>
          {{/each}}
        </ul>
      </div>
    </div>
  </script>

CSS

* {
	font-family: 'tahoma', sans-serif;
}
body {
	background: #eeeeee;
	overflow-y: scroll;
}
#frm {
	margin: 0 auto 15px auto;
	width: 600px;
	text-align: center;
}
#content {
	width: 600px;
	border: 1px solid green;
	margin: 0 auto;
}
	#recent {
		float: left;
		width: 190px;
	}
		#recent ol {
			margin: 0 0 0 15px;
			padding: 0;
		}
			#recent old li {
				padding: 5px;
			}
	#tweets {
		width: 385px;
		float: right;
	}
		#tweets ul {
			padding: 0;
			border: 1px solid #999999;
		}
			#tweets ul li {
				text-align: left;
				margin: 0;
				padding: 10px;
				list-style: none;
				border-bottom: 1px solid #999999;
				min-height: 50px;
				background: #eeeeee; /* Old browsers */
				background: -moz-linear-gradient(top,  #eeeeee 0%, #dddddd 100%); /* FF3.6+ */
				background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#eeeeee), color-stop(100%,#dddddd)); /* Chrome,Safari4+ */
				background: -webkit-linear-gradient(top,  #eeeeee 0%,#dddddd 100%); /* Chrome10+,Safari5.1+ */
				background: -o-linear-gradient(top,  #eeeeee 0%,#dddddd 100%); /* Opera 11.10+ */
				background: -ms-linear-gradient(top,  #eeeeee 0%,#dddddd 100%); /* IE10+ */
				background: linear-gradient(top,  #eeeeee 0%,#dddddd 100%); /* W3C */
				filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#dddddd',GradientType=0 ); /* IE6-9 */
			}
				#tweets ul li:hover {
					background: #cfe7fa; /* Old browsers */
					background: -moz-linear-gradient(top,  #cfe7fa 0%, #6393c1 100%); /* FF3.6+ */
					background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#cfe7fa), color-stop(100%,#6393c1)); /* Chrome,Safari4+ */
					background: -webkit-linear-gradient(top,  #cfe7fa 0%,#6393c1 100%); /* Chrome10+,Safari5.1+ */
					background: -o-linear-gradient(top,  #cfe7fa 0%,#6393c1 100%); /* Opera 11.10+ */
					background: -ms-linear-gradient(top,  #cfe7fa 0%,#6393c1 100%); /* IE10+ */
					background: linear-gradient(top,  #cfe7fa...

JavaScript

// Ember.js Tutorial from http://www.adobe.com/devnet/html5/articles/flame-on-a-beginners-guide-to-emberjs.html

/***********************
* Application
***********************/

App = Em.Application.create();

/***********************
* Models
***********************/

App.Tweet = Em.Object.extend({
  avater: null,
  screen_name: null,
  text: null,
  date: null
});

/***********************
* Views
***********************/

App.SearchTextField = Em.TextField.extend({
  insertNewline: function() {
    App.tweetsController.loadTweets();
  }
});

/***********************
* Controllers
***********************/

App.tweetsController = Em.ArrayController.create({
  content: [],
  username: '',
  loadTweets: function() {
    var me = this;
    var username = me.get("username");
    if ( username ) {
      var url = 'http://api.twitter.com/1/statuses/user_timeline.json'
          url += '?screen_name=%@&callback=?'.fmt(me.get("username"));
      // push username to recent searches array
      App.recentSearchesController.addUser(username);
      $.getJSON(url, function(data) {
        me.set('content', []);
        $(data).each(function(index, value) {
          var t = App.Tweet.create({
            avatar: value.user.profile_image_url,
            screen_name: value.user.screen_name,
            text: value.text,
            date: value.created_at
          });
          me.pushObject(t);
        });
      }); // end getJSON
    }
  } // end loadTweets
});

App.recentSearchesController = Em.ArrayController.create({
  content: [],
  addUser: function(name) {
    if ( this.contains(name) )
      this.removeObject(name);
    this.pushObject(name);
  },
  removeUser: function(view) {
    this.removeObject(view.context);
  },
  searchAgain: function(view) {
    App.tweetsController.set('username', view.context);
    App.tweetsController.loadTweets();
  },
  reverse: function(view) {
    return this.toArray().reverse();
  }.property('@each')
});