mir_extensions 0.2.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/.gitignore +3 -0
  2. data/Gemfile +2 -1
  3. data/Gemfile.lock +18 -2
  4. data/Rakefile +1 -1
  5. data/VERSION +1 -1
  6. data/app/controllers/foos_controller.rb +83 -0
  7. data/app/helpers/application_helper.rb +1 -0
  8. data/app/models/foo.rb +2 -0
  9. data/app/views/foos/_form.html.erb +20 -0
  10. data/app/views/foos/edit.html.erb +6 -0
  11. data/app/views/foos/index.html.erb +27 -0
  12. data/app/views/foos/new.html.erb +5 -0
  13. data/app/views/foos/show.html.erb +20 -0
  14. data/config.ru +1 -1
  15. data/config/application.rb +5 -1
  16. data/config/environment.rb +1 -1
  17. data/config/environments/development.rb +1 -1
  18. data/config/environments/test.rb +1 -1
  19. data/config/initializers/secret_token.rb +1 -1
  20. data/config/initializers/session_store.rb +1 -1
  21. data/config/routes.rb +5 -2
  22. data/db/migrate/20100801224509_create_foos.rb +16 -0
  23. data/db/mir_ext_development.sqlite3 +0 -0
  24. data/db/mir_ext_test.sqlite3 +0 -0
  25. data/db/schema.rb +11 -1
  26. data/lib/core_ext/core_ext.rb +1 -2
  27. data/lib/mir_extensions.rb +386 -2
  28. data/lib/mir_form_builder.rb +166 -0
  29. data/mir_extensions.gemspec +29 -7
  30. data/public/stylesheets/scaffold.css +56 -0
  31. data/spec/controllers/foos_controller_spec.rb +125 -0
  32. data/spec/routing/foos_routing_spec.rb +35 -0
  33. data/spec/support/integration_example_group.rb +35 -0
  34. data/spec/views/foos/edit.html.erb_spec.rb +61 -0
  35. data/spec/views/foos/index.html.erb_spec.rb +25 -0
  36. data/spec/views/foos/new.html.erb_spec.rb +22 -0
  37. data/spec/views/foos/show.html.erb_spec.rb +18 -0
  38. metadata +29 -7
  39. data/lib/core_ext/helper_extensions.rb +0 -383
  40. data/log/development.log +0 -151
  41. data/log/test.log +0 -27
  42. data/public/index.html +0 -262
data/.gitignore CHANGED
@@ -17,5 +17,8 @@ tmtags
17
17
  coverage
18
18
  rdoc
19
19
  pkg
20
+ log
21
+ tmp
22
+ test
20
23
 
21
24
  ## PROJECT::SPECIFIC
data/Gemfile CHANGED
@@ -6,7 +6,7 @@ gem 'rails', '3.0.0.rc'
6
6
  # gem 'rails', :git => 'git://github.com/rails/rails.git'
7
7
 
8
8
  gem 'friendly_id'
9
- gem 'mir_extensions'
9
+ gem 'mir_extensions', '>= 0.3.0'
10
10
  gem 'sqlite3-ruby', :require => 'sqlite3'
11
11
  gem 'jeweler'
12
12
  gem 'gemcutter'
@@ -38,4 +38,5 @@ group :test do
38
38
  gem 'rspec-rails', '>= 2.0.0.beta.10'
39
39
  gem "machinist", '>= 2.0.0.beta1'
40
40
  gem "mocha"
41
+ gem "capybara", ">= 0.3.9"
41
42
  end
@@ -32,10 +32,20 @@ GEM
32
32
  activesupport (>= 3.0.0.beta)
33
33
  babosa (0.1.0)
34
34
  builder (2.1.2)
35
+ capybara (0.3.9)
36
+ culerity (>= 0.2.4)
37
+ mime-types (>= 1.16)
38
+ nokogiri (>= 1.3.3)
39
+ rack (>= 1.0.0)
40
+ rack-test (>= 0.5.4)
41
+ selenium-webdriver (>= 0.0.3)
42
+ culerity (0.2.10)
35
43
  diff-lcs (1.1.2)
36
44
  erubis (2.6.6)
37
45
  abstract (>= 1.0.0)
38
46
  faker (0.3.1)
47
+ ffi (0.6.3)
48
+ rake (>= 0.8.7)
39
49
  friendly_id (3.1.1.1)
40
50
  babosa (>= 0.1.0)
41
51
  gemcutter (0.6.1)
@@ -52,7 +62,7 @@ GEM
52
62
  mime-types
53
63
  treetop (>= 1.4.5)
54
64
  mime-types (1.16)
55
- mir_extensions (0.1.0)
65
+ mir_extensions (0.3.0)
56
66
  mocha (0.9.8)
