Skip to content
Browse files

my-todo

  • Loading branch information...
1 parent b8208f6 commit 27c646669f280261726d517c5fecb26daf3bb954 @Bonias committed Oct 12, 2012
Showing with 1,934 additions and 1 deletion.
  1. +3 −1 .gitignore
  2. +38 −0 Gemfile
  3. +122 −0 Gemfile.lock
  4. +261 −0 README.rdoc
  5. +7 −0 Rakefile
  6. BIN app/assets/images/bg.png
  7. BIN app/assets/images/rails.png
  8. +21 −0 app/assets/javascripts/application.js
  9. +2 −0 app/assets/javascripts/backbone/initialize.js.coffee
  10. 0 app/assets/javascripts/backbone/models/.gitkeep
  11. +44 −0 app/assets/javascripts/backbone/models/entry.js.coffee
  12. 0 app/assets/javascripts/backbone/routers/.gitkeep
  13. +14 −0 app/assets/javascripts/backbone/routers/app_router.js.coffee
  14. 0 app/assets/javascripts/backbone/templates/.gitkeep
  15. +6 −0 app/assets/javascripts/backbone/templates/item_template.jst.ejs
  16. +15 −0 app/assets/javascripts/backbone/templates/stats_template.jst.ejs
  17. +14 −0 app/assets/javascripts/backbone/todo_app.js.coffee
  18. 0 app/assets/javascripts/backbone/views/.gitkeep
  19. +100 −0 app/assets/javascripts/backbone/views/app.js.coffee
  20. +66 −0 app/assets/javascripts/backbone/views/entries.js.coffee
  21. +3 −0 app/assets/javascripts/entries.js.coffee
  22. +13 −0 app/assets/stylesheets/application.css
  23. +410 −0 app/assets/stylesheets/base.css
  24. +3 −0 app/assets/stylesheets/entries.css.scss
  25. +69 −0 app/assets/stylesheets/scaffolds.css.scss
  26. +3 −0 app/controllers/application_controller.rb
  27. +90 −0 app/controllers/entries_controller.rb
  28. +4 −0 app/controllers/home_controller.rb
  29. +2 −0 app/helpers/application_helper.rb
  30. +2 −0 app/helpers/entries_helper.rb
  31. +2 −0 app/helpers/home_helper.rb
  32. 0 app/mailers/.gitkeep
  33. 0 app/models/.gitkeep
  34. +5 −0 app/models/entry.rb
  35. +25 −0 app/views/entries/_form.html.erb
  36. +6 −0 app/views/entries/edit.html.erb
  37. +25 −0 app/views/entries/index.html.erb
  38. +5 −0 app/views/entries/new.html.erb
  39. +15 −0 app/views/entries/show.html.erb
  40. +19 −0 app/views/home/index.html.erb
  41. +14 −0 app/views/layouts/application.html.erb
  42. +4 −0 config.ru
  43. +68 −0 config/application.rb
  44. +6 −0 config/boot.rb
  45. +25 −0 config/database.yml
  46. +5 −0 config/environment.rb
  47. +37 −0 config/environments/development.rb
  48. +67 −0 config/environments/production.rb
  49. +37 −0 config/environments/test.rb
  50. +7 −0 config/initializers/backtrace_silencers.rb
  51. +15 −0 config/initializers/inflections.rb
  52. +5 −0 config/initializers/mime_types.rb
  53. +7 −0 config/initializers/secret_token.rb
  54. +8 −0 config/initializers/session_store.rb
  55. +14 −0 config/initializers/wrap_parameters.rb
  56. +5 −0 config/locales/en.yml
  57. +64 −0 config/routes.rb
  58. +11 −0 db/migrate/20121012183502_create_entries.rb
  59. +24 −0 db/schema.rb
  60. +7 −0 db/seeds.rb
  61. +2 −0 doc/README_FOR_APP
  62. 0 lib/assets/.gitkeep
  63. 0 lib/tasks/.gitkeep
  64. +26 −0 public/404.html
  65. +26 −0 public/422.html
  66. +25 −0 public/500.html
  67. 0 public/favicon.ico
  68. +5 −0 public/robots.txt
  69. +6 −0 script/rails
  70. 0 vendor/assets/javascripts/.gitkeep
  71. 0 vendor/assets/stylesheets/.gitkeep
  72. 0 vendor/plugins/.gitkeep
View
4 .gitignore
@@ -13,4 +13,6 @@ capybara-*.html
/spec/tmp/*
**.orig
rerun.txt
-pickle-email-*.html
+pickle-email-*.html
+/.idea/*
+/.rvmrc
View
38 Gemfile
@@ -0,0 +1,38 @@
+source 'https://rubygems.org'
+
+gem 'rails', '3.2.8'
+
+# Bundle edge Rails instead:
+# gem 'rails', :git => 'git://github.com/rails/rails.git'
+
+gem 'sqlite3'
+gem "rails-backbone"
+
+# Gems used only for assets and not required
+# in production environments by default.
+group :assets do
+ gem 'sass-rails', '~> 3.2.3'
+ gem 'coffee-rails', '~> 3.2.1'
+
+ # See https://github.com/sstephenson/execjs#readme for more supported runtimes
+ gem 'therubyracer', :platforms => :ruby
+
+ gem 'uglifier', '>= 1.0.3'
+end
+
+gem 'jquery-rails'
+
+# To use ActiveModel has_secure_password
+# gem 'bcrypt-ruby', '~> 3.0.0'
+
+# To use Jbuilder templates for JSON
+# gem 'jbuilder'
+
+# Use unicorn as the app server
+# gem 'unicorn'
+
+# Deploy with Capistrano
+# gem 'capistrano'
+
+# To use debugger
+# gem 'debugger'
View
122 Gemfile.lock
@@ -0,0 +1,122 @@
+GEM
+ remote: https://rubygems.org/
+ specs:
+ actionmailer (3.2.8)
+ actionpack (= 3.2.8)
+ mail (~> 2.4.4)
+ actionpack (3.2.8)
+ activemodel (= 3.2.8)
+ activesupport (= 3.2.8)
+ builder (~> 3.0.0)
+ erubis (~> 2.7.0)
+ journey (~> 1.0.4)
+ rack (~> 1.4.0)
+ rack-cache (~> 1.2)
+ rack-test (~> 0.6.1)
+ sprockets (~> 2.1.3)
+ activemodel (3.2.8)
+ activesupport (= 3.2.8)
+ builder (~> 3.0.0)
+ activerecord (3.2.8)
+ activemodel (= 3.2.8)
+ activesupport (= 3.2.8)
+ arel (~> 3.0.2)
+ tzinfo (~> 0.3.29)
+ activeresource (3.2.8)
+ activemodel (= 3.2.8)
+ activesupport (= 3.2.8)
+ activesupport (3.2.8)
+ i18n (~> 0.6)
+ multi_json (~> 1.0)
+ arel (3.0.2)
+ builder (3.0.3)
+ coffee-rails (3.2.2)
+ coffee-script (>= 2.2.0)
+ railties (~> 3.2.0)
+ coffee-script (2.2.0)
+ coffee-script-source
+ execjs
+ coffee-script-source (1.3.3)
+ ejs (1.1.1)
+ erubis (2.7.0)
+ execjs (1.4.0)
+ multi_json (~> 1.0)
+ hike (1.2.1)
+ i18n (0.6.1)
+ journey (1.0.4)
+ jquery-rails (2.1.3)
+ railties (>= 3.1.0, < 5.0)
+ thor (~> 0.14)
+ json (1.7.5)
+ libv8 (3.3.10.4)
+ mail (2.4.4)
+ i18n (>= 0.4.0)
+ mime-types (~> 1.16)
+ treetop (~> 1.4.8)
+ mime-types (1.19)
+ multi_json (1.3.6)
+ polyglot (0.3.3)
+ rack (1.4.1)
+ rack-cache (1.2)
+ rack (>= 0.4)
+ rack-ssl (1.3.2)
+ rack
+ rack-test (0.6.2)
+ rack (>= 1.0)
+ rails (3.2.8)
+ actionmailer (= 3.2.8)
+ actionpack (= 3.2.8)
+ activerecord (= 3.2.8)
+ activeresource (= 3.2.8)
+ activesupport (= 3.2.8)
+ bundler (~> 1.0)
+ railties (= 3.2.8)
+ rails-backbone (0.8.0)
+ coffee-script (~> 2.2.0)
+ ejs (~> 1.1.1)
+ jquery-rails (~> 2.1.3)
+ railties (>= 3.1.0)
+ railties (3.2.8)
+ actionpack (= 3.2.8)
+ activesupport (= 3.2.8)
+ rack-ssl (~> 1.3.2)
+ rake (>= 0.8.7)
+ rdoc (~> 3.4)
+ thor (>= 0.14.6, < 2.0)
+ rake (0.9.2.2)
+ rdoc (3.12)
+ json (~> 1.4)
+ sass (3.2.1)
+ sass-rails (3.2.5)
+ railties (~> 3.2.0)
+ sass (>= 3.1.10)
+ tilt (~> 1.3)
+ sprockets (2.1.3)
+ hike (~> 1.2)
+ rack (~> 1.0)
+ tilt (~> 1.1, != 1.3.0)
+ sqlite3 (1.3.6)
+ therubyracer (0.10.2)
+ libv8 (~> 3.3.10)
+ thor (0.16.0)
+ tilt (1.3.3)
+ treetop (1.4.11)
+ polyglot
+ polyglot (>= 0.3.1)
+ tzinfo (0.3.33)
+ uglifier (1.3.0)
+ execjs (>= 0.3.0)
+ multi_json (~> 1.0, >= 1.0.2)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ coffee-rails (~> 3.2.1)
+ jquery-rails
+ rails (= 3.2.8)
+ rails-backbone
+ sass-rails (~> 3.2.3)
+ sqlite3
+ therubyracer
+ uglifier (>= 1.0.3)
View
261 README.rdoc
@@ -0,0 +1,261 @@
+== Welcome to Rails
+
+Rails is a web-application framework that includes everything needed to create
+database-backed web applications according to the Model-View-Control pattern.
+
+This pattern splits the view (also called the presentation) into "dumb"
+templates that are primarily responsible for inserting pre-built data in between
+HTML tags. The model contains the "smart" domain objects (such as Account,
+Product, Person, Post) that holds all the business logic and knows how to
+persist themselves to a database. The controller handles the incoming requests
+(such as Save New Account, Update Product, Show Post) by manipulating the model
+and directing data to the view.
+
+In Rails, the model is handled by what's called an object-relational mapping
+layer entitled Active Record. This layer allows you to present the data from
+database rows as objects and embellish these data objects with business logic
+methods. You can read more about Active Record in
+link:files/vendor/rails/activerecord/README.html.
+
+The controller and view are handled by the Action Pack, which handles both
+layers by its two parts: Action View and Action Controller. These two layers
+are bundled in a single package due to their heavy interdependence. This is
+unlike the relationship between the Active Record and Action Pack that is much
+more separate. Each of these packages can be used independently outside of
+Rails. You can read more about Action Pack in
+link:files/vendor/rails/actionpack/README.html.
+
+
+== Getting Started
+
+1. At the command prompt, create a new Rails application:
+ <tt>rails new myapp</tt> (where <tt>myapp</tt> is the application name)
+
+2. Change directory to <tt>myapp</tt> and start the web server:
+ <tt>cd myapp; rails server</tt> (run with --help for options)
+
+3. Go to http://localhost:3000/ and you'll see:
+ "Welcome aboard: You're riding Ruby on Rails!"
+
+4. Follow the guidelines to start developing your application. You can find
+the following resources handy:
+
+* The Getting Started Guide: http://guides.rubyonrails.org/getting_started.html
+* Ruby on Rails Tutorial Book: http://www.railstutorial.org/
+
+
+== Debugging Rails
+
+Sometimes your application goes wrong. Fortunately there are a lot of tools that
+will help you debug it and get it back on the rails.
+
+First area to check is the application log files. Have "tail -f" commands
+running on the server.log and development.log. Rails will automatically display
+debugging and runtime information to these files. Debugging info will also be
+shown in the browser on requests from 127.0.0.1.
+
+You can also log your own messages directly into the log file from your code
+using the Ruby logger class from inside your controllers. Example:
+
+ class WeblogController < ActionController::Base
+ def destroy
+ @weblog = Weblog.find(params[:id])
+ @weblog.destroy
+ logger.info("#{Time.now} Destroyed Weblog ID ##{@weblog.id}!")
+ end
+ end
+
+The result will be a message in your log file along the lines of:
+
+ Mon Oct 08 14:22:29 +1000 2007 Destroyed Weblog ID #1!
+
+More information on how to use the logger is at http://www.ruby-doc.org/core/
+
+Also, Ruby documentation can be found at http://www.ruby-lang.org/. There are
+several books available online as well:
+
+* Programming Ruby: http://www.ruby-doc.org/docs/ProgrammingRuby/ (Pickaxe)
+* Learn to Program: http://pine.fm/LearnToProgram/ (a beginners guide)
+
+These two books will bring you up to speed on the Ruby language and also on
+programming in general.
+
+
+== Debugger
+
+Debugger support is available through the debugger command when you start your
+Mongrel or WEBrick server with --debugger. This means that you can break out of
+execution at any point in the code, investigate and change the model, and then,
+resume execution! You need to install ruby-debug to run the server in debugging
+mode. With gems, use <tt>sudo gem install ruby-debug</tt>. Example:
+
+ class WeblogController < ActionController::Base
+ def index
+ @posts = Post.all
+ debugger
+ end
+ end
+
+So the controller will accept the action, run the first line, then present you
+with a IRB prompt in the server window. Here you can do things like:
+
+ >> @posts.inspect
+ => "[#<Post:0x14a6be8
+ @attributes={"title"=>nil, "body"=>nil, "id"=>"1"}>,
+ #<Post:0x14a6620
+ @attributes={"title"=>"Rails", "body"=>"Only ten..", "id"=>"2"}>]"
+ >> @posts.first.title = "hello from a debugger"
+ => "hello from a debugger"
+
+...and even better, you can examine how your runtime objects actually work:
+
+ >> f = @posts.first
+ => #<Post:0x13630c4 @attributes={"title"=>nil, "body"=>nil, "id"=>"1"}>
+ >> f.
+ Display all 152 possibilities? (y or n)
+
+Finally, when you're ready to resume execution, you can enter "cont".
+
+
+== Console
+
+The console is a Ruby shell, which allows you to interact with your
+application's domain model. Here you'll have all parts of the application
+configured, just like it is when the application is running. You can inspect
+domain models, change values, and save to the database. Starting the script
+without arguments will launch it in the development environment.
+
+To start the console, run <tt>rails console</tt> from the application
+directory.
+
+Options:
+
+* Passing the <tt>-s, --sandbox</tt> argument will rollback any modifications
+ made to the database.
+* Passing an environment name as an argument will load the corresponding
+ environment. Example: <tt>rails console production</tt>.
+
+To reload your controllers and models after launching the console run
+<tt>reload!</tt>
+
+More information about irb can be found at:
+link:http://www.rubycentral.org/pickaxe/irb.html
+
+
+== dbconsole
+
+You can go to the command line of your database directly through <tt>rails
+dbconsole</tt>. You would be connected to the database with the credentials
+defined in database.yml. Starting the script without arguments will connect you
+to the development database. Passing an argument will connect you to a different
+database, like <tt>rails dbconsole production</tt>. Currently works for MySQL,
+PostgreSQL and SQLite 3.
+
+== Description of Contents
+
+The default directory structure of a generated Ruby on Rails application:
+
+ |-- app
+ | |-- assets
+ | |-- images
+ | |-- javascripts
+ | `-- stylesheets
+ | |-- controllers
+ | |-- helpers
+ | |-- mailers
+ | |-- models
+ | `-- views
+ | `-- layouts
+ |-- config
+ | |-- environments
+ | |-- initializers
+ | `-- locales
+ |-- db
+ |-- doc
+ |-- lib
+ | `-- tasks
+ |-- log
+ |-- public
+ |-- script
+ |-- test
+ | |-- fixtures
+ | |-- functional
+ | |-- integration
+ | |-- performance
+ | `-- unit
+ |-- tmp
+ | |-- cache
+ | |-- pids
+ | |-- sessions
+ | `-- sockets
+ `-- vendor
+ |-- assets
+ `-- stylesheets
+ `-- plugins
+
+app
+ Holds all the code that's specific to this particular application.
+
+app/assets
+ Contains subdirectories for images, stylesheets, and JavaScript files.
+
+app/controllers
+ Holds controllers that should be named like weblogs_controller.rb for
+ automated URL mapping. All controllers should descend from
+ ApplicationController which itself descends from ActionController::Base.
+
+app/models
+ Holds models that should be named like post.rb. Models descend from
+ ActiveRecord::Base by default.
+
+app/views
+ Holds the template files for the view that should be named like
+ weblogs/index.html.erb for the WeblogsController#index action. All views use
+ eRuby syntax by default.
+
+app/views/layouts
+ Holds the template files for layouts to be used with views. This models the
+ common header/footer method of wrapping views. In your views, define a layout
+ using the <tt>layout :default</tt> and create a file named default.html.erb.
+ Inside default.html.erb, call <% yield %> to render the view using this
+ layout.
+
+app/helpers
+ Holds view helpers that should be named like weblogs_helper.rb. These are
+ generated for you automatically when using generators for controllers.
+ Helpers can be used to wrap functionality for your views into methods.
+
+config
+ Configuration files for the Rails environment, the routing map, the database,
+ and other dependencies.
+
+db
+ Contains the database schema in schema.rb. db/migrate contains all the
+ sequence of Migrations for your schema.
+
+doc
+ This directory is where your application documentation will be stored when
+ generated using <tt>rake doc:app</tt>
+
+lib
+ Application specific libraries. Basically, any kind of custom code that
+ doesn't belong under controllers, models, or helpers. This directory is in
+ the load path.
+
+public
+ The directory available for the web server. Also contains the dispatchers and the
+ default HTML files. This should be set as the DOCUMENT_ROOT of your web
+ server.
+
+script
+ Helper scripts for automation and generation.
+
+test
+ Unit and functional tests along with fixtures. When using the rails generate
+ command, template test files will be generated for you and placed in this
+ directory.
+
+vendor
+ External libraries that the application depends on. Also includes the plugins
+ subdirectory. If the app has frozen rails, those gems also go here, under
+ vendor/rails/. This directory is in the load path.
View
7 Rakefile
@@ -0,0 +1,7 @@
+#!/usr/bin/env rake
+# Add your own tasks in files placed in lib/tasks ending in .rake,
+# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
+
+require File.expand_path('../config/application', __FILE__)
+
+TodoApp::Application.load_tasks
View
BIN app/assets/images/bg.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN app/assets/images/rails.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
21 app/assets/javascripts/application.js
@@ -0,0 +1,21 @@
+// This is a manifest file that'll be compiled into application.js, which will include all the files
+// listed below.
+//
+// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
+// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
+//
+// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
+// the compiled file.
+//
+// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
+// GO AFTER THE REQUIRES BELOW.
+//
+//= require jquery
+//= require jquery_ujs
+//= require underscore
+//= require backbone
+//= require backbone_rails_sync
+//= require backbone_datalink
+//= require backbone/todo_app
+//= require_tree .
+
View
2 app/assets/javascripts/backbone/initialize.js.coffee
@@ -0,0 +1,2 @@
+$ ->
+ new App.Views.AppView()
View
0 app/assets/javascripts/backbone/models/.gitkeep
No changes.
View
44 app/assets/javascripts/backbone/models/entry.js.coffee
@@ -0,0 +1,44 @@
+App.Models.Entry = Backbone.Model.extend
+ paramRoot: 'entry'
+
+ defaults:
+ title: null,
+ is_completed: false
+
+ toggle: ()->
+ @save
+ is_completed: !@get('is_completed')
+
+ formatError: (json)->
+ msgs = []
+ _.each json, (errs, attr)->
+ msgs.push "" + attr + ' ' + errs.join(", ")
+ msgs.join("\n")
+
+App.Collections.Entries = Backbone.Collection.extend
+ # Reference to this collection's model.
+ model: App.Models.Entry
+ url: '/entries'
+
+ # Filter down the list of all todo items that are finished.
+ completed: ()->
+ @filter (entry)->
+ entry.get('is_completed')
+
+ # Filter down the list to only todo items that are still not finished.
+ remaining: ()->
+ @without.apply(@, @completed() );
+
+ # We keep the Todos in sequential order, despite being saved by unordered GUID in the database. This generates the next order number for new items.
+ nextOrder: ()->
+ if !@length
+ 1
+ else
+ @last().get('order') + 1
+
+ # Todos are sorted by their original insertion order.
+ comparator: (entry)->
+ entry.get('order')
+
+
+App.Collections.entries = new App.Collections.Entries();
View
0 app/assets/javascripts/backbone/routers/.gitkeep
No changes.
View
14 app/assets/javascripts/backbone/routers/app_router.js.coffee
@@ -0,0 +1,14 @@
+App.Routers.AppRouter = Backbone.Router.extend
+
+ routes:
+ '*filter': 'setFilter'
+
+ setFilter: (param)->
+ # Set the current filter to be used
+ window.App.EntryFilter = param.trim() || ''
+
+ # Trigger a collection filter event, causing hiding/unhiding of Todo view items
+ window.App.Collections.entries.trigger('filter')
+
+App.AppRouter = new App.Routers.AppRouter()
+Backbone.history.start()
View
0 app/assets/javascripts/backbone/templates/.gitkeep
No changes.
View
6 app/assets/javascripts/backbone/templates/item_template.jst.ejs
@@ -0,0 +1,6 @@
+<div class="view">
+ <input class="toggle" type="checkbox" <%= is_completed ? 'checked' : '' %>>
+ <label><%- title %></label>
+ <button class="destroy"></button>
+</div>
+<input class="edit" value="<%- title %>">
View
15 app/assets/javascripts/backbone/templates/stats_template.jst.ejs
@@ -0,0 +1,15 @@
+<span id="todo-count"><strong><%= remaining %></strong> <%= remaining === 1 ? 'item' : 'items' %> left</span>
+<ul id="filters">
+ <li>
+ <a class="selected" href="#/">All</a>
+ </li>
+ <li>
+ <a href="#/active">Active</a>
+ </li>
+ <li>
+ <a href="#/completed">Completed</a>
+ </li>
+</ul>
+<% if (completed) { %>
+<button id="clear-completed">Clear completed (<%= completed %>)</button>
+<% } %>
View
14 app/assets/javascripts/backbone/todo_app.js.coffee
@@ -0,0 +1,14 @@
+#= require_self
+#= require_tree ./templates
+#= require_tree ./models
+#= require_tree ./views
+#= require_tree ./routers
+#= require ./initialize
+
+window.App =
+ Models: {}
+ Collections: {}
+ Routers: {}
+ Views: {}
+ Utils:
+ ENTER_KEY: 13
View
0 app/assets/javascripts/backbone/views/.gitkeep
No changes.
View
100 app/assets/javascripts/backbone/views/app.js.coffee
@@ -0,0 +1,100 @@
+App.Views.AppView = Backbone.View.extend
+ # Instead of generating a new element, bind to the existing skeleton of the App already present in the HTML.
+ el: '#todoapp'
+
+ # Our template for the line of statistics at the bottom of the app.
+ statsTemplate: JST["backbone/templates/stats_template"]
+
+ # Delegated events for creating new items, and clearing completed ones.
+ events:
+ 'keypress #new-todo': 'createOnEnter'
+ 'click #clear-completed': 'clearCompleted'
+ 'click #toggle-all': 'toggleAllComplete'
+
+ # At initialization we bind to the relevant events on the `Todos` collection, when items are added or changed. Kick things off by loading any preexisting todos that might be saved in *localStorage*.
+ initialize: ()->
+ @input = @$('#new-todo')
+ @allCheckbox = @$('#toggle-all')[0]
+ @$footer = @$('#footer')
+ @$main = @$('#main')
+
+ window.App.Collections.entries.on 'add', @addOne, @
+ window.App.Collections.entries.on 'reset', @addAll, @
+ window.App.Collections.entries.on 'change:completed', @filterOne, @
+ window.App.Collections.entries.on "filter", @filterAll, @
+
+ window.App.Collections.entries.on 'all', @render, @
+
+ window.App.Collections.entries.fetch()
+
+ # Re-rendering the App just means refreshing the statistics -- the rest of the app doesn't change.
+ render: ()->
+ completed = App.Collections.entries.completed().length
+ remaining = App.Collections.entries.remaining().length
+
+ if (App.Collections.entries.length)
+ @$main.show()
+ @$footer.show()
+
+ @$footer.html(@statsTemplate({
+ completed: completed,
+ remaining: remaining
+ }))
+
+ @$('#filters li a').removeClass('selected').filter('[href="#/' + ( App.EntryFilter || '' ) + '"]').addClass('selected')
+ else
+ @$main.hide()
+ @$footer.hide()
+
+ @allCheckbox.checked = !remaining
+
+ # Add a single todo item to the list by creating a view for it, and appending its element to the `<ul>`.
+ addOne: (entry)->
+ view = new App.Views.EntriesView({model: entry})
+ $('#todo-list').append view.render().el
+
+ # Add all items in the **Todos** collection at once.
+ addAll: ()->
+ @$('#todo-list').html ''
+ App.Collections.entries.each @addOne, @
+
+ filterOne: (entry)->
+ entry.trigger("visible")
+
+ filterAll: ()->
+ App.Collections.entries.each @filterOne, @
+
+ # Generate the attributes for a new Todo item.
+ newAttributes: ()->
+ ret =
+ title: @input.val().trim()
+ order: App.Collections.entries.nextOrder()
+ is_completed: false
+
+ # If you hit return in the main input field, create new **Todo** model, persisting it to *localStorage*.
+ createOnEnter: (e)->
+ if e.which != App.Utils.ENTER_KEY# || !@input.val().trim()
+ return null
+
+ App.Collections.entries.create @newAttributes(),
+ wait: true
+ error: (model, response)->
+ json = $.parseJSON(response.responseText)
+ error = model.formatError(json)
+ alert(error)
+
+ @input.val('')
+
+
+ # Clear all completed todo items, destroying their models.
+ clearCompleted: ()->
+ _.each window.App.Collections.entries.completed(), (entry)->
+ entry.destroy()
+
+ false
+
+ toggleAllComplete: ()->
+ completed = @allCheckbox.checked
+
+ App.Collections.entries.each (entry)->
+ entry.save({'completed': completed})
View
66 app/assets/javascripts/backbone/views/entries.js.coffee
@@ -0,0 +1,66 @@
+App.Views.EntriesView = Backbone.View.extend
+
+#... is a list tag.
+ tagName: 'li'
+
+ # Cache the template function for a single item.
+ template: JST["backbone/templates/item_template"]
+
+ # The DOM events specific to an item.
+ events:
+ 'click .toggle': 'togglecompleted'
+ 'dblclick label': 'edit'
+ 'click .destroy': 'clear'
+ 'keypress .edit': 'updateOnEnter'
+ 'blur .edit': 'close'
+
+ # The TodoView listens for changes to its model, re-rendering. Since there's a one-to-one correspondence between a **Todo** and a **TodoView** in this app, we set a direct reference on the model for convenience.
+ initialize: ()->
+ @model.on 'change', @render, @
+ @model.on 'destroy', @remove, @
+ @model.on 'visible', @toggleVisible, @
+
+ # Re-render the titles of the todo item.
+ render: ()->
+ @$el.html(@template(@model.toJSON()))
+ @$el.toggleClass('completed', @model.get('is_completed'))
+
+ @toggleVisible()
+ @input = @$('.edit')
+ @
+
+ toggleVisible: ()->
+ @$el.toggleClass('hidden', @isHidden())
+
+ isHidden: ()->
+ isCompleted = @model.get('is_completed')
+ (!isCompleted && App.EntryFilter == 'completed') || (isCompleted && App.EntryFilter == 'active')
+
+ # Toggle the `"completed"` state of the model.
+ togglecompleted: ()->
+ @model.toggle()
+
+ # Switch this view into `"editing"` mode, displaying the input field.
+ edit: ()->
+ @$el.addClass('editing')
+ @input.focus()
+
+ # Close the `"editing"` mode, saving changes to the todo.
+ close: ()->
+ value = @input.val().trim()
+
+ if value
+ @model.save({title: value})
+ else
+ @clear()
+
+ @$el.removeClass('editing')
+
+ # If you hit `enter`, we're through editing the item.
+ updateOnEnter: (e)->
+ if e.which == App.Utils.ENTER_KEY
+ @close()
+
+ # Remove the item, destroy the model from *localStorage* and delete its view.
+ clear: ()->
+ @model.destroy()
View
3 app/assets/javascripts/entries.js.coffee
@@ -0,0 +1,3 @@
+# Place all the behaviors and hooks related to the matching controller here.
+# All this logic will automatically be available in application.js.
+# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
View
13 app/assets/stylesheets/application.css
@@ -0,0 +1,13 @@
+/*
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
+ * listed below.
+ *
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
+ *
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
+ * compiled file, but it's generally better to create a new file per style scope.
+ *
+ *= require_self
+ *= require_tree .
+ */
View
410 app/assets/stylesheets/base.css
@@ -0,0 +1,410 @@
+html,
+body {
+ margin: 0;
+ padding: 0;
+}
+
+button {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ background: none;
+ font-size: 100%;
+ vertical-align: baseline;
+ font-family: inherit;
+ color: inherit;
+ -webkit-appearance: none;
+ /*-moz-appearance: none;*/
+ -ms-appearance: none;
+ -o-appearance: none;
+ appearance: none;
+}
+
+body {
+ font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
+ line-height: 1.4em;
+ background: #eaeaea url('bg.png');
+ color: #4d4d4d;
+ width: 550px;
+ margin: 0 auto;
+ -webkit-font-smoothing: antialiased;
+ -moz-font-smoothing: antialiased;
+ -ms-font-smoothing: antialiased;
+ -o-font-smoothing: antialiased;
+ font-smoothing: antialiased;
+}
+
+#todoapp {
+ background: #fff;
+ background: rgba(255, 255, 255, 0.9);
+ margin: 130px 0 40px 0;
+ border: 1px solid #ccc;
+ position: relative;
+ border-top-left-radius: 2px;
+ border-top-right-radius: 2px;
+ box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.2),
+ 0 25px 50px 0 rgba(0, 0, 0, 0.15);
+}
+
+#todoapp:before {
+ content: '';
+ border-left: 1px solid #f5d6d6;
+ border-right: 1px solid #f5d6d6;
+ width: 2px;
+ position: absolute;
+ top: 0;
+ left: 40px;
+ height: 100%;
+}
+
+#todoapp input::-webkit-input-placeholder {
+ font-style: italic;
+}
+
+#todoapp input:-moz-placeholder {
+ font-style: italic;
+ color: #a9a9a9;
+}
+
+#todoapp h1 {
+ position: absolute;
+ top: -120px;
+ width: 100%;
+ font-size: 70px;
+ font-weight: bold;
+ text-align: center;
+ color: #b3b3b3;
+ color: rgba(255, 255, 255, 0.3);
+ text-shadow: -1px -1px rgba(0, 0, 0, 0.2);
+ -webkit-text-rendering: optimizeLegibility;
+ -moz-text-rendering: optimizeLegibility;
+ -ms-text-rendering: optimizeLegibility;
+ -o-text-rendering: optimizeLegibility;
+ text-rendering: optimizeLegibility;
+}
+
+#header {
+ padding-top: 15px;
+ border-radius: inherit;
+}
+
+#header:before {
+ content: '';
+ position: absolute;
+ top: 0;
+ right: 0;
+ left: 0;
+ height: 15px;
+ z-index: 2;
+ border-bottom: 1px solid #6c615c;
+ background: #8d7d77;
+ background: -webkit-gradient(linear, left top, left bottom, from(rgba(132, 110, 100, 0.8)),to(rgba(101, 84, 76, 0.8)));
+ background: -webkit-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
+ background: -moz-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
+ background: -o-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
+ background: -ms-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
+ background: linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
+ filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#9d8b83', EndColorStr='#847670');
+ border-top-left-radius: 1px;
+ border-top-right-radius: 1px;
+}
+
+#new-todo,
+.edit {
+ position: relative;
+ margin: 0;
+ width: 100%;
+ font-size: 24px;
+ font-family: inherit;
+ line-height: 1.4em;
+ border: 0;
+ outline: none;
+ color: inherit;
+ padding: 6px;
+ border: 1px solid #999;
+ box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -ms-box-sizing: border-box;
+ -o-box-sizing: border-box;
+ box-sizing: border-box;
+ -webkit-font-smoothing: antialiased;
+ -moz-font-smoothing: antialiased;
+ -ms-font-smoothing: antialiased;
+ -o-font-smoothing: antialiased;
+ font-smoothing: antialiased;
+}
+
+#new-todo {
+ padding: 16px 16px 16px 60px;
+ border: none;
+ background: rgba(0, 0, 0, 0.02);
+ z-index: 2;
+ box-shadow: none;
+}
+
+#main {
+ position: relative;
+ z-index: 2;
+ border-top: 1px dotted #adadad;
+}
+
+label[for='toggle-all'] {
+ display: none;
+}
+
+#toggle-all {
+ position: absolute;
+ top: -56px;
+ left: -15px;
+ width: 65px;
+ height: 41px;
+ text-align: center;
+ border: none; /* Mobile Safari */
+ -webkit-appearance: none;
+ /*-moz-appearance: none;*/
+ -ms-appearance: none;
+ -o-appearance: none;
+ appearance: none;
+ -webkit-transform: rotate(90deg);
+ /*-moz-transform: rotate(90deg);*/
+ -ms-transform: rotate(90deg);
+ /*-o-transform: rotate(90deg);*/
+ transform: rotate(90deg);
+}
+
+#toggle-all:before {
+ content: '»';
+ font-size: 28px;
+ color: #d9d9d9;
+ padding: 0 25px 7px;
+}
+
+#toggle-all:checked:before {
+ color: #737373;
+}
+
+#todo-list {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+}
+
+#todo-list li {
+ position: relative;
+ font-size: 24px;
+ border-bottom: 1px dotted #ccc;
+}
+
+#todo-list li:last-child {
+ border-bottom: none;
+}
+
+#todo-list li.editing {
+ border-bottom: none;
+ padding: 0;
+}
+
+#todo-list li.editing .edit {
+ display: block;
+ width: 506px;
+ padding: 13px 17px 12px 17px;
+ margin: 0 0 0 43px;
+}
+
+#todo-list li.editing .view {
+ display: none;
+}
+
+#todo-list li .toggle {
+ text-align: center;
+ width: 40px;
+ height: 40px;
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ margin: auto 0;
+ border: none; /* Mobile Safari */
+ -webkit-appearance: none;
+ /*-moz-appearance: none;*/
+ -ms-appearance: none;
+ -o-appearance: none;
+ appearance: none;
+}
+
+#todo-list li .toggle:after {
+ font-size: 18px;
+ content: '';
+ line-height: 43px; /* 40 + a couple of pixels visual adjustment */
+ font-size: 20px;
+ color: #d9d9d9;
+ text-shadow: 0 -1px 0 #bfbfbf;
+}
+
+#todo-list li .toggle:checked:after {
+ color: #85ada7;
+ text-shadow: 0 1px 0 #669991;
+ bottom: 1px;
+ position: relative;
+}
+
+#todo-list li label {
+ word-break: break-word;
+ padding: 15px;
+ margin-left: 45px;
+ display: block;
+ line-height: 1.2;
+ -webkit-transition: color 0.4s;
+ -moz-transition: color 0.4s;
+ -ms-transition: color 0.4s;
+ -o-transition: color 0.4s;
+ transition: color 0.4s;
+}
+
+#todo-list li.completed label {
+ color: #a9a9a9;
+ text-decoration: line-through;
+}
+
+#todo-list li .destroy {
+ display: none;
+ position: absolute;
+ top: 0;
+ right: 10px;
+ bottom: 0;
+ width: 40px;
+ height: 40px;
+ margin: auto 0;
+ font-size: 22px;
+ color: #a88a8a;
+ -webkit-transition: all 0.2s;
+ -moz-transition: all 0.2s;
+ -ms-transition: all 0.2s;
+ -o-transition: all 0.2s;
+ transition: all 0.2s;
+}
+
+#todo-list li .destroy:hover {
+ text-shadow: 0 0 1px #000,
+ 0 0 10px rgba(199, 107, 107, 0.8);
+ -webkit-transform: scale(1.3);
+ -moz-transform: scale(1.3);
+ -ms-transform: scale(1.3);
+ -o-transform: scale(1.3);
+ transform: scale(1.3);
+}
+
+#todo-list li .destroy:after {
+ content: '';
+}
+
+#todo-list li:hover .destroy {
+ display: block;
+}
+
+#todo-list li .edit {
+ display: none;
+}
+
+#todo-list li.editing:last-child {
+ margin-bottom: -1px;
+}
+
+#footer {
+ color: #777;
+ padding: 0 15px;
+ position: absolute;
+ right: 0;
+ bottom: -31px;
+ left: 0;
+ height: 20px;
+ z-index: 1;
+ text-align: center;
+}
+
+#footer:before {
+ content: '';
+ position: absolute;
+ right: 0;
+ bottom: 31px;
+ left: 0;
+ height: 50px;
+ z-index: -1;
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.3),
+ 0 6px 0 -3px rgba(255, 255, 255, 0.8),
+ 0 7px 1px -3px rgba(0, 0, 0, 0.3),
+ 0 43px 0 -6px rgba(255, 255, 255, 0.8),
+ 0 44px 2px -6px rgba(0, 0, 0, 0.2);
+}
+
+#todo-count {
+ float: left;
+ text-align: left;
+}
+
+#filters {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+ position: absolute;
+ right: 0;
+ left: 0;
+}
+
+#filters li {
+ display: inline;
+}
+
+#filters li a {
+ color: #83756f;
+ margin: 2px;
+ text-decoration: none;
+}
+
+#filters li a.selected {
+ font-weight: bold;
+}
+
+#clear-completed {
+ float: right;
+ position: relative;
+ line-height: 20px;
+ text-decoration: none;
+ background: rgba(0, 0, 0, 0.1);
+ font-size: 11px;
+ padding: 0 10px;
+ border-radius: 3px;
+ box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.2);
+}
+
+#clear-completed:hover {
+ background: rgba(0, 0, 0, 0.15);
+ box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.3);
+}
+
+#info {
+ margin: 65px auto 0;
+ color: #a6a6a6;
+ font-size: 12px;
+ text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);
+ text-align: center;
+}
+
+#info a {
+ color: inherit;
+}
+
+/*
+ Hack to remove background from Mobile Safari.
+ Can't use it globally since it destroys checkboxes in Firefox and Opera
+*/
+@media screen and (-webkit-min-device-pixel-ratio:0) {
+ #toggle-all,
+ #todo-list li .toggle {
+ background: none;
+ }
+}
+
+.hidden{
+ display:none;
+}
View
3 app/assets/stylesheets/entries.css.scss
@@ -0,0 +1,3 @@
+// Place all the styles related to the Entries controller here.
+// They will automatically be included in application.css.
+// You can use Sass (SCSS) here: http://sass-lang.com/
View
69 app/assets/stylesheets/scaffolds.css.scss
@@ -0,0 +1,69 @@
+body {
+ background-color: #fff;
+ color: #333;
+ font-family: verdana, arial, helvetica, sans-serif;
+ font-size: 13px;
+ line-height: 18px;
+}
+
+p, ol, ul, td {
+ font-family: verdana, arial, helvetica, sans-serif;
+ font-size: 13px;
+ line-height: 18px;
+}
+
+pre {
+ background-color: #eee;
+ padding: 10px;
+ font-size: 11px;
+}
+
+a {
+ color: #000;
+ &:visited {
+ color: #666;
+ }
+ &:hover {
+ color: #fff;
+ background-color: #000;
+ }
+}
+
+div {
+ &.field, &.actions {
+ margin-bottom: 10px;
+ }
+}
+
+#notice {
+ color: green;
+}
+
+.field_with_errors {
+ padding: 2px;
+ background-color: red;
+ display: table;
+}
+
+#error_explanation {
+ width: 450px;
+ border: 2px solid red;
+ padding: 7px;
+ padding-bottom: 0;
+ margin-bottom: 20px;
+ background-color: #f0f0f0;
+ h2 {
+ text-align: left;
+ font-weight: bold;
+ padding: 5px 5px 5px 15px;
+ font-size: 12px;
+ margin: -7px;
+ margin-bottom: 0px;
+ background-color: #c00;
+ color: #fff;
+ }
+ ul li {
+ font-size: 12px;
+ list-style: square;
+ }
+}
View
3 app/controllers/application_controller.rb
@@ -0,0 +1,3 @@
+class ApplicationController < ActionController::Base
+ protect_from_forgery
+end
View
90 app/controllers/entries_controller.rb
@@ -0,0 +1,90 @@
+class EntriesController < ApplicationController
+ # GET /entries
+ # GET /entries.json
+ def index
+ @entries = Entry.all
+
+ respond_to do |format|
+ format.html # index.html.erb
+ format.json { render json: @entries }
+ end
+ end
+
+ # GET /entries/1
+ # GET /entries/1.json
+ def show
+ @entry = Entry.find(params[:id])
+
+ respond_to do |format|
+ format.html # show.html.erb
+ format.json { render json: @entry }
+ end
+ end
+
+ # GET /entries/new
+ # GET /entries/new.json
+ def new
+ @entry = Entry.new
+
+ respond_to do |format|
+ format.html # new.html.erb
+ format.json { render json: @entry }
+ end
+ end
+
+ # GET /entries/1/edit
+ def edit
+ @entry = Entry.find(params[:id])
+ end
+
+ # POST /entries
+ # POST /entries.json
+ def create
+ @entry = Entry.new(params[:entry])
+
+ respond_to do |format|
+ if @entry.save
+ format.html { redirect_to @entry, notice: 'Entry was successfully created.' }
+ format.json { render json: @entry, status: :created, location: @entry }
+ else
+ format.html { render action: "new" }
+ format.json { render json: @entry.errors, status: :unprocessable_entity }
+ end
+ end
+ end
+
+ # PUT /entries/1
+ # PUT /entries/1.json
+ def update
+ @entry = Entry.find(params[:id])
+
+ respond_to do |format|
+ if @entry.update_attributes(process_backbone_parameters(params[:entry]))
+ format.html { redirect_to @entry, notice: 'Entry was successfully updated.' }
+ format.json { head :no_content }
+ else
+ format.html { render action: "edit" }
+ format.json { render json: @entry.errors, status: :unprocessable_entity }
+ end
+ end
+ end
+
+ # DELETE /entries/1
+ # DELETE /entries/1.json
+ def destroy
+ @entry = Entry.find(params[:id])
+ @entry.destroy
+
+ respond_to do |format|
+ format.html { redirect_to entries_url }
+ format.json { head :no_content }
+ end
+ end
+
+ private
+
+ def process_backbone_parameters(params)
+ return params unless params.is_a?(Hash)
+ params.except('id', 'updated_at', 'created_at')
+ end
+end
View
4 app/controllers/home_controller.rb
@@ -0,0 +1,4 @@
+class HomeController < ApplicationController
+ def index
+ end
+end
View
2 app/helpers/application_helper.rb
@@ -0,0 +1,2 @@
+module ApplicationHelper
+end
View
2 app/helpers/entries_helper.rb
@@ -0,0 +1,2 @@
+module EntriesHelper
+end
View
2 app/helpers/home_helper.rb
@@ -0,0 +1,2 @@
+module HomeHelper
+end
View
0 app/mailers/.gitkeep
No changes.
View
0 app/models/.gitkeep
No changes.
View
5 app/models/entry.rb
@@ -0,0 +1,5 @@
+class Entry < ActiveRecord::Base
+ attr_accessible :is_completed, :title, :order
+
+ validates :title, :presence => true
+end
View
25 app/views/entries/_form.html.erb
@@ -0,0 +1,25 @@
+<%= form_for(@entry) do |f| %>
+ <% if @entry.errors.any? %>
+ <div id="error_explanation">
+ <h2><%= pluralize(@entry.errors.count, "error") %> prohibited this entry from being saved:</h2>
+
+ <ul>
+ <% @entry.errors.full_messages.each do |msg| %>
+ <li><%= msg %></li>
+ <% end %>
+ </ul>
+ </div>
+ <% end %>
+
+ <div class="field">
+ <%= f.label :title %><br />
+ <%= f.text_field :title %>
+ </div>
+ <div class="field">
+ <%= f.label :is_completed %><br />
+ <%= f.check_box :is_completed %>
+ </div>
+ <div class="actions">
+ <%= f.submit %>
+ </div>
+<% end %>
View
6 app/views/entries/edit.html.erb
@@ -0,0 +1,6 @@
+<h1>Editing entry</h1>
+
+<%= render 'form' %>
+
+<%= link_to 'Show', @entry %> |
+<%= link_to 'Back', entries_path %>
View
25 app/views/entries/index.html.erb
@@ -0,0 +1,25 @@
+<h1>Listing entries</h1>
+
+<table>
+ <tr>
+ <th>Title</th>
+ <th>Is completed</th>
+ <th></th>
+ <th></th>
+ <th></th>
+ </tr>
+
+<% @entries.each do |entry| %>
+ <tr>
+ <td><%= entry.title %></td>
+ <td><%= entry.is_completed %></td>
+ <td><%= link_to 'Show', entry %></td>
+ <td><%= link_to 'Edit', edit_entry_path(entry) %></td>
+ <td><%= link_to 'Destroy', entry, method: :delete, data: { confirm: 'Are you sure?' } %></td>
+ </tr>
+<% end %>
+</table>
+
+<br />
+
+<%= link_to 'New Entry', new_entry_path %>
View
5 app/views/entries/new.html.erb
@@ -0,0 +1,5 @@
+<h1>New entry</h1>
+
+<%= render 'form' %>
+
+<%= link_to 'Back', entries_path %>
View
15 app/views/entries/show.html.erb
@@ -0,0 +1,15 @@
+<p id="notice"><%= notice %></p>
+
+<p>
+ <b>Title:</b>
+ <%= @entry.title %>
+</p>
+
+<p>
+ <b>Is completed:</b>
+ <%= @entry.is_completed %>
+</p>
+
+
+<%= link_to 'Edit', edit_entry_path(@entry) %> |
+<%= link_to 'Back', entries_path %>
View
19 app/views/home/index.html.erb
@@ -0,0 +1,19 @@
+<section id="todoapp">
+ <header id="header">
+ <h1>todos</h1>
+ <input id="new-todo" placeholder="What needs to be done?" autofocus>
+ </header>
+ <section id="main">
+ <input id="toggle-all" type="checkbox">
+ <label for="toggle-all">Mark all as complete</label>
+ <ul id="todo-list"></ul>
+ </section>
+ <footer id="footer"></footer>
+</section>
+<div id="info">
+ <p>Double-click to edit a todo</p>
+
+ <p>Written by <a href="https://github.com/addyosmani">Addy Osmani</a></p>
+
+ <p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
+</div>
View
14 app/views/layouts/application.html.erb
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>TodoApp</title>
+ <%= stylesheet_link_tag "application", :media => "all" %>
+ <%= javascript_include_tag "application" %>
+ <%= csrf_meta_tags %>
+</head>
+<body>
+
+<%= yield %>
+
+</body>
+</html>
View
4 config.ru
@@ -0,0 +1,4 @@
+# This file is used by Rack-based servers to start the application.
+
+require ::File.expand_path('../config/environment', __FILE__)
+run TodoApp::Application
View
68 config/application.rb
@@ -0,0 +1,68 @@
+require File.expand_path('../boot', __FILE__)
+
+# Pick the frameworks you want:
+require "active_record/railtie"
+require "action_controller/railtie"
+require "action_mailer/railtie"
+require "active_resource/railtie"
+require "sprockets/railtie"
+# require "rails/test_unit/railtie"
+
+if defined?(Bundler)
+ # If you precompile assets before deploying to production, use this line
+ Bundler.require(*Rails.groups(:assets => %w(development test)))
+ # If you want your assets lazily compiled in production, use this line
+ # Bundler.require(:default, :assets, Rails.env)
+end
+
+module TodoApp
+ class Application < Rails::Application
+ # Settings in config/environments/* take precedence over those specified here.
+ # Application configuration should go into files in config/initializers
+ # -- all .rb files in that directory are automatically loaded.
+
+ # Custom directories with classes and modules you want to be autoloadable.
+ # config.autoload_paths += %W(#{config.root}/extras)
+
+ # Only load the plugins named here, in the order given (default is alphabetical).
+ # :all can be used as a placeholder for all plugins not explicitly named.
+ # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
+
+ # Activate observers that should always be running.
+ # config.active_record.observers = :cacher, :garbage_collector, :forum_observer
+
+ # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
+ # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
+ # config.time_zone = 'Central Time (US & Canada)'
+
+ # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
+ # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
+ # config.i18n.default_locale = :de
+
+ # Configure the default encoding used in templates for Ruby 1.9.
+ config.encoding = "utf-8"
+
+ # Configure sensitive parameters which will be filtered from the log file.
+ config.filter_parameters += [:password]
+
+ # Enable escaping HTML in JSON.
+ config.active_support.escape_html_entities_in_json = true
+
+ # Use SQL instead of Active Record's schema dumper when creating the database.
+ # This is necessary if your schema can't be completely dumped by the schema dumper,
+ # like if you have constraints or database-specific column types
+ # config.active_record.schema_format = :sql
+
+ # Enforce whitelist mode for mass assignment.
+ # This will create an empty whitelist of attributes available for mass-assignment for all models
+ # in your app. As such, your models will need to explicitly whitelist or blacklist accessible
+ # parameters by using an attr_accessible or attr_protected declaration.
+ config.active_record.whitelist_attributes = true
+
+ # Enable the asset pipeline
+ config.assets.enabled = true
+
+ # Version of your assets, change this if you want to expire all your assets
+ config.assets.version = '1.0'
+ end
+end
View
6 config/boot.rb
@@ -0,0 +1,6 @@
+require 'rubygems'
+
+# Set up gems listed in the Gemfile.
+ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
+
+require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
View
25 config/database.yml
@@ -0,0 +1,25 @@
+# SQLite version 3.x
+# gem install sqlite3
+#
+# Ensure the SQLite 3 gem is defined in your Gemfile
+# gem 'sqlite3'
+development:
+ adapter: sqlite3
+ database: db/development.sqlite3
+ pool: 5
+ timeout: 5000
+
+# Warning: The database defined as "test" will be erased and
+# re-generated from your development database when you run "rake".
+# Do not set this db to the same as development or production.
+test:
+ adapter: sqlite3
+ database: db/test.sqlite3
+ pool: 5
+ timeout: 5000
+
+production:
+ adapter: sqlite3
+ database: db/production.sqlite3
+ pool: 5
+ timeout: 5000
View
5 config/environment.rb
@@ -0,0 +1,5 @@
+# Load the rails application
+require File.expand_path('../application', __FILE__)
+
+# Initialize the rails application
+TodoApp::Application.initialize!
View
37 config/environments/development.rb
@@ -0,0 +1,37 @@
+TodoApp::Application.configure do
+ # Settings specified here will take precedence over those in config/application.rb
+
+ # In the development environment your application's code is reloaded on
+ # every request. This slows down response time but is perfect for development
+ # since you don't have to restart the web server when you make code changes.
+ config.cache_classes = false
+
+ # Log error messages when you accidentally call methods on nil.
+ config.whiny_nils = true
+
+ # Show full error reports and disable caching
+ config.consider_all_requests_local = true
+ config.action_controller.perform_caching = false
+
+ # Don't care if the mailer can't send
+ config.action_mailer.raise_delivery_errors = false
+
+ # Print deprecation notices to the Rails logger
+ config.active_support.deprecation = :log
+
+ # Only use best-standards-support built into browsers
+ config.action_dispatch.best_standards_support = :builtin
+
+ # Raise exception on mass assignment protection for Active Record models
+ config.active_record.mass_assignment_sanitizer = :strict
+
+ # Log the query plan for queries taking more than this (works
+ # with SQLite, MySQL, and PostgreSQL)
+ config.active_record.auto_explain_threshold_in_seconds = 0.5
+
+ # Do not compress assets
+ config.assets.compress = false
+
+ # Expands the lines which load the assets
+ config.assets.debug = true
+end
View
67 config/environments/production.rb
@@ -0,0 +1,67 @@
+TodoApp::Application.configure do
+ # Settings specified here will take precedence over those in config/application.rb
+
+ # Code is not reloaded between requests
+ config.cache_classes = true
+
+ # Full error reports are disabled and caching is turned on
+ config.consider_all_requests_local = false
+ config.action_controller.perform_caching = true
+
+ # Disable Rails's static asset server (Apache or nginx will already do this)
+ config.serve_static_assets = false
+
+ # Compress JavaScripts and CSS
+ config.assets.compress = true
+
+ # Don't fallback to assets pipeline if a precompiled asset is missed
+ config.assets.compile = false
+
+ # Generate digests for assets URLs
+ config.assets.digest = true
+
+ # Defaults to nil and saved in location specified by config.assets.prefix
+ # config.assets.manifest = YOUR_PATH
+
+ # Specifies the header that your server uses for sending files
+ # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
+ # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
+
+ # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
+ # config.force_ssl = true
+
+ # See everything in the log (default is :info)
+ # config.log_level = :debug
+
+ # Prepend all log lines with the following tags
+ # config.log_tags = [ :subdomain, :uuid ]
+
+ # Use a different logger for distributed setups
+ # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)
+
+ # Use a different cache store in production
+ # config.cache_store = :mem_cache_store
+
+ # Enable serving of images, stylesheets, and JavaScripts from an asset server
+ # config.action_controller.asset_host = "http://assets.example.com"
+
+ # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
+ # config.assets.precompile += %w( search.js )
+
+ # Disable delivery errors, bad email addresses will be ignored
+ # config.action_mailer.raise_delivery_errors = false
+
+ # Enable threaded mode
+ # config.threadsafe!
+
+ # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
+ # the I18n.default_locale when a translation can not be found)
+ config.i18n.fallbacks = true
+
+ # Send deprecation notices to registered listeners
+ config.active_support.deprecation = :notify
+
+ # Log the query plan for queries taking more than this (works
+ # with SQLite, MySQL, and PostgreSQL)
+ # config.active_record.auto_explain_threshold_in_seconds = 0.5
+end
View
37 config/environments/test.rb
@@ -0,0 +1,37 @@
+TodoApp::Application.configure do
+ # Settings specified here will take precedence over those in config/application.rb
+
+ # The test environment is used exclusively to run your application's
+ # test suite. You never need to work with it otherwise. Remember that
+ # your test database is "scratch space" for the test suite and is wiped
+ # and recreated between test runs. Don't rely on the data there!
+ config.cache_classes = true
+
+ # Configure static asset server for tests with Cache-Control for performance
+ config.serve_static_assets = true
+ config.static_cache_control = "public, max-age=3600"
+
+ # Log error messages when you accidentally call methods on nil
+ config.whiny_nils = true
+
+ # Show full error reports and disable caching
+ config.consider_all_requests_local = true
+ config.action_controller.perform_caching = false
+
+ # Raise exceptions instead of rendering exception templates
+ config.action_dispatch.show_exceptions = false
+
+ # Disable request forgery protection in test environment
+ config.action_controller.allow_forgery_protection = false
+
+ # Tell Action Mailer not to deliver emails to the real world.
+ # The :test delivery method accumulates sent emails in the
+ # ActionMailer::Base.deliveries array.
+ config.action_mailer.delivery_method = :test
+
+ # Raise exception on mass assignment protection for Active Record models
+ config.active_record.mass_assignment_sanitizer = :strict
+
+ # Print deprecation notices to the stderr
+ config.active_support.deprecation = :stderr
+end
View
7 config/initializers/backtrace_silencers.rb
@@ -0,0 +1,7 @@
+# Be sure to restart your server when you modify this file.
+
+# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
+# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
+
+# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
+# Rails.backtrace_cleaner.remove_silencers!
View
15 config/initializers/inflections.rb
@@ -0,0 +1,15 @@
+# Be sure to restart your server when you modify this file.
+
+# Add new inflection rules using the following format
+# (all these examples are active by default):
+# ActiveSupport::Inflector.inflections do |inflect|
+# inflect.plural /^(ox)$/i, '\1en'
+# inflect.singular /^(ox)en/i, '\1'
+# inflect.irregular 'person', 'people'
+# inflect.uncountable %w( fish sheep )
+# end
+#
+# These inflection rules are supported but not enabled by default:
+# ActiveSupport::Inflector.inflections do |inflect|
+# inflect.acronym 'RESTful'
+# end
View
5 config/initializers/mime_types.rb
@@ -0,0 +1,5 @@
+# Be sure to restart your server when you modify this file.
+
+# Add new mime types for use in respond_to blocks:
+# Mime::Type.register "text/richtext", :rtf
+# Mime::Type.register_alias "text/html", :iphone
View
7 config/initializers/secret_token.rb
@@ -0,0 +1,7 @@
+# Be sure to restart your server when you modify this file.
+
+# Your secret key for verifying the integrity of signed cookies.
+# If you change this key, all old signed cookies will become invalid!
+# Make sure the secret is at least 30 characters and all random,
+# no regular words or you'll be exposed to dictionary attacks.
+TodoApp::Application.config.secret_token = 'e1e5c016d7a7479b281bd199058a2b7adca41b3e88e9c4de5cf56c69d9d3a1da985bb16d6a75987a2fd57febe0140605829364f383a29af87fe8b8f45a7bc833'
View
8 config/initializers/session_store.rb
@@ -0,0 +1,8 @@
+# Be sure to restart your server when you modify this file.
+
+TodoApp::Application.config.session_store :cookie_store, :key => '_todo-app_session'
+
+# Use the database for sessions instead of the cookie-based default,
+# which shouldn't be used to store highly confidential information
+# (create the session table with "rails generate session_migration")
+# TodoApp::Application.config.session_store :active_record_store
View
14 config/initializers/wrap_parameters.rb
@@ -0,0 +1,14 @@
+# Be sure to restart your server when you modify this file.
+#
+# This file contains settings for ActionController::ParamsWrapper which
+# is enabled by default.
+
+# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
+ActiveSupport.on_load(:action_controller) do
+ wrap_parameters :format => [:json]
+end
+
+# Disable root element in JSON by default.
+ActiveSupport.on_load(:active_record) do
+ self.include_root_in_json = false
+end
View
5 config/locales/en.yml
@@ -0,0 +1,5 @@
+# Sample localization file for English. Add more files in this directory for other locales.
+# See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
+
+en:
+ hello: "Hello world"
View
64 config/routes.rb
@@ -0,0 +1,64 @@
+TodoApp::Application.routes.draw do
+ resources :entries
+
+ get "home/index"
+
+ root :to => 'home#index'
+
+ # The priority is based upon order of creation:
+ # first created -> highest priority.
+
+ # Sample of regular route:
+ # match 'products/:id' => 'catalog#view'
+ # Keep in mind you can assign values other than :controller and :action
+
+ # Sample of named route:
+ # match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
+ # This route can be invoked with purchase_url(:id => product.id)
+
+ # Sample resource route (maps HTTP verbs to controller actions automatically):
+ # resources :products
+
+ # Sample resource route with options:
+ # resources :products do
+ # member do
+ # get 'short'
+ # post 'toggle'
+ # end
+ #
+ # collection do
+ # get 'sold'
+ # end
+ # end
+
+ # Sample resource route with sub-resources:
+ # resources :products do
+ # resources :comments, :sales
+ # resource :seller
+ # end
+
+ # Sample resource route with more complex sub-resources
+ # resources :products do
+ # resources :comments
+ # resources :sales do
+ # get 'recent', :on => :collection
+ # end
+ # end
+
+ # Sample resource route within a namespace:
+ # namespace :admin do
+ # # Directs /admin/products/* to Admin::ProductsController
+ # # (app/controllers/admin/products_controller.rb)
+ # resources :products
+ # end
+
+ # You can have the root of your site routed with "root"
+ # just remember to delete public/index.html.
+ # root :to => 'welcome#index'
+
+ # See how all your routes lay out with "rake routes"
+
+ # This is a legacy wild controller route that's not recommended for RESTful applications.
+ # Note: This route will make all actions in every controller accessible via GET requests.
+ # match ':controller(/:action(/:id))(.:format)'
+end
View
11 db/migrate/20121012183502_create_entries.rb
@@ -0,0 +1,11 @@
+class CreateEntries < ActiveRecord::Migration
+ def change
+ create_table :entries do |t|
+ t.string :title
+ t.boolean :is_completed
+ t.integer :order
+
+ t.timestamps
+ end
+ end
+end
View
24 db/schema.rb
@@ -0,0 +1,24 @@
+# encoding: UTF-8
+# This file is auto-generated from the current state of the database. Instead
+# of editing this file, please use the migrations feature of Active Record to
+# incrementally modify your database, and then regenerate this schema definition.
+#
+# Note that this schema.rb definition is the authoritative source for your
+# database schema. If you need to create the application database on another
+# system, you should be using db:schema:load, not running all the migrations
+# from scratch. The latter is a flawed and unsustainable approach (the more migrations
+# you'll amass, the slower it'll run and the greater likelihood for issues).
+#
+# It's strongly recommended to check this file into your version control system.
+
+ActiveRecord::Schema.define(:version => 20121012183502) do
+
+ create_table "entries", :force => true do |t|
+ t.string "title"
+ t.boolean "is_completed"
+ t.integer "order"
+ t.datetime "created_at", :null => false
+ t.datetime "updated_at", :null => false
+ end
+
+end
View
7 db/seeds.rb
@@ -0,0 +1,7 @@
+# This file should contain all the record creation needed to seed the database with its default values.
+# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
+#
+# Examples:
+#
+# cities = City.create([{ :name => 'Chicago' }, { :name => 'Copenhagen' }])
+# Mayor.create(:name => 'Emanuel', :city => cities.first)
View
2 doc/README_FOR_APP
@@ -0,0 +1,2 @@
+Use this README file to introduce your application and point to useful places in the API for learning more.
+Run "rake doc:app" to generate API documentation for your models, controllers, helpers, and libraries.
View
0 lib/assets/.gitkeep
No changes.
View
0 lib/tasks/.gitkeep
No changes.
View
26 public/404.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>The page you were looking for doesn't exist (404)</title>
+ <style type="text/css">
+ body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
+ div.dialog {
+ width: 25em;
+ padding: 0 4em;
+ margin: 4em auto 0 auto;
+ border: 1px solid #ccc;
+ border-right-color: #999;
+ border-bottom-color: #999;
+ }
+ h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
+ </style>
+</head>
+
+<body>
+ <!-- This file lives in public/404.html -->
+ <div class="dialog">
+ <h1>The page you were looking for doesn't exist.</h1>
+ <p>You may have mistyped the address or the page may have moved.</p>
+ </div>
+</body>
+</html>
View
26 public/422.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>The change you wanted was rejected (422)</title>
+ <style type="text/css">
+ body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
+ div.dialog {
+ width: 25em;
+ padding: 0 4em;
+ margin: 4em auto 0 auto;
+ border: 1px solid #ccc;
+ border-right-color: #999;
+ border-bottom-color: #999;
+ }
+ h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
+ </style>
+</head>
+
+<body>
+ <!-- This file lives in public/422.html -->
+ <div class="dialog">
+ <h1>The change you wanted was rejected.</h1>
+ <p>Maybe you tried to change something you didn't have access to.</p>
+ </div>
+</body>
+</html>
View
25 public/500.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>We're sorry, but something went wrong (500)</title>
+ <style type="text/css">
+ body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
+ div.dialog {
+ width: 25em;
+ padding: 0 4em;
+ margin: 4em auto 0 auto;
+ border: 1px solid #ccc;
+ border-right-color: #999;
+ border-bottom-color: #999;
+ }
+ h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
+ </style>
+</head>
+
+<body>
+ <!-- This file lives in public/500.html -->
+ <div class="dialog">
+ <h1>We're sorry, but something went wrong.</h1>
+ </div>
+</body>
+</html>
View
0 public/favicon.ico
No changes.
View
5 public/robots.txt
@@ -0,0 +1,5 @@
+# See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file
+#
+# To ban all spiders from the entire site uncomment the next two lines:
+# User-Agent: *
+# Disallow: /
View
6 script/rails
@@ -0,0 +1,6 @@
+#!/usr/bin/env ruby
+# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
+
+APP_PATH = File.expand_path('../../config/application', __FILE__)
+require File.expand_path('../../config/boot', __FILE__)
+require 'rails/commands'
View
0 vendor/assets/javascripts/.gitkeep
No changes.
View
0 vendor/assets/stylesheets/.gitkeep
No changes.
View
0 vendor/plugins/.gitkeep
No changes.

0 comments on commit 27c6466

Please sign in to comment.
Something went wrong with that request. Please try again.