Skip to content
Orion98MC edited this page Sep 7, 2010 · 30 revisions

Tutorial:

Building an app from scratch with oa_notes.

Pre-requisits:

Have rails installed

Have installed gems:

  • haml
  • cells
  • onfire

Installation log:

Create a "notes" rails application:

$ rails notes
$ cd notes/

Install apotomo, will_paginate, jQuery, oa_widget, oa_notes:

$ ./script/plugin install git://github.com/apotonick/apotomo.git
$ ./script/plugin install git://github.com/mislav/will_paginate.git
$ curl -o public/javascripts/jquery-1.4.2.min.js http://code.jquery.com/jquery-1.4.2.min.js
$ ./script/plugin install git://github.com/Orion98MC/oa_widget.git 
$ rake oa_widget:sync_resources
$ ./script/plugin install git://github.com/Orion98MC/oa_notes.git
$ rake oa_notes:sync_resources

Create a Note model:

$ ./script/generate model Note content:text 
$ rake db:migrate

Create a dashboard controller:

$ ./script/generate controller dashboard

Edit the application's files:

$ mate .

Add the following in config/environment.rb: config.gem 'haml' config.gem 'cells' config.gem 'onfire'

Edit the application layout in app/layouts/application.html.haml: !!! Strict %html{html_attrs}
%head %title %meta{"http-equiv"=>"Content-Type", :content=>"text/html; charset=utf-8"}/ = javascript_include_tag :defaults, 'jquery-1.4.2.min' = javascript_tag "jQuery.noConflict();"

    = javascript_include_tag oa_widget_javascripts, oa_notes_javascripts
    = stylesheet_link_tag oa_widget_stylesheets, oa_notes_stylesheets

  %body
    = yield

Edit the dashboard controller in app/controllers/dashboard_controller.rb: class DashboardController < ApplicationController include Apotomo::Rails::ControllerMethods

  uses_widgets do |root|
    root << OANotes::Container.new('notes_widget')      
  end

  def index
  end

end

Edit the dashboard index action view in app/views/dashboard/index.html.haml: %div{:style => "width: 400px; margin: 50px;"} = render_widget 'notes_widget'

Et voilà!

Now you can run the server: $ ./script/server

And go to http://localhost:3000/dashboard

Customizations:

Let's change the look of the "notes_widget" widget.

First, let's hide the form.

Change the dashboard controller:

  uses_widgets do |root|
    root << OANotes::Container.new('notes_widget', :hide => [:form])      
  end

Now let's add the search ability:

For this, we need to have a scope in the note model to perform the search.

Add the search_content named scope to app/models/note.rb:

class Note < ActiveRecord::Base
  named_scope :search_content, lambda{|arg| {:conditions => ["content LIKE ?", "%#{arg.search_text}%"]}}
end

Change the dashboard controller:

  uses_widgets do |root|
    root << OANotes::Container.new('notes_widget', :hide => [:form], :search => :search_content)
  end

Now let's add a view filter for recent and old notes

Add the recent and old named scopes to app/models/note.rb:

class Note < ActiveRecord::Base
  named_scope :search_content, lambda{|arg| {:conditions => ["content LIKE ?", "%#{arg.search_text}%"]}}
  named_scope :recent, lambda{ {:conditions => ["updated_at >= ?", 2.days.ago]}}
  named_scope :old,    lambda{ {:conditions => ["updated_at < ?",  2.days.ago]}}
end

Change the dashboard controller:

uses_widgets do |root|
  root << OANotes::Container.new('notes_widget', 
    :hide => [:form], 
    :search => :search_content, 
    :views => [ ["All", nil], ["Recent", :recent], ["Old", :old] ]
  )      
end

Now let's add a sort filter to allow sorting by creation date ascending or descending

Change the Note model:

class Note < ActiveRecord::Base
  named_scope :search_content, lambda{|arg| {:conditions => ["content LIKE ?", "%#{arg.search_text}%"]}}

  named_scope :recent, lambda{ {:conditions => ["updated_at >= ?", 2.days.ago]}}
  named_scope :old,    lambda{ {:conditions => ["updated_at < ?",  2.days.ago]}}

  named_scope :by_date_asc, {:order => "created_at ASC"}
  named_scope :by_date_desc, {:order => "created_at DESC"}
end

Change the dashboard controller:

uses_widgets do |root|
  root << OANotes::Container.new('notes_widget', 
    :hide => [:form], 
    :search => :search_content, 
    :views => [ ["All", nil], ["Recent", :recent], ["Old", :old] ],
    :sorts => [ ["Date (^)", :by_date_asc], ["Date (v)", :by_date_desc] ]
  )      
end

Now let's change the note display

We want to customize the way notes are displayed. For this we need to create a partial.

Create app/cells/partials/_note_details.html.haml:

%div
  %p{:style => "color: silver;"}= note.created_at.strftime("%H:%M.%S on %D")
  %p= note.content

(the css styles are there for demo purpose and should be put in a separate stylesheet file)

Change the dashboard controller code:

  uses_widgets do |root|
    root << OANotes::Container.new('notes_widget', 
      :hide => [:form], 
      :search => :search_content, 
      :views => [ ["All", nil], ["Recent", :recent], ["Old", :old] ],
      :sorts => [ ["Date (^)", :by_date_asc], ["Date (v)", :by_date_desc] ],
      :note_partial => 'partials/note_details'
    )      
  end

Now lets tweak the number of notes per page

You could specify the number of notes per page using the :per_page option, like this:

  uses_widgets do |root|
    root << OANotes::Container.new('notes_widget', 
      :hide => [:form], 
      :search => :search_content, 
      :views => [ ["All", nil], ["Recent", :recent], ["Old", :old] ],
      :sorts => [ ["Date (^)", :by_date_asc], ["Date (v)", :by_date_desc] ],
      :note_partial => 'partials/note_details',
      :per_page => 2
    )      
  end

Or, you could add a pages filter to let the user choose:

  uses_widgets do |root|
    root << OANotes::Container.new('notes_widget', 
      :hide => [:form], 
      :search => :search_content, 
      :views => [ ["All", nil], ["Recent", :recent], ["Old", :old] ],
      :sorts => [ ["Date (^)", :by_date_asc], ["Date (v)", :by_date_desc] ],
      :note_partial => 'partials/note_details',
      :pages => [ ["2", 2], ["10", 10] ]
    )      
  end

Now let's add a marking functionnality

We want to be able to mark/un-mark notes. For this we need to alter the notes table to add a mark_date field.

$ ./script/generate migration add_mark_date_to_notes mark_date:datetime
$ rake db:migrate

We also need to add the two methods needed for this to work, that is:

class Note < ActiveRecord::Base
  ...
  def marked?
    !mark_date.nil?
  end

  def toogle_mark!
    update_attribute(:mark_date, marked? ? nil : Time.now) 
  end
end

And update the controller code:

  uses_widgets do |root|
    root << OANotes::Container.new('notes_widget', 
      :hide => [:form], 
      :search => :search_content, 
      :views => [ ["All", nil], ["Recent", :recent], ["Old", :old] ],
      :sorts => [ ["Date (^)", :by_date_asc], ["Date (v)", :by_date_desc] ],
      :note_partial => 'partials/note_details',
      :per_page => 2,
      :pages => [ ["2", 2], ["10", 10] ],
      :has_markings? => true,
      :marked? => :marked?,
      :toogle_mark! => :toogle_mark!
    )      
  end

More tweaks to come... Enjoy! :)