57
67
  rake
58
68
  nokogiri (1.4.3.1)
@@ -89,6 +99,11 @@ GEM
89
99
  webrat (>= 0.7.2.beta.1)
90
100
  rubyforge (2.0.4)
91
101
  json_pure (>= 1.1.7)
102
+ rubyzip (0.9.4)
103
+ selenium-webdriver (0.0.27)
104
+ ffi (>= 0.6.1)
105
+ json_pure
106
+ rubyzip
92
107
  sqlite3-ruby (1.3.1)
93
108
  thor (0.14.0)
94
109
  treetop (1.4.8)
@@ -103,12 +118,13 @@ PLATFORMS
103
118
  ruby
104
119
 
105
120
  DEPENDENCIES
121
+ capybara (>= 0.3.9)
106
122
  faker
107
123
  friendly_id
108
124
  gemcutter
109
125
  jeweler
110
126
  machinist (>= 2.0.0.beta1)
111
- mir_extensions
127
+ mir_extensions (>= 0.3.0)
112
128
  mocha
113
129
  rails (= 3.0.0.rc)
114
130
  rspec (>= 2.0.0.beta.19)
data/Rakefile CHANGED
@@ -47,4 +47,4 @@ Rake::RDocTask.new do |rdoc|
47
47
  end
48
48
 
49
49
  require File.expand_path('../config/application', __FILE__)
50
- MirExtensions::Application.load_tasks
50
+ MirExtensionsContainer::Application.load_tasks
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 1.0.0
@@ -0,0 +1,83 @@
1
+ class FoosController < ApplicationController
2
+ # GET /foos
3
+ # GET /foos.xml
4
+ def index
5
+ @foos = Foo.all
6
+
7
+ respond_to do |format|
8
+ format.html # index.html.erb
9
+ format.xml { render :xml => @foos }
10
+ end
11
+ end
12
+
13
+ # GET /foos/1
14
+ # GET /foos/1.xml
15
+ def show
16
+ @foo = Foo.find(params[:id])
17
+
18
+ respond_to do |format|
19
+ format.html # show.html.erb
20
+ format.xml { render :xml => @foo }
21
+ end
22
+ end
23
+
24
+ # GET /foos/new
25
+ # GET /foos/new.xml
26
+ def new
27
+ @foo = Foo.new
28
+
29
+ respond_to do |format|
30
+ format.html # new.html.erb
31
+ format.xml { render :xml => @foo }
32
+ end
33
+ end
34
+
35
+ # GET /foos/1/edit
36
+ def edit
37
+ @foo = Foo.find(params[:id])
38
+ end
39
+
40
+ # POST /foos
41
+ # POST /foos.xml
42
+ def create
43
+ @foo = Foo.new(params[:foo])
44
+
45
+ respond_to do |format|
46
+ if @foo.save
47
+ format.html { redirect_to(@foo, :notice => 'Foo was successfully created.') }
48
+ format.xml { render :xml => @foo, :status => :created, :location => @foo }
49
+ else
50
+ format.html { render :action => "new" }
51
+ format.xml { render :xml => @foo.errors, :status => :unprocessable_entity }
52
+ end
53
+ end
54
+ end
55
+
56
+ # PUT /foos/1
57
+ # PUT /foos/1.xml
58
+ def update
59
+ @foo = Foo.find(params[:id])
60
+
61
+ respond_to do |format|
62
+ if @foo.update_attributes(params[:foo])
63
+ format.html { redirect_to(@foo, :notice => 'Foo was successfully updated.') }
64
+ format.xml { head :ok }
65
+ else
66
+ format.html { render :action => "edit" }
67
+ format.xml { render :xml => @foo.errors, :status => :unprocessable_entity }
68
+ end
69
+ end
70
+ end
71
+
72
+ # DELETE /foos/1
73
+ # DELETE /foos/1.xml
74
+ def destroy
75
+ @foo = Foo.find(params[:id])
76
+ @foo.destroy
77
+
78
+ respond_to do |format|
79
+ format.html { redirect_to(foos_url) }
80
+ format.xml { head :ok }
81
+ end
82
+ end
83
+ end
@@ -1,2 +1,3 @@
1
1
  module ApplicationHelper
2
2
  end
