Instantly share code, notes, and snippets.

What would you like to do?
window.AppView = Backbone.View.extend
el: $("#main")
"keyup input": "search"
initialize: ->
_.bindAll this, 'addOne', 'addAll', 'search', 'initSearch', 'filter', 'startLoading', 'stopLoading', 'updateTime'
Realms.bind 'refresh', this.addAll
Realms.bind 'refresh:start', this.startLoading
Realms.bind 'refresh:end', this.stopLoading
Realms.bind 'refresh:end', this.updateTime
Realms.bind 'filter:change', this.filter
# Add a single realm to the page.
addOne: (realm) ->
view = new RealmView(model: realm)
this.el.append view.render().el
# Add an entire list of realms to the page.
# Deletages to this.addOne.
addAll: ->
view = this
_.each Realms.models, (realm) ->
unless realm.view?
view.addOne realm
# Now that the initial data is shown, start the controller's routing.
# Called when the "keyup" event is fired from the input box.
# Sets the hash tag, which the controller picks up on and fires
# events to ask the app to filter based on the input.
search: ->
window.location.hash = this.$("input").val()
# Set the initial value of the search box to be whatever is in the URL.
initSearch: ->
# Called when the realm list's filter:change event is triggered.
# Iterates over the realms to see if each matches the search value.
filter: (term) ->
if term == ""
Realms.each (realm) ->
if realm.get('name').startsWith(term)
startLoading: ->
this.$("#loading img").show()
stopLoading: ->
this.$("#loading img").hide()
updateTime: ->
now = new Date
hours = now.getHours()
minutes = now.getMinutes()
seconds = now.getSeconds()
meridian = if hours < 12 then "AM" else "PM"
hours -= 12 if hours > 12
hours = 12 if hours == 0
minutes = "0#{minutes}" if minutes < 10
seconds = "0#{seconds}" if seconds < 10
this.$("#time span").text("#{hours}:#{minutes}:#{seconds} #{meridian}")
window.Controller = Backbone.Controller.extend
":realm": "realm"
# Match any string in the hash tag to be the name of a realm to search for.
realm: (realm)->
window.Realm = Backbone.Model.extend
initialize: ->
# Only set default data if it doesn't already exist.
unless this.get("name")?
name: "unknown"
slug: "unknown"
type: "n/a"
population: "n/a"
queue: false
status: false
window.RealmView = Backbone.View.extend
tagName: "div"
template: _.template $("#realm_template").html()
initialize: ->
_.bindAll this, 'render', 'show', 'hide'
# Whenever the data changes, the view will automatically re-render itself.
this.model.bind 'change', this.render
this.model.view = this
# Render a single realm based on the template embedded in the HTML.
render: ->
show: ->
hide: ->
window.RealmList = Backbone.Collection.extend
model: Realm
url: ""
initialize: ->
_.bindAll this, 'update', 'parse', 'processUpdate', 'filter'
# After the first refresh, we no longer want to replace the models
# in the collection with new ones. Thus, we will use our own 'refresh'
# method which simply updates all the models with the new data.
this.bind 'refresh', ->
this.refresh = this.processUpdate
# A wrapper around fetch() to (1) fire a "loading" event and
# (2) ensure that a timer is set so another update happens in the future.
update: ->
this.trigger 'refresh:start' # Indicates data is being collected.
window.setTimeout this.update, 1000 * 60 * 5 # update every 5 minutes
# Custom parse method (1) extracts the array from Blizzard's JSON API and
# (2) adds an "id" attribute to every model equal to that Realm's slug.
parse: (response) ->
_.each response.realms, (realm) -> = realm.slug
this.trigger 'refresh:end' # Indicates data collection has ended.
# Our replacement 'refresh' method, for every refresh after the first.
# Iterates over the models in the collection and updates each one's data.
processUpdate: (models, options) ->
list = this
_.each models, (model) ->
id =
original_model = list.get(id)
# Called by our controller when the hash tag changes.
# We simply fire an event indicating the term has changed, and any view
# that is interested will handle the work of hiding or showing elements.
filter: (term) ->
this.trigger 'filter:change', term
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment