Amplify - Knockout - MVVM breakout - toastR
by johnpapa
HTML
<script src="https://raw.github.com/appendto/amplify/master/core/amplify.core.js"></script>
<script src="https://raw.github.com/appendto/amplify/master/store/amplify.store.js"></script>
<script src="https://raw.github.com/appendto/amplify/master/request/amplify.request.js"></script>
<link rel="stylesheet" href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css">
<link rel="stylesheet" href="http://twitter.github.com/bootstrap/assets/css/bootstrap-responsive.css">
<script src="https://raw.github.com/mennovanslooten/mockJSON/master/js/jquery.mockjson.js"></script>
<script src="https://raw.github.com/timrwood/moment/1.5.0/min/moment.min.js"></script>
<script src="http://codeseven.github.com/toastr/toastr.js"></script>
<link rel="stylesheet" href="http://codeseven.github.com/toastr/toastr.css">
<link rel="stylesheet" href="http://codeseven.github.com/toastr/toastr-responsive.css">
<script src="https://github.com/downloads/SteveSanderson/knockout/knockout-2.1.0.js"></script>
<div class="form-horizontal">
<div class="control-group">
<label for="userName" class="control-label">User name</label>
<div class="controls">
<div class="input-prepend input-append">
<span class="add-on">@</span><input id="userName" class="input-medium" placeholder="Twitter Name Here …" data-bind="value:userName, hasfocus:true, valueUpdate: 'afterkeydown'"/><button class="btn"><i class="icon-remove icon-input-append-btn" data-bind="click:clearSearch"></i></button><button
type="button"
class="btn btn-primary"
id="getButton"
data-bind="command:loadTweetsCommand">Load Tweets</button>
</div>
</div>
</div>
</div>
<div class="hide" data-bind="css: { show: tweets().length }">
<div>
<h4 class="caption">Tweets</h4>
<a class="btn btn-danger"...
CSS
body { margin: 30px; }
.dialog {
width: 550px;
}
.icon-input-append-btn {
height:16px;
margin-top: 0px;
}
.json-container{
margin-top: 20px;
width: 600px;
}
.twitter-item{
color:#444;
font-size:12px;
min-height: 51px;
padding: 12px 12px 12px 12px;
border: 1px solid #E8E8E8;
background-color:#F9F9F9;
}
.twitter-group {
/*margin: 20px 8px 8px 8px;*/
width: 600px;
}
.twitter-group > div:first-child
{
-moz-border-radius-topright: 15px;
-moz-border-radius-topleft: 15px;
-webkit-border-top-right-radius: 15px;
-webkit-border-top-left-radius: 15px;
border-top-right-radius: 15px;
border-top-left-radius: 15px;
}
.twitter-group > div:last-child
{
-moz-border-radius-bottomright: 15px;
-moz-border-radius-bottomleft: 15px;
-webkit-border-bottom-right-radius: 15px;
-webkit-border-bottom-left-radius: 15px;
border-bottom-right-radius: 15px;
border-bottom-left-radius: 15px;
}
/*.twitter_container a{
color:#0066CC;
font-weight:bold;
}
*/
.twitter-status{
height:60px;
padding:6px;
border-bottom:solid 1px #DEDEDE;
}
.twitter-image{
float:left;
margin-right:14px;
border:solid 2px #DEDEDE;
width:50px;
height:50px;
}
.twitter-posted-at{
font-size:11px;
padding-top:4px;
color:#999;
}
.alert {
padding-top: 10px;
margin-top: 0;
margin-bottom: 0;
margin-left: auto;
margin-right: auto;
width: 400px;
}
.close {
margin-top: 3px;
}
JavaScript
ko.utils.wrapAccessor = function(accessor) {
return function() {
return accessor
}
}
ko.bindingHandlers.command = {
init: function(element, valueAccessor, allBindingsAccessor, viewModel) {
var value = valueAccessor()
var commands = value.execute ? { click: value } : value
var events = {}
for (var command in commands) {
events[command] = commands[command].execute
}
ko.bindingHandlers.event.init(element, ko.utils.wrapAccessor(events), allBindingsAccessor, viewModel)
},
update: function(element, valueAccessor, allBindingsAccessor, viewModel) {
var commands = valueAccessor()
var canExecute = commands.canExecute || (commands.click ? commands.click.canExecute : null)
if (!canExecute) {
return
}
ko.bindingHandlers.enable.update(element, ko.utils.wrapAccessor(canExecute()), allBindingsAccessor, viewModel)
}
}
ko.asyncCommand = function(executeDelegate, canExecuteDelegate) {
var me = ko.observable()
me.isExecuting = ko.observable()
me.executeDelegate = executeDelegate
me.canExecute = ko.computed(function() {
return canExecuteDelegate ? canExecuteDelegate(me.isExecuting()) : true
})
me.completeCallback = function() {
me.isExecuting(false)
}
me.execute = function(argument) {
var args = []
// Allow for this argument to be passed on to execute delegate
if (me.executeDelegate.length === 2) {
args.push(argument)
}
args.push(me.completeCallback)
me.isExecuting(true)
me.executeDelegate.apply(this, args)
}
return me
}
var my = my || {}
my.defineRequests = (function () {
// Define what a getTweets request looks like... url, dataType, etc
// Typically put all of these in their own script file
amplify.request.define("getTweets", "ajax", {
url:...