3
+
@@ -0,0 +1,2 @@
1
+ class Foo < ActiveRecord::Base
2
+ end
@@ -0,0 +1,20 @@
1
+ <%= form_for(@foo) do |f| %>
2
+ <% if @foo.errors.any? %>
3
+ <div id="error_explanation">
4
+ <h2><%= pluralize(@foo.errors.count, "error") %> prohibited this foo from being saved:</h2>
5
+
6
+ <ul>
7
+ <% @foo.errors.full_messages.each do |msg| %>
8
+ <li><%= msg %></li>
9
+ <% end %>
10
+ </ul>
11
+ </div>
12
+ <% end %>
13
+
14
+ <%= f.text_field :name %>
15
+ <%= f.check_box :active, :label => 'Status', :inline_label => 'Active' %>
16
+ <%= f.select :style, [select_prompt, "foo", "bar"], :label => 'Select a Style' %>
17
+ <%= f.date_select :due_date, :order => [:month, :day, :year] -%>
18
+ <%= f.submit %>
19
+
20
+ <% end %>
@@ -0,0 +1,6 @@
1
+ <h1>Editing foo</h1>
2
+
3
+ <%= render 'form' %>
4
+
5
+ <%= link_to 'Show', @foo %> |
6
+ <%= link_to 'Back', foos_path %>
@@ -0,0 +1,27 @@
1
+ <h1>Listing foos</h1>
2
+
3
+ <table>
4
+ <tr>
5
+ <th>Name</th>
6
+ <th>Active</th>
7
+ <th>Style</th>
8
+ <th></th>
9
+ <th></th>
10
+ <th></th>
11
+ </tr>
12
+
13
+ <% @foos.each do |foo| %>
14
+ <tr>
15
+ <td><%= foo.name %></td>
16
+ <td><%= foo.active %></td>
17
+ <td><%= foo.style %></td>
18
+ <td><%= link_to 'Show', foo %></td>
19
+ <td><%= link_to 'Edit', edit_foo_path(foo) %></td>
20
+ <td><%= link_to 'Destroy', foo, :confirm => 'Are you sure?', :method => :delete %></td>
21
+ </tr>
22
+ <% end %>
23
+ </table>
24
+
25
+ <br />
26
+
27
+ <%= link_to 'New Foo', new_foo_path %>
@@ -0,0 +1,5 @@
1
+ <h1>New foo</h1>
2
+
3
+ <%= render 'form' %>
4
+
5
+ <%= link_to 'Back', foos_path %>
@@ -0,0 +1,20 @@
1
+ <p id="notice"><%= notice %></p>
2
+
3
+ <p>
4
+ <b>Name:</b>
5
+ <%= @foo.name %>
6
+ </p>
7
+
8
+ <p>
9
+ <b>Active:</b>
10
+ <%= @foo.active %>
11
+ </p>
12
+
13
+ <p>
14
+ <b>Style:</b>
15
+ <%= @foo.style %>
16
+ </p>
17
+
18
+
19
+ <%= link_to 'Edit', edit_foo_path(@foo) %> |
20
+ <%= link_to 'Back', foos_path %>
data/config.ru CHANGED
@@ -1,4 +1,4 @@
1
1
  # This file is used by Rack-based servers to start the application.
2
2
 
3
3
  require ::File.expand_path('../config/environment', __FILE__)
4
- run MirExtensions::Application
4
+ run MirExtensionsContainer::Application
@@ -1,12 +1,13 @@
1
1
  require File.expand_path('../boot', __FILE__)
2
2
 
3
3
  require 'rails/all'
4
+ require 'lib/mir_form_builder'
4
5
 
5
6
  # If you have a Gemfile, require the gems listed there, including any gems
6
7
  # you've limited to :test, :development, or :production.
7
8
  Bundler.require(:default, Rails.env) if defined?(Bundler)
8
9
 
9
- module MirExtensions
10
+ module MirExtensionsContainer
10
11
  class Application < Rails::Application
11
12
  # Settings in config/environments/* take precedence over those specified here.
12
13
  # Application configuration should go into files in config/initializers
@@ -39,9 +40,12 @@ module MirExtensions
39
40
  # Configure sensitive parameters which will be filtered from the log file.
40
41
  config.filter_parameters += [:password]
41
42
 
43
+ config.action_view.default_form_builder = MirExtensions::MirFormBuilder
44
+
42
45
  config.generators do |g|
43
46
  g.test_framework :rspec
44
47
  end
45
48
 
46
49
  end
47
50
  end
51
+
@@ -2,4 +2,4 @@
2
2
  require File.expand_path('../application', __FILE__)
3
3
 
4
4
  # Initialize the rails application
5
- MirExtensions::Application.initialize!
5
+ MirExtensionsContainer::Application.initialize!
@@ -1,4 +1,4 @@
1
- MirExtensions::Application.configure do
1
+ MirExtensionsContainer::Application.configure do
2
2
  # Settings specified here will take precedence over those in config/environment.rb
3
3
 
4
4
  # In the development environment your application's code is reloaded on
