Skip to content

Instantly share code, notes, and snippets.

@jrmoran
Created January 16, 2012 09:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jrmoran/1620051 to your computer and use it in GitHub Desktop.
Save jrmoran/1620051 to your computer and use it in GitHub Desktop.
Backbone and CoffeeScript
$ ->
# Inspired in
# [this](http://adamjspooner.github.com/coffeescript-meet-backbonejs/)
#
# Live sample [here](http://jrmoran.com/playground/backbone-coffeescript/)
# override backbone sync, so when we remove/save items no server calls
# are made
Backbone.sync = (method, model, success, error) -> success()
mainView = new MainView el: '#container'
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Items</title>
<!--<link rel="stylesheet" href="/coffeescript-meet-backbonejs/style.css">-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script src="http://ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js"></script>
<script src="http://ajax.cdnjs.com/ajax/libs/underscore.js/1.1.6/underscore-min.js"></script>
<script src="http://ajax.cdnjs.com/ajax/libs/backbone.js/0.3.3/backbone-min.js"></script>
<script src="js/client.js"></script>
<!--<script src="js/client.min.js"></script>-->
<style type="text/css">
#container{
margin-top: 20px;
}
</style>
</head>
<body>
<h1>Backbone & CoffeeScript</h1>
<div>
<a href="docs/App.html">Docs</a>
</div>
<div id="container"></div>
</body>
</html>
class Item extends Backbone.Model
defaults:
name: 'Awesome'
price: 10.40
validate: (attrs)->
attrs.price = parseFloat attrs.price
if attrs.name is '' or isNaN attrs.price
'Invalid data'
class Items extends Backbone.Collection
model: Item
class ItemView extends Backbone.View
tagName: 'li'
events:
'click button.delete' : 'remove'
initialize: ->
_.bindAll this
@model.bind 'remove', @unrender
@render()
render: ->
$(@el).html "#{@model.get 'name'} <em>$#{@model.get 'price'}</em>
<button class = 'delete'>delete</button>"
this
remove : -> @model.destroy()
unrender: => $(@el).remove()
class MainView extends Backbone.View
initialize: ->
_.bindAll this
# collection
@collection = new Items
@collection.bind 'add', @appendItem
@collection.bind 'remove', @removeItem
@render()
events:
'submit #create': 'addItem'
render: ->
$(@el).append '<form id = "create">
<input name = "name" placeholder = "Name" />
<input name = "price" placeholder = "Price" />
<input type = "submit" value = "create" />
</form>
<h1>Items</h1>
<ul id = "items"></ul>
<div id = "notification"></div>'
@$notification = $ '#notification'
@$notification.hide()
# this should probably be its own view
showNotification: (text)->
@$notification.text(text).fadeIn 800, -> $(this).fadeOut()
addItem: (e)->
target = $(e.target)
item = new Item
# `set` returns a boolean indicating if the result was successful,
# and `error` callback can also be passed
isSet = item.set
name : target.find("[name=name]").val()
price: target.find("[name=price]").val()
,
error: (item, error)=> @showNotification error
if isSet
@collection.add item
e.preventDefault()
# run the listener in the context of the MainView
appendItem: (item)=>
itemView = new ItemView model: item
$(@el).find('ul').append itemView.el
removeItem: (item)=>
@showNotification "Item removed. #{@collection.length} remaining."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment