scaffold_logic 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. data/.document +5 -0
  2. data/Capfile +4 -0
  3. data/README.rdoc +29 -0
  4. data/Rakefile +51 -0
  5. data/VERSION +1 -0
  6. data/config/deploy.rb +41 -0
  7. data/lib/generators/scaffold_logic/layout/USAGE +7 -0
  8. data/lib/generators/scaffold_logic/layout/layout_generator.rb +38 -0
  9. data/lib/generators/scaffold_logic/layout/templates/_nav_tabs.html.erb +3 -0
  10. data/lib/generators/scaffold_logic/layout/templates/images/icons/add.png +0 -0
  11. data/lib/generators/scaffold_logic/layout/templates/images/icons/collapsed.gif +0 -0
  12. data/lib/generators/scaffold_logic/layout/templates/images/icons/delete.png +0 -0
  13. data/lib/generators/scaffold_logic/layout/templates/images/icons/drag.png +0 -0
  14. data/lib/generators/scaffold_logic/layout/templates/images/icons/edit.png +0 -0
  15. data/lib/generators/scaffold_logic/layout/templates/images/icons/expanded.gif +0 -0
  16. data/lib/generators/scaffold_logic/layout/templates/images/icons/help_icon.png +0 -0
  17. data/lib/generators/scaffold_logic/layout/templates/images/icons/link_icon.png +0 -0
  18. data/lib/generators/scaffold_logic/layout/templates/images/icons/move.png +0 -0
  19. data/lib/generators/scaffold_logic/layout/templates/images/icons/move_white.png +0 -0
  20. data/lib/generators/scaffold_logic/layout/templates/images/icons/note.png +0 -0
  21. data/lib/generators/scaffold_logic/layout/templates/images/icons/note_white.png +0 -0
  22. data/lib/generators/scaffold_logic/layout/templates/images/icons/notification_icon_sprite.png +0 -0
  23. data/lib/generators/scaffold_logic/layout/templates/images/icons/spinner.gif +0 -0
  24. data/lib/generators/scaffold_logic/layout/templates/images/icons/view.png +0 -0
  25. data/lib/generators/scaffold_logic/layout/templates/images/icons/warning.png +0 -0
  26. data/lib/generators/scaffold_logic/layout/templates/images/icons/warning_2.png +0 -0
  27. data/lib/generators/scaffold_logic/layout/templates/images/icons/warning_box.png +0 -0
  28. data/lib/generators/scaffold_logic/layout/templates/images/icons/warning_icon.png +0 -0
  29. data/lib/generators/scaffold_logic/layout/templates/images/icons/warning_white.png +0 -0
  30. data/lib/generators/scaffold_logic/layout/templates/images/layout/arrow_asc.png +0 -0
  31. data/lib/generators/scaffold_logic/layout/templates/images/layout/arrow_desc.png +0 -0
  32. data/lib/generators/scaffold_logic/layout/templates/images/layout/back.png +0 -0
  33. data/lib/generators/scaffold_logic/layout/templates/images/layout/black_bar.png +0 -0
  34. data/lib/generators/scaffold_logic/layout/templates/images/layout/breadcrumb_bg.png +0 -0
  35. data/lib/generators/scaffold_logic/layout/templates/images/layout/button_bg.png +0 -0
  36. data/lib/generators/scaffold_logic/layout/templates/images/layout/content_left_bg.png +0 -0
  37. data/lib/generators/scaffold_logic/layout/templates/images/layout/content_right_bg.png +0 -0
  38. data/lib/generators/scaffold_logic/layout/templates/images/layout/credit_cards.gif +0 -0
  39. data/lib/generators/scaffold_logic/layout/templates/images/layout/footer_bg.png +0 -0
  40. data/lib/generators/scaffold_logic/layout/templates/images/layout/h1_bg.png +0 -0
  41. data/lib/generators/scaffold_logic/layout/templates/images/layout/h2_bg.png +0 -0
  42. data/lib/generators/scaffold_logic/layout/templates/images/layout/h2_bg_for_table.png +0 -0
  43. data/lib/generators/scaffold_logic/layout/templates/images/layout/header_bg_grey.png +0 -0
  44. data/lib/generators/scaffold_logic/layout/templates/images/layout/header_bg_purple.png +0 -0
  45. data/lib/generators/scaffold_logic/layout/templates/images/layout/legend_bg.png +0 -0
  46. data/lib/generators/scaffold_logic/layout/templates/images/layout/menu_box_bg.png +0 -0
  47. data/lib/generators/scaffold_logic/layout/templates/images/layout/shadow_border.png +0 -0
  48. data/lib/generators/scaffold_logic/layout/templates/images/layout/shadow_border_2.png +0 -0
  49. data/lib/generators/scaffold_logic/layout/templates/images/layout/shadow_border_3.png +0 -0
  50. data/lib/generators/scaffold_logic/layout/templates/images/layout/shadow_border_4.png +0 -0
  51. data/lib/generators/scaffold_logic/layout/templates/images/layout/tab.png +0 -0
  52. data/lib/generators/scaffold_logic/layout/templates/images/layout/tab_active.png +0 -0
  53. data/lib/generators/scaffold_logic/layout/templates/images/layout/table_header.png +0 -0
  54. data/lib/generators/scaffold_logic/layout/templates/images/layout/text_field_bg.jpg +0 -0
  55. data/lib/generators/scaffold_logic/layout/templates/images/layout/text_field_error_bg.png +0 -0
  56. data/lib/generators/scaffold_logic/layout/templates/images/layout/th_bg.png +0 -0
  57. data/lib/generators/scaffold_logic/layout/templates/images/layout/th_bg_selected.png +0 -0
  58. data/lib/generators/scaffold_logic/layout/templates/images/src/black_bar.psd +0 -0
  59. data/lib/generators/scaffold_logic/layout/templates/images/src/branding.psd +0 -0
  60. data/lib/generators/scaffold_logic/layout/templates/images/src/legend_bg.psd +0 -0
  61. data/lib/generators/scaffold_logic/layout/templates/images/src/menu_icons.psd +0 -0
  62. data/lib/generators/scaffold_logic/layout/templates/layout.html.erb +49 -0
  63. data/lib/generators/scaffold_logic/layout/templates/layout_helper.rb +16 -0
  64. data/lib/generators/scaffold_logic/layout/templates/stylesheets/application.css +881 -0
  65. data/lib/generators/scaffold_logic/layout/templates/stylesheets/core.css +1146 -0
  66. data/lib/generators/scaffold_logic/layout/templates/stylesheets/core_ie.css +52 -0
  67. data/lib/generators/scaffold_logic/layout/templates/stylesheets/csshover3.htc +14 -0
  68. data/lib/generators/scaffold_logic/scaffold/USAGE +48 -0
  69. data/lib/generators/scaffold_logic/scaffold/scaffold_generator.rb +230 -0
  70. data/lib/generators/scaffold_logic/scaffold/templates/actions/create.rb +9 -0
  71. data/lib/generators/scaffold_logic/scaffold/templates/actions/destroy.rb +6 -0
  72. data/lib/generators/scaffold_logic/scaffold/templates/actions/edit.rb +3 -0
  73. data/lib/generators/scaffold_logic/scaffold/templates/actions/index.rb +3 -0
  74. data/lib/generators/scaffold_logic/scaffold/templates/actions/new.rb +3 -0
  75. data/lib/generators/scaffold_logic/scaffold/templates/actions/show.rb +3 -0
  76. data/lib/generators/scaffold_logic/scaffold/templates/actions/update.rb +9 -0
  77. data/lib/generators/scaffold_logic/scaffold/templates/controller.rb +7 -0
  78. data/lib/generators/scaffold_logic/scaffold/templates/helper.rb +2 -0
  79. data/lib/generators/scaffold_logic/scaffold/templates/migration.rb +16 -0
  80. data/lib/generators/scaffold_logic/scaffold/templates/model.rb +18 -0
  81. data/lib/generators/scaffold_logic/scaffold/templates/mongoid_model.rb +30 -0
  82. data/lib/generators/scaffold_logic/scaffold/templates/tests/rspec/actions/create.rb +10 -0
  83. data/lib/generators/scaffold_logic/scaffold/templates/tests/rspec/actions/destroy.rb +5 -0
  84. data/lib/generators/scaffold_logic/scaffold/templates/tests/rspec/actions/edit.rb +4 -0
  85. data/lib/generators/scaffold_logic/scaffold/templates/tests/rspec/actions/index.rb +5 -0
  86. data/lib/generators/scaffold_logic/scaffold/templates/tests/rspec/actions/new.rb +4 -0
  87. data/lib/generators/scaffold_logic/scaffold/templates/tests/rspec/actions/show.rb +4 -0
  88. data/lib/generators/scaffold_logic/scaffold/templates/tests/rspec/actions/update.rb +11 -0
  89. data/lib/generators/scaffold_logic/scaffold/templates/tests/rspec/controller.rb +12 -0
  90. data/lib/generators/scaffold_logic/scaffold/templates/tests/rspec/model.rb +5 -0
  91. data/lib/generators/scaffold_logic/scaffold/templates/tests/shoulda/actions/create.rb +13 -0
  92. data/lib/generators/scaffold_logic/scaffold/templates/tests/shoulda/actions/destroy.rb +8 -0
  93. data/lib/generators/scaffold_logic/scaffold/templates/tests/shoulda/actions/edit.rb +6 -0
  94. data/lib/generators/scaffold_logic/scaffold/templates/tests/shoulda/actions/index.rb +6 -0
  95. data/lib/generators/scaffold_logic/scaffold/templates/tests/shoulda/actions/new.rb +6 -0
  96. data/lib/generators/scaffold_logic/scaffold/templates/tests/shoulda/actions/show.rb +6 -0
  97. data/lib/generators/scaffold_logic/scaffold/templates/tests/shoulda/actions/update.rb +13 -0
  98. data/lib/generators/scaffold_logic/scaffold/templates/tests/shoulda/controller.rb +5 -0
  99. data/lib/generators/scaffold_logic/scaffold/templates/tests/shoulda/model.rb +7 -0
  100. data/lib/generators/scaffold_logic/scaffold/templates/tests/testunit/actions/create.rb +11 -0
  101. data/lib/generators/scaffold_logic/scaffold/templates/tests/testunit/actions/destroy.rb +6 -0
  102. data/lib/generators/scaffold_logic/scaffold/templates/tests/testunit/actions/edit.rb +4 -0
  103. data/lib/generators/scaffold_logic/scaffold/templates/tests/testunit/actions/index.rb +4 -0
  104. data/lib/generators/scaffold_logic/scaffold/templates/tests/testunit/actions/new.rb +4 -0
  105. data/lib/generators/scaffold_logic/scaffold/templates/tests/testunit/actions/show.rb +4 -0
  106. data/lib/generators/scaffold_logic/scaffold/templates/tests/testunit/actions/update.rb +11 -0
  107. data/lib/generators/scaffold_logic/scaffold/templates/tests/testunit/controller.rb +5 -0
  108. data/lib/generators/scaffold_logic/scaffold/templates/tests/testunit/model.rb +7 -0
  109. data/lib/generators/scaffold_logic/scaffold/templates/views/erb/_form.html.erb +39 -0
  110. data/lib/generators/scaffold_logic/scaffold/templates/views/erb/edit.html.erb +5 -0
  111. data/lib/generators/scaffold_logic/scaffold/templates/views/erb/index.html.erb +32 -0
  112. data/lib/generators/scaffold_logic/scaffold/templates/views/erb/new.html.erb +5 -0
  113. data/lib/generators/scaffold_logic/scaffold/templates/views/erb/show.html.erb +22 -0
  114. data/lib/scaffold_logic.rb +198 -0
  115. data/lib/scaffold_logic/data_import.rb +80 -0
  116. data/lib/scaffold_logic/form_helper.rb +148 -0
  117. data/lib/scaffold_logic/helper.rb +174 -0
  118. data/lib/scaffold_logic/menu_helper.rb +27 -0
  119. data/lib/scaffold_logic/tab_interface_helper.rb +125 -0
  120. data/scaffold_logic.gemspec +154 -0
  121. metadata +184 -0
@@ -0,0 +1,80 @@
1
+ # Adapted from http://paulbarry.com/articles/2008/04/19/importing-data-with-rails
2
+
3
+ require 'faster_csv' if Object.const_defined?('FasterCSV')
4
+
5
+ module ScaffoldLogic
6
+ class DataImport
7
+ attr_reader :file, :fields, :row_map
8
+
9
+ # Class Methods ==================================================================================
10
+ def self.run(file)
11
+ new(file).run
12
+ end
13
+
14
+ def self.save(upload)
15
+ # create file path
16
+ _path = File.join('tmp', upload['datafile'].original_filename)
17
+
18
+ # write file
19
+ File.open(_path, 'wb') { |f| f.write(upload['datafile'].read) }
20
+
21
+ self.run(_path)
22
+ end
23
+
24
+ # Instance Methods ===============================================================================
25
+ def initialize(file)
26
+ @file = file
27
+ raise 'You must specify a file' unless @file
28
+ end
29
+
30
+ def initialize_row!
31
+ unless @fields_initialized
32
+ initialize_fields!
33
+ else
34
+ initialize_row_map!
35
+ process_row
36
+ end
37
+ end
38
+
39
+ def create_from_row( model )
40
+ model.create(row_map)
41
+ end
42
+
43
+ def run
44
+ @errors = []
45
+ @row_index = 1
46
+
47
+ FasterCSV.foreach(file, :col_sep => "\t", :row_sep => :auto) do |@row|
48
+ initialize_row!
49
+ @row_index += 1
50
+ end
51
+
52
+ @errors
53
+ end
54
+
55
+ def valid_row?
56
+ @missing_fields = []
57
+
58
+ @required_fields.each do |field|
59
+ @missing_fields << field if row_map[field].blank?
60
+ end
61
+
62
+ @missing_fields.empty?
63
+ end
64
+
65
+ private
66
+
67
+ def initialize_fields!
68
+ @fields = @row.map{ |f| f && f.strip.downcase.to_sym }
69
+ @fields_initialized = true
70
+ end
71
+
72
+ def initialize_row_map!
73
+ @row_map ||= {}
74
+ @row_map.clear
75
+ @row.each_with_index do |_c, _i|
76
+ @row_map[fields[_i]] = _c && _c.strip
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,148 @@
1
+ module ScaffoldLogic
2
+ module FormHelper
3
+ SELECT_PROMPT_OPTION = '<option>Select...</option>'
4
+
5
+ # Returns a check mark.
6
+ #
7
+ # Usage:
8
+ #
9
+ # <%= checkmark -%>
10
+ def checkmark
11
+ %{<div class="checkmark"></div>}.html_safe
12
+ end
13
+
14
+ def countdown_field(field_id,update_id,max,options = {})
15
+ function = "$('#{update_id}').innerHTML = (#{max} - $F('#{field_id}').length);"
16
+ count_field_tag(field_id,function,options)
17
+ end
18
+
19
+ def count_field(field_id,update_id,options = {})
20
+ function = "$('#{update_id}').innerHTML = $F('#{field_id}').length;"
21
+ count_field_tag(field_id,function,options)
22
+ end
23
+
24
+ def count_field_tag(field_id,function,options = {})
25
+ %{
26
+ <script type="text/javascript">
27
+ Event.observe($('#{field_id}'), 'keydown', function (){ #{function} });
28
+ </script>
29
+ }.html_safe
30
+ end
31
+
32
+ # Returns a simulated text-field for read-only versions of a form.
33
+ #
34
+ # Usage:
35
+ #
36
+ # <%= faux_field 'Name', @user.name -%>
37
+ def faux_field(label, content, options={:field_id => nil, :help => nil})
38
+ if options[:help]
39
+ options[:field_id] ||= "field_#{Time.zone.now.to_i}#{rand(10000)}"
40
+ %{#{tag_for_label_with_inline_help label, options[:field_id], options[:help]}<div class="faux_field">#{content}</div>}.html_safe
41
+ else
42
+ %{<label>#{label}</label><div class="faux_field">#{content}</div>}.html_safe
43
+ end
44
+ end
45
+
46
+ # Returns a legend tag that renders correctly in all browsers.
47
+ #
48
+ # Usage:
49
+ #
50
+ # <%= legend_tag "Report Criteria" -%>
51
+ #
52
+ # With help text:
53
+ #
54
+ # <%= legend_tag "Report Criteria", :help => "Some descriptive copy here." -%>
55
+ # <span id="hide_or_show_backlinks" class="show_link" style="background-color: #999999;
56
+ # border: 1px solid #999999;" onclick="javascript:hide_or_show('backlinks');"></span>Backlinks (<%=
57
+ # @google_results.size -%>)
58
+ # <%- end -%>
59
+ #
60
+ # Recommended CSS to support display of help icon and text:
61
+ #
62
+ # .help_icon {
63
+ # display: block;
64
+ # float: left;
65
+ # margin-top: -16px;
66
+ # margin-left: 290px;
67
+ # border-left: 1px solid #444444;
68
+ # padding: 3px 6px;
69
+ # cursor: pointer;
70
+ # }
71
+ #
72
+ # div.popup_help {
73
+ # color: #666666;
74
+ # width: 98%;
75
+ # background: #ffffff;
76
+ # padding: 1em;
77
+ # border: 1px solid #999999;
78
+ # margin: 1em 0em;
79
+ # }
80
+ def legend_tag(text, options={})
81
+ options[:id] ||= "#{text.downcase.gsub(' ', '-')}-legend"
82
+ if options[:help]
83
+ _html = %{<div id="#{options[:id]}" class="faux_legend">#{text}<span class="help_icon" onclick="$('#{options[:id]}-help').toggle();">?</span></div>\r}
84
+ _html << %{<div id="#{options[:id]}-help" class="popup_help" style="display: none;">#{options[:help]}<br /></div>\r}
85
+ else
86
+ _html = %{<div id="#{options[:id]}" class="faux_legend">#{text}</div>\r}
87
+ end
88
+ _html.gsub!(/ id=""/,'')
89
+ _html.gsub!(/ class=""/,'')
90
+ _html.html_safe
91
+ end
92
+
93
+ # Create a set of tags for displaying a field label with inline help.
94
+ # Field label text is appended with a ? icon, which responds to a click
95
+ # by showing or hiding the provided help text.
96
+ #
97
+ # Sample usage:
98
+ #
99
+ # <%= 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.' %>
100
+ #
101
+ # Yields:
102
+ #
103
+ # <label for="rel_frequency">Relative Frequency: <%= image_tag "/images/help_icon.png", :onclick => "$('rel_frequency_help').toggle();", :class => 'inline_icon' %></label>
104
+ # <div class="inline_help" id="rel_frequency_help" style="display: none;">
105
+ # <p>Relative frequency of search traffic for this keyword across multiple search engines, as measured by WordTracker.</p>
106
+ # </div>
107
+ def tag_for_label_with_inline_help( label_text, field_id, help_text )
108
+ _html = ""
109
+ _html << %{<label for="#{field_id}">#{label_text}}
110
+ _html << %{<img src="/images/icons/help_icon.png" onclick="$('#{field_id}_help').toggle();" class='inline_icon' />}
111
+ _html << %{</label>}
112
+ _html << %{<div class="inline_help" id="#{field_id}_help" style="display: none;">}
113
+ _html << %{<p>#{help_text}</p>}
114
+ _html << %{</div>}
115
+ _html
116
+ end
117
+
118
+ # Create a set of tags for displaying a field label followed by instructions.
119
+ # The instructions are displayed on a new line following the field label.
120
+ #
121
+ # Usage:
122
+ #
123
+ # <%= tag_for_label_with_instructions 'Status', 'is_active', 'Only active widgets will be visible to the public.' %>
124
+ #
125
+ # Yields:
126
+ #
127
+ # <label for="is_active">
128
+ # Status
129
+ # <span class="instructions">Only active widgets will be visible to the public.</span>
130
+ # </label>
131
+ def tag_for_label_with_instructions( label_text, field_id, instructions )
132
+ _html = ""
133
+ _html << %{<label for="#{field_id}">#{label_text}}
134
+ _html << %{<span class="instructions">#{instructions}</span>}
135
+ _html << %{</label>}
136
+ _html
137
+ end
138
+
139
+ # Returns a string of HTML option tags for the given array of option values. Specify the selected value for stickiness.
140
+ #
141
+ # Usage:
142
+ #
143
+ # <%= select_tag :user, tags_for_option_values(User.all.map{ |c| [c.name, c.id] }, params[:user]) -%>
144
+ def tags_for_option_values( a, selected = nil, prompt_option = SELECT_PROMPT_OPTION )
145
+ "#{prompt_option}#{a.map{ |_e| _flag = _e[1].to_s == selected ? 'selected="1"' : ''; _e.is_a?(Array) ? "<option value=\"#{_e[1]}\" #{_flag}>#{_e[0]}</option>" : "<option>#{_e}</option>" }}".html_safe
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,174 @@
1
+ module ScaffoldLogic
2
+ module Helper
3
+ # Returns true if the current request's action matches the specified string or regular expression.
4
+ def action?( expression )
5
+ !! ( expression.class == Regexp ? controller.action_name =~ expression : controller.action_name == expression )
6
+ end
7
+
8
+ # Returns true if the current request's controller matches the specified string or regular expression.
9
+ def controller?( expression )
10
+ !! ( expression.class == Regexp ? controller.controller_name =~ expression : controller.controller_name == expression )
11
+ end
12
+
13
+ def meta_description(content=nil)
14
+ content_for(:meta_description) { content } unless content.blank?
15
+ end
16
+
17
+ def meta_keywords(content=nil)
18
+ content_for(:meta_keywords) { content } unless content.blank?
19
+ end
20
+
21
+ # Display admin links for standard CRUD actions. Action symbols follow the convention in
22
+ # routes.rb. The controller must be namespaced as Admin::MyController.
23
+ #
24
+ # Use in index views like this:
25
+ #
26
+ # <%- @models.each do |model| -%>
27
+ # <td class="crud_links"><%= admin_crud_links(model, [:destroy, :edit]) -%></td>
28
+ # <%- end -%>
29
+ def admin_crud_links(model, actions)
30
+ crud_links_for_actions_and_paths actions.map{ |a| {a => eval((a == :destroy || a == :show) ? "admin_#{model.class.name.underscore}_path(model)" : "#{a.to_s}_admin_#{model.class.name.underscore}_path(model)") } }.inject({}) {|a, b| a.merge(b)}
31
+ end
32
+
33
+ # Display links for standard CRUD actions. Action symbols follow the convention in routes.rb.
34
+ #
35
+ # Use in index views like this:
36
+ #
37
+ # <%- @models.each do |model| -%>
38
+ # <td class="crud_links"><%= crud_links(model, [:edit, :show]) -%></td>
39
+ # <%- end -%>
40
+ def crud_links(model, actions)
41
+ crud_links_for_actions_and_paths actions.map{ |a| {a => eval((a == :destroy || a == :show) ? "#{model.class.name.underscore}_path(model)" : "#{a.to_s}_#{model.class.name.underscore}_path(model)") } }.inject({}) {|a, b| a.merge(b)}
42
+ end
43
+
44
+ # Display links for the specified hash of CRUD actions and paths. Action symbols follow the
45
+ # convention in routes.rb.
46
+ #
47
+ # Use in index views like this:
48
+ #
49
+ # <td class="crud_links"><%= crud_links_for_actions_and_paths(:show => model_path) -%></td>
50
+ def crud_links_for_actions_and_paths(actions_and_paths)
51
+ _html = ''
52
+
53
+ [:show, :edit, :destroy].each do |action|
54
+ next unless actions_and_paths.key?(action)
55
+
56
+ if action == :show
57
+ _html << link_to(image_tag('icons/view.png', :class => 'crud_icon', :width => 14, :height => 14), actions_and_paths[action], :title => "View")
58
+ elsif action == :edit
59
+ _html << link_to(image_tag('icons/edit.png', :class => 'crud_icon', :width => 14, :height => 14), actions_and_paths[action], :title => "Edit")
60
+ elsif action == :destroy
61
+ _html << link_to(image_tag('icons/delete.png', :class => 'crud_icon', :width => 14, :height => 14), actions_and_paths[action], :confirm => 'Are you sure? This action cannot be undone.', :method => :delete, :title => "Delete")
62
+ end
63
+ end
64
+
65
+ _html.html_safe
66
+ end
67
+
68
+ # Returns a navigation link.
69
+ #
70
+ # Usage:
71
+ # <ul>
72
+ # <%= nav_link( root_path, 'Home', 'home' ) -%>
73
+ # </ul>
74
+ def nav_link(url, link_text, id, options = {})
75
+ %{
76
+ <li id="#{id}" class="#{@active_tab == id || options[:active] ? 'here' : ''}" onclick="javascript:window.location='#{url}';">
77
+ <a href="#{url}" title="#{link_text}">#{link_text}</a>
78
+ </li>
79
+ }.html_safe
80
+ end
81
+
82
+ def nav_link_with_dropdowns(url, link_text, id, options = {}, &proc)
83
+ concat %{<li id="#{id}" class="#{@active_tab == id || options[:active] ? 'here' : ''}" onclick="javascript:window.location='#{url}';"><a href="#{url}" title="#{link_text}">#{link_text}</a>}.html_safe
84
+ yield
85
+ concat %{</li>}.html_safe
86
+ return ''
87
+ end
88
+
89
+ # Returns a link_to tag with sorting parameters that can be used with ActiveRecord.order_by.
90
+ #
91
+ # To use standard resources, specify the resources as a plural symbol:
92
+ # sort_link(:users, 'email', params)
93
+ #
94
+ # To use resources aliased with :as (in routes.rb), specify the aliased route as a string.
95
+ # sort_link('users_admin', 'email', params)
96
+ #
97
+ # You can override the link's label by adding a labels hash to your params in the controller:
98
+ # params[:labels] = {'user_id' => 'User'}
99
+ def sort_link(model, field, params, html_options={})
100
+ if (field.to_sym == params[:by] || field == params[:by]) && params[:dir] == "asc"
101
+ classname = "arrow-asc"
102
+ dir = "desc"
103
+ elsif (field.to_sym == params[:by] || field == params[:by])
104
+ classname = "arrow-desc"
105
+ dir = "asc"
106
+ else
107
+ dir = "asc"
108
+ end
109
+
110
+ options = {
111
+ :anchor => html_options[:anchor],
112
+ :by => field,
113
+ :dir => dir,
114
+ :search => params[:search],
115
+ :category => params[:category],
116
+ :show => params[:show]
117
+ }
118
+
119
+ options[:show] = params[:show] unless params[:show].blank? || params[:show] == 'all'
120
+
121
+ html_options = {
122
+ :class => "#{classname} #{html_options[:class]}",
123
+ :style => "color: white; font-weight: #{params[:by] == field ? "bold" : "normal"}; #{html_options[:style]}",
124
+ :title => "Sort by this field"
125
+ }
126
+
127
+ field_name = params[:labels] && params[:labels][field] ? params[:labels][field] : field.titleize
128
+
129
+ _link = model.is_a?(Symbol) ? eval("#{model}_url(options)") : "/#{model}?#{options.to_params}"
130
+ link_to(field_name, _link, html_options)
131
+ end
132
+
133
+ # Returns a navigation link.
134
+ # <b>DEPRECATED:</b> Please use <tt>nav_link</tt> instead.
135
+ def tab_for(link, link_title, tab_name, options = {})
136
+ nav_link link, link_title, tab_name, options
137
+ end
138
+ end
139
+ end
140
+
141
+ class Hash
142
+ def to_params
143
+ params = ''
144
+ stack = []
145
+
146
+ each do |k, v|
147
+ next if v.blank?
148
+
149
+ if v.is_a?(Hash)
150
+ stack << [k,v]
151
+ elsif v.is_a?(Array)
152
+ v.each{|val| stack << ["#{k}[]",v]}
153
+ else
154
+ params << "#{k}=#{v}&"
155
+ end
156
+ end
157
+
158
+ stack.each do |parent, hash|
159
+ hash.each do |k, v|
160
+ next if v.blank?
161
+
162
+ if v.is_a?(Hash)
163
+ stack << ["#{parent}[#{k}]", v]
164
+ else
165
+ params << "#{parent}[#{k}]=#{v}&"
166
+ end
167
+ end
168
+ end
169
+
170
+ params.chop!
171
+ params
172
+ end
173
+
174
+ end
@@ -0,0 +1,27 @@
1
+ module ScaffoldLogic
2
+ module MenuHelper
3
+
4
+ # Returns an admin menu item.
5
+ #
6
+ # Usage:
7
+ #
8
+ # menu_item(
9
+ # :heading => 'Reports',
10
+ # :url => admin_reports_path
11
+ # )
12
+ def menu_item(args)
13
+ raise ArgumentError, "Missing required values! You must pass a heading and url." unless args[:heading] && args[:url]
14
+ _id = args[:heading].downcase.gsub(/[^a-z]/, '_')
15
+ %{
16
+ <div class="menu_icon" id="#{_id}">
17
+ <h2><a href="#{args[:url]}" title="#{args[:heading]}">#{args[:heading]}</a></h2>
18
+ #{args[:description]}
19
+ <script type="text/javascript">
20
+ Event.observe($('#{_id}'), 'click', function (){ window.location = '#{args[:url]}'; });
21
+ </script>
22
+ </div>
23
+ }.html_safe
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,125 @@
1
+ module ScaffoldLogic
2
+ module TabInterfaceHelper
3
+ # Returns formatted tabs with appropriate JS for activation. Use in conjunction with tab_body.
4
+ #
5
+ # Usage:
6
+ #
7
+ # <%- tabset do -%>
8
+ # <%= tab_tag :id => 'ppc_ads', :label => 'PPC Ads', :state => 'active' %>
9
+ # <%= tab_tag :id => 'budget' %>
10
+ # <%= tab_tag :id => 'geotargeting' %>
11
+ # <%- end -%>
12
+ #
13
+ def tabset(&block)
14
+ concat %{
15
+ <div class="jump_links">
16
+ <ul>
17
+ }.html_safe
18
+ yield
19
+ concat %{
20
+ </ul>
21
+ </div>
22
+ <br style="clear: both;" /><br />
23
+ <input type="hidden" id="show_tab" />
24
+ <script type="text/javascript">
25
+ function hide_all_tabs() { $$('.tab_block').invoke('hide'); }
26
+ function activate_tab(tab) {
27
+ $$('.tab_control').each(function(elem){ elem.className = 'tab_control'});
28
+ $('show_' + tab).className = 'tab_control active';
29
+ hide_all_tabs();
30
+ $(tab).toggle();
31
+ $('show_tab').value = tab
32
+ }
33
+ function sticky_tab() { if (location.hash) { activate_tab(location.hash.gsub('#','')); } }
34
+ Event.observe(window, 'load', function() { sticky_tab(); });
35
+ </script>
36
+ }.html_safe
37
+ return ''
38
+ end
39
+
40
+ # Returns a tab body corresponding to tabs in a tabset. Make sure that the id of the tab_body
41
+ # matches the id provided to the tab_tag in the tabset block.
42
+ #
43
+ # Usage:
44
+ #
45
+ # <%- tab_body :id => 'ppc_ads', :label => 'PPC Ad Details' do -%>
46
+ # PPC ads form here.
47
+ # <%- end -%>
48
+ #
49
+ # <%- tab_body :id => 'budget' do -%>
50
+ # Budget form here.
51
+ # <%- end -%>
52
+ #
53
+ # <%- tab_body :id => 'geotargeting' do -%>
54
+ # Geotargeting form here.
55
+ # <%- end -%>
56
+ #
57
+ def tab_body(args, &proc)
58
+ concat %{<div id="#{args[:id]}" class="tab_block form_container" style="display: #{args[:display] || 'none'};">}.html_safe
59
+ concat %{#{legend_tag(args[:label] || args[:id].titleize, :help => args[:help] )}}.html_safe
60
+ concat %{<a name="#{args[:id]}"></a><br />}.html_safe
61
+ yield
62
+ concat %{</div>}.html_safe
63
+ return ''
64
+ end
65
+
66
+ # Returns the necessary HTML for a particular tab. Use inside a tabset block.
67
+ # Override the default tab label by specifying a :label parameter.
68
+ # Indicate that the tab should be active by setting its :state to 'active'.
69
+ # (NOTE: You must define a corresponding CSS style for active tabs.)
70
+ #
71
+ # Usage:
72
+ #
73
+ # <%= tab_tag :id => 'ppc_ads', :label => 'PPC Ads', :state => 'active' %>
74
+ #
75
+ def tab_tag(args, *css_class)
76
+ %{<li id="show_#{args[:id]}" class="tab_control #{args[:state]}" onclick="activate_tab('#{args[:id]}');"><a href="##{args[:id]}">#{args[:label] || args[:id].to_s.titleize}</a></li>}.html_safe
77
+ end
78
+
79
+ # Create a set of tags for displaying a field label with inline help.
80
+ # Field label text is appended with a ? icon, which responds to a click
81
+ # by showing or hiding the provided help text.
82
+ #
83
+ # Sample usage:
84
+ #
85
+ # <%= 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.' %>
86
+ #
87
+ # Yields:
88
+ #
89
+ # <label for="rel_frequency">Relative Frequency: <%= image_tag "/images/help_icon.png", :onclick => "$('rel_frequency_help').toggle();", :class => 'inline_icon' %></label><br />
90
+ # <div class="inline_help" id="rel_frequency_help" style="display: none;">
91
+ # <p>Relative frequency of search traffic for this keyword across multiple search engines, as measured by WordTracker.</p>
92
+ # </div>
93
+ def tag_for_label_with_inline_help( label_text, field_id, help_text )
94
+ _html = ""
95
+ _html << %{<label for="#{field_id}">#{label_text}}
96
+ _html << %{<img src="/images/icons/help_icon.png" onclick="$('#{field_id}_help').toggle();" class='inline_icon' />}
97
+ _html << %{</label><br />}
98
+ _html << %{<div class="inline_help" id="#{field_id}_help" style="display: none;">}
99
+ _html << %{<p>#{help_text}</p>}
100
+ _html << %{</div>}
101
+ _html
102
+ end
103
+
104
+ # Create a set of tags for displaying a field label followed by instructions.
105
+ # The instructions are displayed on a new line following the field label.
106
+ #
107
+ # Usage:
108
+ #
109
+ # <%= tag_for_label_with_instructions 'Status', 'is_active', 'Only active widgets will be visible to the public.' %>
110
+ #
111
+ # Yields:
112
+ #
113
+ # <label for="is_active">
114
+ # Status<br />
115
+ # <span class="instructions">Only active widgets will be visible to the public.</span>
116
+ # <label><br />
117
+ def tag_for_label_with_instructions( label_text, field_id, instructions )
118
+ _html = ""
119
+ _html << %{<label for="#{field_id}">#{label_text}}
120
+ _html << %{<span class="instructions">#{instructions}</span>}
121
+ _html << %{</label><br />}
122
+ _html
123
+ end
124
+ end
125
+ end