@@ -1,4 +1,4 @@
1
- MirExtensions::Application.configure do
1
+ MirExtensionsContainer::Application.configure do
2
2
  # Settings specified here will take precedence over those in config/environment.rb
3
3
 
4
4
  # The test environment is used exclusively to run your application's
@@ -4,4 +4,4 @@
4
4
  # If you change this key, all old signed cookies will become invalid!
5
5
  # Make sure the secret is at least 30 characters and all random,
6
6
  # no regular words or you'll be exposed to dictionary attacks.
7
- MirExtensions::Application.config.secret_token = 'df016d1dd6851037860d1dc3e9abfc4c3b1c99169dfdd03a19c00d243f8d3507fd0b17376371a8bd472797b093afd885a5dd9e5bc10c36475c432ea212437ecc'
7
+ MirExtensionsContainer::Application.config.secret_token = 'df016d1dd6851037860d1dc3e9abfc4c3b1c99169dfdd03a19c00d243f8d3507fd0b17376371a8bd472797b093afd885a5dd9e5bc10c36475c432ea212437ecc'
@@ -1,6 +1,6 @@
1
1
  # Be sure to restart your server when you modify this file.
2
2
 
3
- MirExtensions::Application.config.session_store :cookie_store, :key => '_MirExtensions_session'
3
+ MirExtensionsContainer::Application.config.session_store :cookie_store, :key => '_MirExtensions_session'
4
4
 
5
5
  # Use the database for sessions instead of the cookie-based default,
6
6
  # which shouldn't be used to store highly confidential information
@@ -1,4 +1,7 @@
1
- MirExtensions::Application.routes.draw do
1
+ MirExtensionsContainer::Application.routes.draw do
2
+
3
+ resources :foos
4
+
2
5
  # The priority is based upon order of creation:
3
6
  # first created -> highest priority.
4
7
 
@@ -48,7 +51,7 @@ MirExtensions::Application.routes.draw do
48
51
 
49
52
  # You can have the root of your site routed with "root"
50
53
  # just remember to delete public/index.html.
51
- # root :to => "welcome#index"
54
+ root :to => "foos#index"
52
55
 
53
56
  # See how all your routes lay out with "rake routes"
54
57
 
@@ -0,0 +1,16 @@
1
+ class CreateFoos < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :foos do |t|
4
+ t.string :name
5
+ t.boolean :active
6
+ t.string :style
7
+ t.datetime :due_date
8
+ t.string :country
9
+ t.timestamps
10
+ end
11
+ end
12
+
13
+ def self.down
14
+ drop_table :foos
15
+ end
16
+ end
Binary file
@@ -10,7 +10,17 @@
10
10
  #
11
11
  # It's strongly recommended to check this file into your version control system.
12
12
 
13
- ActiveRecord::Schema.define(:version => 0) do
13
+ ActiveRecord::Schema.define(:version => 20100801224509) do
14
+
15
+ create_table "foos", :force => true do |t|
16
+ t.string "name"
17
+ t.boolean "active"
18
+ t.string "style"
19
+ t.datetime "due_date"
20
+ t.string "country"
21
+ t.datetime "created_at"
22
+ t.datetime "updated_at"
23
+ end
14
24
 
15
25
  create_table "primaries", :force => true do |t|
16
26
  t.string "name"
@@ -250,8 +250,7 @@ class ActiveRecord::Base
250
250
 
251
251
  #FIXME Extending AR in this way will stop working under Rails 2.3.2 for some reason.
252
252
 
253
- # scope :order_by, lambda{ |col, dir| {:order => (col.blank?) ? ( (dir.blank?) ? 'id' : dir ) : "#{col} #{dir}"} }
254
- # scope :limit, lambda { |num| { :limit => num } }
253
+ scope :order_by, lambda{ |col, dir| {:order => (col.blank?) ? ( (dir.blank?) ? 'id' : dir ) : "#{col} #{dir}"} }
255
254
 
256
255
  # TODO: call the column_names class method on the subclass
257
256
  # named_scope :sort_by, lambda{ |col, dir| {:order => (col.blank?) ? ( (dir.blank?) ? (Client.column_names.include?('name') ? 'name' : 'id') : h(dir) ) : "#{h(col)} #{h(dir)}"} }
@@ -1,9 +1,9 @@
1
1
  require 'singleton'
2
- require File.expand_path(File.dirname(__FILE__) + '/core_ext/core_ext')
3
2
  require 'friendly_id'
3
+ require 'core_ext/core_ext'
4
4
 
5
5
  module MirExtensions
6
-
6
+
7
7
  # Constants ======================================================================================
8
8
 
9
9
  MONTHS = {0 => "JAN", 1 => "FEB", 2 => "MAR", 3 => "APR", 4 => "MAY", 5 => "JUN", 6 => "JUL", 7 => "AUG", 8 => "SEP", 9 => "OCT", 10 => "NOV", 11 => "DEC"}
@@ -33,5 +33,389 @@ module MirExtensions
33
33
  def self.state_name_for(abbreviation)
34
34
  STATE_CODES.invert[abbreviation]
35
35
  end
36
+
37
+ module HelperExtensions
38
+
39
+ def action?( expression )
40
+ !! ( expression.class == Regexp ? controller.action_name =~ expression : controller.action_name == expression )
41
+ end
42
+
43
+ # Formats an array with HTML line breaks, or the specified delimiter.
44
+ def array_to_lines(array, delimiter = '<br />')
45
+ array.blank? ? nil : array * delimiter
46
+ end
47
+
48
+ def checkmark
49
+ %{<div class="checkmark"></div>}.html_safe
50
+ end
51
+
52
+ def controller?( expression )
53
+ !! ( expression.class == Regexp ? controller.controller_name =~ expression : controller.controller_name == expression )
54
+ end
55
+
56
+ # Display CRUD icons or links, according to setting in use_crud_icons method.
57
+ #
58
+ # In application_helper.rb:
59
+ #
60
+ # def use_crud_icons
61
+ # true
62
+ # end
63
+ #
64
+ # Then use in index views like this:
65
+ #
66
+ # <td class="crud_links"><%= crud_links(my_model, 'my_model', [:show, :edit, :delete]) -%></td>
67
+ #
68
+ def crud_links(model, instance_name, actions, args={})
69
+ _html = ""
70
+ _options = args.keys.empty? ? '' : ", #{args.map{|k,v| ":#{k} => #{v}"}}"
71
+
72
+ if use_crud_icons
73
+ if actions.include?(:show)
74
+ _html << eval("link_to image_tag('/images/icons/view.png', :class => 'crud_icon'), model, :title => 'View'#{_options}")
75
+ end
76
+ if actions.include?(:edit)
77
+ _html << eval("link_to image_tag('/images/icons/edit.png', :class => 'crud_icon'), edit_#{instance_name}_path(model), :title => 'Edit'#{_options}")
78
+ end
79
+ if actions.include?(:delete)
80
+ _html << eval("link_to image_tag('/images/icons/delete.png', :class => 'crud_icon'), model, :confirm => 'Are you sure? This action cannot be undone.', :method => :delete, :title => 'Delete'#{_options}")
81
+ end
82
+ else
83
+ if actions.include?(:show)
84
+ _html << eval("link_to 'View', model, :title => 'View', :class => 'crud_link'#{_options}")
85
+ end
86
+ if actions.include?(:edit)
87
+ _html << eval("link_to 'Edit', edit_#{instance_name}_path(model), :title => 'Edit', :class => 'crud_link'#{_options}")
88
+ end
89
+ if actions.include?(:delete)
90
+ _html << eval("link_to 'Delete', model, :confirm => 'Are you sure? This action cannot be undone.', :method => :delete, :title => 'Delete', :class => 'crud_link'#{_options}")
91
+ end
92
+ end
93
+ _html
94
+ end
95
+
96
+ # Display CRUD icons or links, according to setting in use_crud_icons method.
97
+ # This method works with nested resources.
98
+ # Use in index views like this:
99
+ #
100
+ # <td class="crud_links"><%= crud_links_for_nested_resource(@my_model, my_nested_model, 'my_model', 'my_nested_model', [:show, :edit, :delete]) -%></td>
101
+ #
102
+ def crud_links_for_nested_resource(model, nested_model, model_instance_name, nested_model_instance_name, actions, args={})
103
+ _html = ""
104
+ if use_crud_icons
105
+ if actions.include?(:show)
106
+ _html << eval("link_to image_tag('/images/icons/view.png', :class => 'crud_icon'), #{model_instance_name}_#{nested_model_instance_name}_path(model, nested_model), :title => 'View'")
107
+ end
108
+
109
+ if actions.include?(:edit)
110
+ _html << eval("link_to image_tag('/images/icons/edit.png', :class => 'crud_icon'), edit_#{model_instance_name}_#{nested_model_instance_name}_path(model, nested_model), :title => 'Edit'")
111
+ end
112
+
113
+ if actions.include?(:delete)
114
+ _html << eval("link_to image_tag('/images/icons/delete.png', :class => 'crud_icon'), #{model_instance_name}_#{nested_model_instance_name}_path(model, nested_model), :method => :delete, :confirm => 'Are you sure? This action cannot be undone.', :title => 'Delete'")
115
+ end
116
+ end
117
+ _html
118
+ end
119
+
120
+ # DRY way to return a legend tag that renders correctly in all browsers. This variation allows
121
+ # for more "stuff" inside the legend tag, e.g. expand/collapse controls, without having to worry
122
+ # about escape sequences.
123
+ #
124
+ # Sample usage:
125
+ #
126
+ # <%- legend_block do -%>
127
+ # <span id="hide_or_show_backlinks" class="show_link" style="background-color: #999999;
128
+ # border: 1px solid #999999;" onclick="javascript:hide_or_show('backlinks');"></span>Backlinks (<%=
129
+ # @google_results.size -%>)
130
+ # <%- end -%>
131
+ #
132
+ def legend_block(&block)
133
+ concat content_tag(:div, capture(&block), :class => "faux_legend")
134
+ end
135
+
136
+ # DRY way to return a legend tag that renders correctly in all browsers
137
+ def legend_tag(text, args={})
138
+ _html = %{<div id="#{args[:id]}" class="faux_legend">#{text}</div>\r}
139
+ _html.gsub!(/ id=""/,'')
140
+ _html.gsub!(/ class=""/,'')
141
+ _html
142
+ end
143
+
144
+ def meta_description(content=nil)
145
+ content_for(:meta_description) { content } unless content.blank?
146
+ end
147
+
148
+ def meta_keywords(content=nil)
149
+ content_for(:meta_keywords) { content } unless content.blank?
150
+ end
151
+
152
+ def models_for_select( models, label = 'name' )
153
+ models.map{ |m| [m[label], m.id] }.sort_by{ |e| e[0] }
154
+ end
155
+
156
+ def options_for_array( a, selected = nil, prompt = select_prompt )
157
+ "<option value=''>#{prompt}</option>" + a.map{ |_e| _flag = _e[0].to_s == selected ? 'selected="1"' : ''; _e.is_a?(Array) ? "<option value=\"#{_e[0]}\" #{_flag}>#{_e[1]}</option>" : "<option>#{_e}</option>" }.to_s
158
+ end
159
+
160
+ # Create a link that is opaque to search engine spiders.
161
+ def obfuscated_link_to(path, image, label, args={})
162
+ _html = %{<form action="#{path}" method="get" class="obfuscated_link">}
163
+ _html << %{ <fieldset><input alt="#{label}" src="#{image}" type="image" /></fieldset>}
164
+ args.each{ |k,v| _html << %{ <div><input id="#{k.to_s}" name="#{k}" type="hidden" value="#{v}" /></div>} }
165
+ _html << %{</form>}
166
+ _html
167
+ end
168
+
169
+ # Wraps the given HTML in Rails' default style to highlight validation errors, if any.
170
+ def required_field_helper( model, element, html )
171
+ if model && ! model.errors.empty? && element.is_required
172
+ return content_tag( :div, html, :class => 'fieldWithErrors' )
173
+ else
174
+ return html
175
+ end
176
+ end
177
+
178
+ def select_prompt
179
+ "Select..."
180
+ end
181
+
182
+ def select_prompt_option
183
+ "<option value=''>#{select_prompt}</option>"
184
+ end
185
+
186
+ # Use on index pages to create dropdown list of filtering criteria.
187
+ # Populate the filter list using a constant in the model corresponding to named scopes.
188
+ #
189
+ # Usage:
190
+ #
191
+ # - item.rb:
192
+ #
193
+ # scope :active, :conditions => { :is_active => true }
194
+ # scope :inactive, :conditions => { :is_active => false }
195
+ #
196
+ # FILTERS = [
197
+ # {:scope => "all", :label => "All"},
198
+ # {:scope => "active", :label => "Active Only"},
199
+ # {:scope => "inactive", :label => "Inactive Only"}
200
+ # ]
201
+ #
202
+ # - items/index.html.erb:
203
+ #
204
+ # <%= select_tag_for_filter("items", @filters, params) -%>
205
+ #
206
+ # - items_controller.rb:
207
+ #
208
+ # def index
209
+ # @filters = Item::FILTERS
210
+ # if params[:show] && params[:show] != "all" && @filters.collect{|f| f[:scope]}.include?(params[:show])
211
+ # @items = eval("@items.#{params[:show]}.order_by(params[:by], params[:dir])")
212
+ # else
213
+ # @items = @items.order_by(params[:by], params[:dir])
214
+ # end
215
+ # ...
216
+ # end
217
+ #
218
+ def select_tag_for_filter(model, nvpairs, params)
219
+ return unless model && nvpairs && ! nvpairs.empty?
220
+ options = { :query => params[:query] }
221
+ _url = url_for(eval("#{model}_url(options)"))
222
+ _html = %{<label for="show">Show:</label><br />}
223
+ _html << %{<select name="show" id="show" onchange="window.location='#{_url}' + '?show=' + this.value">}
224
+ nvpairs.each do |pair|
225
+ _html << %{<option value="#{pair[:scope]}"}
226
+ if params[:show] == pair[:scope] || ((params[:show].nil? || params[:show].empty?) && pair[:scope] == "all")
227
+ _html << %{ selected="selected"}
228
+ end
229
+ _html << %{>#{pair[:label]}}
230
+ _html << %{</option>}
231
+ end
232
+ _html << %{</select>}
233
+ end
234
+
235
+ # Returns a link_to tag with sorting parameters that can be used with ActiveRecord.order_by.
236
+ #
237
+ # To use standard resources, specify the resources as a plural symbol:
238
+ # sort_link(:users, 'email', params)
239
+ #
240
+ # To use resources aliased with :as (in routes.rb), specify the aliased route as a string.
241
+ # sort_link('users_admin', 'email', params)
242
+ #
243
+ # You can override the link's label by adding a labels hash to your params in the controller:
244
+ # params[:labels] = {'user_id' => 'User'}
245
+ def sort_link(model, field, params, html_options={})
246
+ if (field.to_sym == params[:by] || field == params[:by]) && params[:dir] == "ASC"
247
+ classname = "arrow-asc"
248
+ dir = "DESC"
249
+ elsif (field.to_sym == params[:by] || field == params[:by])
250
+ classname = "arrow-desc"
251
+ dir = "ASC"
252
+ else
253
+ dir = "ASC"
254
+ end
255
+
256
+ options = {
257
+ :anchor => html_options[:anchor] || nil,
258
+ :by => field,
259
+ :dir => dir,
260
+ :query => params[:query],
261
+ :show => params[:show]
262
+ }
263
+
264
+ options[:show] = params[:show] unless params[:show].blank? || params[:show] == 'all'
265
+
266
+ html_options = {
267
+ :class => "#{classname} #{html_options[:class]}",
268
+ :style => "color: white; font-weight: #{params[:by] == field ? "bold" : "normal"}; #{html_options[:style]}",
269
+ :title => "Sort by this field"
270
+ }
271
+
272
+ field_name = params[:labels] && params[:labels][field] ? params[:labels][field] : field.titleize
273
+
274
+ _link = model.is_a?(Symbol) ? eval("#{model}_url(options)") : "/#{model}?#{options.to_params}"
275
+ link_to(field_name, _link, html_options)
276
+ end
277
+
278
+ # Tabbed interface helpers =======================================================================
279
+
280
+ # Returns formatted tabs with appropriate JS for activation. Use in conjunction with tab_body.
281
+ #
282
+ # Usage:
283
+ #
284
+ # <%- tabset do -%>
285
+ # <%= tab_tag :id => 'ppc_ads', :label => 'PPC Ads', :state => 'active' %>
286
+ # <%= tab_tag :id => 'budget' %>
287
+ # <%= tab_tag :id => 'geotargeting' %>
288
+ # <%- end -%>
289
+ #
290
+ def tabset(&proc)
291
+ concat %{
292
+ <div class="jump_links">
293
+ <ul>
294
+ }
295
+ yield
296
+ concat %{
297
+ </ul>
298
+ </div>
299
+ <br style="clear: both;" /><br />
300
+ <input type="hidden" id="show_tab" />
301
+ <script type="text/javascript">
302
+ function hide_all_tabs() { $$('.tab_block').invoke('hide'); }
303
+ function activate_tab(tab) {
304
+ $$('.tab_control').each(function(elem){ elem.className = 'tab_control'});
305
+ $('show_' + tab).className = 'tab_control active';
306
+ hide_all_tabs();
307
+ $(tab).toggle();
308
+ $('show_tab').value = tab
309
+ }
310
+ function sticky_tab() { if (location.hash) { activate_tab(location.hash.gsub('#','')); } }
311
+ Event.observe(window, 'load', function() { sticky_tab(); });
312
+ </script>
313
+ }
314
+ end
315
+
316
+ # Returns a tab body corresponding to tabs in a tabset. Make sure that the id of the tab_body
317
+ # matches the id provided to the tab_tag in the tabset block.
318
+ #
319
+ # Usage:
320
+ #
321
+ # <%- tab_body :id => 'ppc_ads', :label => 'PPC Ad Details' do -%>
322
+ # PPC ads form here.
323
+ # <%- end -%>
324
+ #
325
+ # <%- tab_body :id => 'budget' do -%>
326
+ # Budget form here.
327
+ # <%- end -%>
328
+ #
329
+ # <%- tab_body :id => 'geotargeting' do -%>
330
+ # Geotargeting form here.
331
+ # <%- end -%>
332
+ #
333
+ def tab_body(args, &proc)
334
+ concat %{<div id="#{args[:id]}" class="tab_block form_container" style="display: #{args[:display] || 'none'};">}
335
+ concat %{#{legend_tag args[:label] || args[:id].titleize }}
336
+ concat %{<a name="#{args[:id]}"></a><br />}
337
+ yield
338
+ concat %{</div>}
339
+ end
340
+
341
+ # Returns the necessary HTML for a particular tab. Use inside a tabset block.
342
+ # Override the default tab label by specifying a :label parameter.
343
+ # Indicate that the tab should be active by setting its :state to 'active'.
344
+ # (NOTE: You must define a corresponding CSS style for active tabs.)
345
+ #
346
+ # Usage:
347
+ #
348
+ # <%= tab_tag :id => 'ppc_ads', :label => 'PPC Ads', :state => 'active' %>
349
+ #
350
+ def tab_tag(args, *css_class)
351
+ %{<li id="show_#{args[:id]}" class="tab_control #{args[:state]}" onclick="window.location='##{args[:id]}'; activate_tab('#{args[:id]}');">#{args[:label] || args[:id].to_s.titleize}</li>}
352
+ end
353
+
354
+ # ================================================================================================
355
+
356
+ def tag_for_collapsible_row(obj, params)
357
+ _html = ""
358
+ if obj && obj.respond_to?(:parent) && obj.parent
359
+ _html << %{<tr class="#{obj.class.name.downcase}_#{obj.parent.id} #{params[:class]}" style="display: none; #{params[:style]}">}
360
+ else
361
+ _html << %{<tr class="#{params[:class]}" style="#{params[:style]}">}
362
+ end
363
+ _html
364
+ end
365
+
366
+ def tag_for_collapsible_row_control(obj)
367
+ _base_id = "#{obj.class.name.downcase}_#{obj.id}"
368
+ _html = %{<div id="hide_or_show_#{_base_id}" class="show_link" style="background-color: #999999; border: 1px solid #999999;" onclick="javascript:hide_or_show('#{_base_id}');"></div>}
369
+ end
370
+
371
+ # Create a set of tags for displaying a field label with inline help.
372
+ # Field label text is appended with a ? icon, which responds to a click
373
+ # by showing or hiding the provided help text.
374
+ #
375
+ # Sample usage:
376
+ #
377
+ # <%= tag_for_label_with_inline_help 'Relative Frequency', 'rel_frequency', 'Relative frequency of search traffic for this keyword across multiple search engines, as measured by WordTracker.' %>
378
+ #
379
+ # Yields:
380
+ #
381
+ # <label for="rel_frequency">Relative Frequency: <%= image_tag "/images/help_icon.png", :onclick => "$('rel_frequency_help').toggle();", :class => 'inline_icon' %></label><br />
382
+ # <div class="inline_help" id="rel_frequency_help" style="display: none;">
383
+ # <p>Relative frequency of search traffic for this keyword across multiple search engines, as measured by WordTracker.</p>
384
+ # </div>
385
+ def tag_for_label_with_inline_help( label_text, field_id, help_text )
386
+ _html = ""
387
+ _html << %{<label for="#{field_id}">#{label_text}}
388
+ _html << %{<img src="/images/icons/help_icon.png" onclick="$('#{field_id}_help').toggle();" class='inline_icon' />}
389
+ _html << %{</label><br />}
390
+ _html << %{<div class="inline_help" id="#{field_id}_help" style="display: none;">}
391
+ _html << %{<p>#{help_text}</p>}
392
+ _html << %{</div>}
393
+ _html
394
+ end
395
+
396
+ # Create a set of tags for displaying a field label followed by instructions.
397
+ # The instructions are displayed on a new line following the field label.
398
+ #
399
+ # Usage:
400
+ #
401
+ # <%= tag_for_label_with_instructions 'Status', 'is_active', 'Only active widgets will be visible to the public.' %>
402
+ #
403
+ # Yields:
404
+ #
405
+ # <label for="is_active">
406
+ # Status<br />
407
+ # <span class="instructions">Only active widgets will be visible to the public.</span>
408
+ # <label><br />
409
+ def tag_for_label_with_instructions( label_text, field_id, instructions )
410
+ _html = ""
411
+ _html << %{<label for="#{field_id}">#{label_text}}
412
+ _html << %{<span class="instructions">#{instructions}</span>}
413
+ _html << %{</label><br />}
414
+ _html
415
+ end
416
+
417
+ end
36
418
 
37
419
  end
420
+
421
+ ActionView::Base.send :include, MirExtensions::HelperExtensions