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.
- data/.document +5 -0
- data/Capfile +4 -0
- data/README.rdoc +29 -0
- data/Rakefile +51 -0
- data/VERSION +1 -0
- data/config/deploy.rb +41 -0
- data/lib/generators/scaffold_logic/layout/USAGE +7 -0
- data/lib/generators/scaffold_logic/layout/layout_generator.rb +38 -0
- data/lib/generators/scaffold_logic/layout/templates/_nav_tabs.html.erb +3 -0
- data/lib/generators/scaffold_logic/layout/templates/images/icons/add.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/icons/collapsed.gif +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/icons/delete.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/icons/drag.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/icons/edit.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/icons/expanded.gif +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/icons/help_icon.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/icons/link_icon.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/icons/move.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/icons/move_white.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/icons/note.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/icons/note_white.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/icons/notification_icon_sprite.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/icons/spinner.gif +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/icons/view.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/icons/warning.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/icons/warning_2.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/icons/warning_box.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/icons/warning_icon.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/icons/warning_white.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/layout/arrow_asc.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/layout/arrow_desc.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/layout/back.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/layout/black_bar.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/layout/breadcrumb_bg.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/layout/button_bg.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/layout/content_left_bg.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/layout/content_right_bg.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/layout/credit_cards.gif +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/layout/footer_bg.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/layout/h1_bg.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/layout/h2_bg.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/layout/h2_bg_for_table.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/layout/header_bg_grey.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/layout/header_bg_purple.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/layout/legend_bg.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/layout/menu_box_bg.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/layout/shadow_border.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/layout/shadow_border_2.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/layout/shadow_border_3.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/layout/shadow_border_4.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/layout/tab.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/layout/tab_active.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/layout/table_header.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/layout/text_field_bg.jpg +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/layout/text_field_error_bg.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/layout/th_bg.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/layout/th_bg_selected.png +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/src/black_bar.psd +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/src/branding.psd +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/src/legend_bg.psd +0 -0
- data/lib/generators/scaffold_logic/layout/templates/images/src/menu_icons.psd +0 -0
- data/lib/generators/scaffold_logic/layout/templates/layout.html.erb +49 -0
- data/lib/generators/scaffold_logic/layout/templates/layout_helper.rb +16 -0
- data/lib/generators/scaffold_logic/layout/templates/stylesheets/application.css +881 -0
- data/lib/generators/scaffold_logic/layout/templates/stylesheets/core.css +1146 -0
- data/lib/generators/scaffold_logic/layout/templates/stylesheets/core_ie.css +52 -0
- data/lib/generators/scaffold_logic/layout/templates/stylesheets/csshover3.htc +14 -0
- data/lib/generators/scaffold_logic/scaffold/USAGE +48 -0
- data/lib/generators/scaffold_logic/scaffold/scaffold_generator.rb +230 -0
- data/lib/generators/scaffold_logic/scaffold/templates/actions/create.rb +9 -0
- data/lib/generators/scaffold_logic/scaffold/templates/actions/destroy.rb +6 -0
- data/lib/generators/scaffold_logic/scaffold/templates/actions/edit.rb +3 -0
- data/lib/generators/scaffold_logic/scaffold/templates/actions/index.rb +3 -0
- data/lib/generators/scaffold_logic/scaffold/templates/actions/new.rb +3 -0
- data/lib/generators/scaffold_logic/scaffold/templates/actions/show.rb +3 -0
- data/lib/generators/scaffold_logic/scaffold/templates/actions/update.rb +9 -0
- data/lib/generators/scaffold_logic/scaffold/templates/controller.rb +7 -0
- data/lib/generators/scaffold_logic/scaffold/templates/helper.rb +2 -0
- data/lib/generators/scaffold_logic/scaffold/templates/migration.rb +16 -0
- data/lib/generators/scaffold_logic/scaffold/templates/model.rb +18 -0
- data/lib/generators/scaffold_logic/scaffold/templates/mongoid_model.rb +30 -0
- data/lib/generators/scaffold_logic/scaffold/templates/tests/rspec/actions/create.rb +10 -0
- data/lib/generators/scaffold_logic/scaffold/templates/tests/rspec/actions/destroy.rb +5 -0
- data/lib/generators/scaffold_logic/scaffold/templates/tests/rspec/actions/edit.rb +4 -0
- data/lib/generators/scaffold_logic/scaffold/templates/tests/rspec/actions/index.rb +5 -0
- data/lib/generators/scaffold_logic/scaffold/templates/tests/rspec/actions/new.rb +4 -0
- data/lib/generators/scaffold_logic/scaffold/templates/tests/rspec/actions/show.rb +4 -0
- data/lib/generators/scaffold_logic/scaffold/templates/tests/rspec/actions/update.rb +11 -0
- data/lib/generators/scaffold_logic/scaffold/templates/tests/rspec/controller.rb +12 -0
- data/lib/generators/scaffold_logic/scaffold/templates/tests/rspec/model.rb +5 -0
- data/lib/generators/scaffold_logic/scaffold/templates/tests/shoulda/actions/create.rb +13 -0
- data/lib/generators/scaffold_logic/scaffold/templates/tests/shoulda/actions/destroy.rb +8 -0
- data/lib/generators/scaffold_logic/scaffold/templates/tests/shoulda/actions/edit.rb +6 -0
- data/lib/generators/scaffold_logic/scaffold/templates/tests/shoulda/actions/index.rb +6 -0
- data/lib/generators/scaffold_logic/scaffold/templates/tests/shoulda/actions/new.rb +6 -0
- data/lib/generators/scaffold_logic/scaffold/templates/tests/shoulda/actions/show.rb +6 -0
- data/lib/generators/scaffold_logic/scaffold/templates/tests/shoulda/actions/update.rb +13 -0
- data/lib/generators/scaffold_logic/scaffold/templates/tests/shoulda/controller.rb +5 -0
- data/lib/generators/scaffold_logic/scaffold/templates/tests/shoulda/model.rb +7 -0
- data/lib/generators/scaffold_logic/scaffold/templates/tests/testunit/actions/create.rb +11 -0
- data/lib/generators/scaffold_logic/scaffold/templates/tests/testunit/actions/destroy.rb +6 -0
- data/lib/generators/scaffold_logic/scaffold/templates/tests/testunit/actions/edit.rb +4 -0
- data/lib/generators/scaffold_logic/scaffold/templates/tests/testunit/actions/index.rb +4 -0
- data/lib/generators/scaffold_logic/scaffold/templates/tests/testunit/actions/new.rb +4 -0
- data/lib/generators/scaffold_logic/scaffold/templates/tests/testunit/actions/show.rb +4 -0
- data/lib/generators/scaffold_logic/scaffold/templates/tests/testunit/actions/update.rb +11 -0
- data/lib/generators/scaffold_logic/scaffold/templates/tests/testunit/controller.rb +5 -0
- data/lib/generators/scaffold_logic/scaffold/templates/tests/testunit/model.rb +7 -0
- data/lib/generators/scaffold_logic/scaffold/templates/views/erb/_form.html.erb +39 -0
- data/lib/generators/scaffold_logic/scaffold/templates/views/erb/edit.html.erb +5 -0
- data/lib/generators/scaffold_logic/scaffold/templates/views/erb/index.html.erb +32 -0
- data/lib/generators/scaffold_logic/scaffold/templates/views/erb/new.html.erb +5 -0
- data/lib/generators/scaffold_logic/scaffold/templates/views/erb/show.html.erb +22 -0
- data/lib/scaffold_logic.rb +198 -0
- data/lib/scaffold_logic/data_import.rb +80 -0
- data/lib/scaffold_logic/form_helper.rb +148 -0
- data/lib/scaffold_logic/helper.rb +174 -0
- data/lib/scaffold_logic/menu_helper.rb +27 -0
- data/lib/scaffold_logic/tab_interface_helper.rb +125 -0
- data/scaffold_logic.gemspec +154 -0
- 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
|