Skip to content

Instantly share code, notes, and snippets.

@mchung
Created May 26, 2011 06:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mchung/992681 to your computer and use it in GitHub Desktop.
Save mchung/992681 to your computer and use it in GitHub Desktop.
instant-eol code breakdown
var eol = {};
// For more information on this organizational pattern, refer to James Yu's
// blog post titled "A Backbone.js Tutorial with Rails (Part 1)" referenced
// in the README.
var App = {
Views: {},
Controllers: {},
Collections: {},
init: function() {
// Configure Backbone to interpolate Mustache/Handlebars template.
_.templateSettings = {
interpolate : /\{\{(.+?)\}\}/g
};
// Add {{images}} helper to Handlebars.
//
// The following helper displays a list of images on multiple rows.
// Currently, this is hard coded to 5 images per row.
Handlebars.registerHelper('images', function(images, fn) {
var out = "<tr>";
var i = 0;
for(i = 0, l = images.length; i < l; i++) {
out = out + "<td>" + fn(images[i]) + "</td>";
if (i % 5 == 4) {
out = out + "</tr><tr>";
}
}
return out + "</tr>";
});
// Load the main controller (search) and start Backbone.
eol.app = new App.Controllers.Search();
Backbone.history.start();
}
};
%script{:id => "index-template", :type => "text/x-handlebars-template"}
.index
#logo
Search the
%a{:href => "http://eol.org"} Encyclopedia of Life
%form{:id => "search_form", :method => "get", :autocomplete => "off", :onsubmit => "return false;"}
%input{:id => "search_query", :type => "text", :placeholder => "Panthera Leo, Homo sapiens"}
%a{:id => "search_action", :href => "#", :class => "large green awesome"}
Search Images
#previous
%ul
%li
History:
- @history.each do |query|
%li
%a{:href => "/#search/#{query}/1", :class => "saved_search_action", :"data-search-query" => "#{query}"} #{query}
#progress{:style => "display: none;"}
%img{:src => "/images/ajax-loader.gif"}
App.Views.Index = Backbone.View.extend({
el: $("#main"),
template: Handlebars.compile($("#index-template").html()),
events: {
"click a#search_action" : "searchOnClick",
"submit form" : "searchOnSubmit",
"click a.saved_search_action" : "searchSavedOnClick"
},
initialize: function(args) {
_.bindAll(this, "render");
},
render: function() {
$(this.el).html(this.template());
document.getElementById("search_query").focus();
return this;
},
searchOnClick: function(e) {
var q = $("#search_query").val();
$("#progress").show();
$("a#search_action").attr("href", "#search/" + q + "/1");
},
searchOnSubmit: function(e) {
var q = $("#search_query").val();
$("#progress").show();
eol.app.search(q, 1);
},
searchSavedOnClick: function(e) {
var q = e.target.getAttribute("data-search-query");
$("#search_query").val(q);
$("#progress").show();
}
});
App.Controllers.Search = Backbone.Controller.extend({
// This controller is responsible for the following activites
routes: {
// The results page, with the list of images. An example of a full URL:
// - http://localhost/#search/Lion/1
// - http://localhost/#search/Unicorn/1
"search/:query/:page": "search",
// The index page, with the single text field for searching.
"": "index"
},
// By default, this view is rendered when a user visits our application.
index: function() {
new App.Views.Index().render();
},
// This view is rendered when a user submits a search query.
search: function(query, page) {
// When a user submits an empty query, our default search is for the
// almighty Panthera Leo.
if (query === "" || query === undefined) {
query = "Panthera Leo";
}
if (page === undefined) {
page = 1;
}
var url = "search/" + query + "/" + page;
console.log("#" + url);
// Write the current URL to the browser's URL window whenever a new
// search query has been submitted. We do this for two reasons:
// 1. Users can save their search results as a bookmark
// 2. To preserve the functionality of the browser's back button
Backbone.history.saveLocation(url);
var rv = new ResultSet();
// The server's url method signature matches the fragment. Normally
// this URL points at some RESTful interface on the server side, but
// since we're building a search interface, this URL points to the
// actual search method.
//
// The server's search API and the browser's URL fragment are
// deliberately identical.
rv.url = function() {
return url;
};
// Fetch our search results from the server side and render the results
rv.fetch({
success: function(collection, response) {
// console.log("success");
// console.log(collection);
// console.log(response);
new App.Views.Results({model: collection}).render();
}
// TODO: Possibly handle the case where no results are available.
// , error :function() {}
});
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment