active_scaffold 3.1.20 → 3.2.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 (95) hide show
  1. data/app/assets/javascripts/jquery/active_scaffold.js +4 -1
  2. data/app/assets/javascripts/prototype/active_scaffold.js +4 -1
  3. data/app/assets/stylesheets/{active_scaffold.scss~ → active_scaffold.css.scss} +5 -2
  4. data/app/assets/stylesheets/{active_scaffold_colors.scss → active_scaffold_colors.css.scss} +4 -0
  5. data/app/assets/stylesheets/active_scaffold_extensions.css.erb +2 -0
  6. data/app/assets/stylesheets/active_scaffold_images.css.scss +43 -0
  7. data/lib/active_scaffold/actions/core.rb +1 -0
  8. data/lib/active_scaffold/actions/nested.rb +0 -1
  9. data/lib/active_scaffold/extensions/action_view_rendering.rb +1 -1
  10. data/lib/active_scaffold/helpers/form_column_helpers.rb +1 -0
  11. data/lib/active_scaffold/version.rb +2 -2
  12. data/test/mock_app/.gitignore +2 -0
  13. metadata +86 -164
  14. data/app/assets/javascripts/active_scaffold.js.erb~ +0 -16
  15. data/app/assets/javascripts/jquery/active_scaffold.js~ +0 -1053
  16. data/app/assets/javascripts/jquery/draggable_lists.js~ +0 -27
  17. data/app/assets/javascripts/prototype/active_scaffold.js~ +0 -1037
  18. data/app/assets/stylesheets/active_scaffold.css.erb +0 -11
  19. data/app/assets/stylesheets/active_scaffold.css.erb~ +0 -11
  20. data/app/assets/stylesheets/active_scaffold.css.scss.erb~ +0 -1120
  21. data/app/assets/stylesheets/active_scaffold.css.scss~ +0 -11
  22. data/app/assets/stylesheets/active_scaffold.css~ +0 -11
  23. data/app/assets/stylesheets/active_scaffold_colors.css +0 -244
  24. data/app/assets/stylesheets/active_scaffold_colors.css.scss~ +0 -481
  25. data/app/assets/stylesheets/active_scaffold_default.css.erb +0 -47
  26. data/app/assets/stylesheets/active_scaffold_default.css.erb~ +0 -57
  27. data/app/assets/stylesheets/active_scaffold_default.css.scss~ +0 -1092
  28. data/app/assets/stylesheets/active_scaffold_default.css~ +0 -923
  29. data/app/assets/stylesheets/active_scaffold_layout.css~ +0 -922
  30. data/app/assets/stylesheets/blue-theme.css~ +0 -1150
  31. data/config/locales/es.yml~ +0 -120
  32. data/frontends/default/views/_action_group.html.erb~ +0 -24
  33. data/frontends/default/views/_base_form.html.erb~ +0 -42
  34. data/frontends/default/views/_form.html.erb~ +0 -26
  35. data/frontends/default/views/_form_association.html.erb~ +0 -19
  36. data/frontends/default/views/_form_association_footer.html.erb~ +0 -48
  37. data/frontends/default/views/_horizontal_subform.html.erb~ +0 -32
  38. data/frontends/default/views/_horizontal_subform_header.html.erb~ +0 -11
  39. data/frontends/default/views/_horizontal_subform_record.html.erb~ +0 -38
  40. data/frontends/default/views/_list_actions.html.erb~ +0 -15
  41. data/frontends/default/views/_list_inline_adapter.html.erb~ +0 -10
  42. data/frontends/default/views/_list_messages.html.erb~ +0 -30
  43. data/frontends/default/views/_list_pagination.html.erb~ +0 -11
  44. data/frontends/default/views/_list_pagination_links.html.erb~ +0 -0
  45. data/frontends/default/views/_list_with_header.html.erb~ +0 -36
  46. data/frontends/default/views/_render_field.js.erb~ +0 -23
  47. data/frontends/default/views/_row.html.erb~ +0 -6
  48. data/frontends/default/views/_show.html.erb~ +0 -8
  49. data/frontends/default/views/_update_form.html.erb~ +0 -6
  50. data/frontends/default/views/_vertical_subform.html.erb~ +0 -12
  51. data/frontends/default/views/add_existing.js.erb~ +0 -18
  52. data/frontends/default/views/add_existing_form.html.erb~ +0 -5
  53. data/frontends/default/views/create.html.erb~ +0 -5
  54. data/frontends/default/views/edit_associated.js.erb~ +0 -13
  55. data/frontends/default/views/on_create.js.erb~ +0 -45
  56. data/frontends/default/views/on_update.js.erb~ +0 -31
  57. data/frontends/default/views/render_field.js.erb~ +0 -1
  58. data/frontends/default/views/search.html.erb~ +0 -5
  59. data/frontends/default/views/show.html.erb~ +0 -5
  60. data/frontends/default/views/update.html.erb~ +0 -8
  61. data/frontends/default/views/update_column.js.erb~ +0 -16
  62. data/lib/active_scaffold.rb~ +0 -373
  63. data/lib/active_scaffold/actions/core.rb~ +0 -203
  64. data/lib/active_scaffold/actions/create.rb~ +0 -148
  65. data/lib/active_scaffold/actions/list.rb~ +0 -196
  66. data/lib/active_scaffold/actions/nested.rb~ +0 -247
  67. data/lib/active_scaffold/actions/search.rb~ +0 -49
  68. data/lib/active_scaffold/actions/subform.rb~ +0 -27
  69. data/lib/active_scaffold/actions/update.rb~ +0 -150
  70. data/lib/active_scaffold/attribute_params.rb~ +0 -203
  71. data/lib/active_scaffold/bridges/date_picker/helper.rb~ +0 -180
  72. data/lib/active_scaffold/bridges/record_select/helpers.rb~ +0 -86
  73. data/lib/active_scaffold/bridges/shared/date_bridge.rb~ +0 -209
  74. data/lib/active_scaffold/config/base.rb~ +0 -72
  75. data/lib/active_scaffold/config/list.rb~ +0 -195
  76. data/lib/active_scaffold/config/nested.rb~ +0 -41
  77. data/lib/active_scaffold/config/search.rb~ +0 -74
  78. data/lib/active_scaffold/constraints.rb~ +0 -186
  79. data/lib/active_scaffold/data_structures/action_columns.rb~ +0 -140
  80. data/lib/active_scaffold/data_structures/action_link.rb~ +0 -179
  81. data/lib/active_scaffold/data_structures/nested_info.rb~ +0 -147
  82. data/lib/active_scaffold/extensions/action_controller_rendering.rb~ +0 -22
  83. data/lib/active_scaffold/extensions/action_view_rendering.rb~ +0 -120
  84. data/lib/active_scaffold/extensions/active_association_reflection.rb~ +0 -22
  85. data/lib/active_scaffold/extensions/cache_association.rb~ +0 -12
  86. data/lib/active_scaffold/extensions/reverse_associations.rb~ +0 -64
  87. data/lib/active_scaffold/extensions/routing_mapper.rb~ +0 -48
  88. data/lib/active_scaffold/extensions/unsaved_associated.rb~ +0 -62
  89. data/lib/active_scaffold/finder.rb~ +0 -370
  90. data/lib/active_scaffold/helpers/controller_helpers.rb~ +0 -92
  91. data/lib/active_scaffold/helpers/form_column_helpers.rb~ +0 -320
  92. data/lib/active_scaffold/helpers/id_helpers.rb~ +0 -123
  93. data/lib/active_scaffold/helpers/list_column_helpers.rb~ +0 -370
  94. data/lib/active_scaffold/helpers/search_column_helpers.rb~ +0 -263
  95. data/lib/active_scaffold/helpers/view_helpers.rb~ +0 -350
@@ -1,320 +0,0 @@
1
- module ActiveScaffold
2
- module Helpers
3
- # Helpers that assist with the rendering of a Form Column
4
- module FormColumnHelpers
5
- # This method decides which input to use for the given column.
6
- # It does not do any rendering. It only decides which method is responsible for rendering.
7
- def active_scaffold_input_for(column, scope = nil, options = {})
8
- options = active_scaffold_input_options(column, scope, options)
9
- options = update_columns_options(column, scope, options)
10
- active_scaffold_render_input(column, options)
11
- end
12
-
13
- alias form_column active_scaffold_input_for
14
-
15
- def active_scaffold_render_input(column, options)
16
- begin
17
- # first, check if the dev has created an override for this specific field
18
- if override_form_field?(column)
19
- send(override_form_field(column), @record, options)
20
- # second, check if the dev has specified a valid form_ui for this column
21
- elsif column.form_ui and override_input?(column.form_ui)
22
- send(override_input(column.form_ui), column, options)
23
- # fallback: we get to make the decision
24
- else
25
- if column.association
26
- if column.form_ui.nil?
27
- # its an association and nothing is specified, we will assume form_ui :select
28
- active_scaffold_input_select(column, options)
29
- else
30
- # if we get here, it's because the column has a form_ui but not one ActiveScaffold knows about.
31
- raise "Unknown form_ui `#{column.form_ui}' for column `#{column.name}'"
32
- end
33
- elsif column.virtual?
34
- options[:value] = format_number_value(@record.send(column.name), column.options) if column.number?
35
- active_scaffold_input_virtual(column, options)
36
-
37
- else # regular model attribute column
38
- # if we (or someone else) have created a custom render option for the column type, use that
39
- if override_input?(column.column.type)
40
- send(override_input(column.column.type), column, options)
41
- # final ultimate fallback: use rails' generic input method
42
- else
43
- # for textual fields we pass different options
44
- text_types = [:text, :string, :integer, :float, :decimal, :date, :time, :datetime]
45
- options = active_scaffold_input_text_options(options) if text_types.include?(column.column.type)
46
- if column.column.type == :string && options[:maxlength].blank?
47
- options[:maxlength] = column.column.limit
48
- options[:size] ||= ActionView::Helpers::InstanceTag::DEFAULT_FIELD_OPTIONS["size"]
49
- end
50
- options[:include_blank] = true if column.column.null and [:date, :datetime, :time].include?(column.column.type)
51
- options[:value] = format_number_value(@record.send(column.name), column.options) if column.number?
52
- text_field(:record, column.name, options.merge(column.options))
53
- end
54
- end
55
- end
56
- rescue Exception => e
57
- logger.error Time.now.to_s + "#{e.inspect} -- on the ActiveScaffold column = :#{column.name} in #{controller.class}"
58
- raise e
59
- end
60
- end
61
-
62
- # the standard active scaffold options used for textual inputs
63
- def active_scaffold_input_text_options(options = {})
64
- options[:autocomplete] = 'off'
65
- options[:class] = "#{options[:class]} text-input".strip
66
- options
67
- end
68
-
69
- # the standard active scaffold options used for class, name and scope
70
- def active_scaffold_input_options(column, scope = nil, options = {})
71
- name = scope ? "record#{scope}[#{column.name}]" : "record[#{column.name}]"
72
-
73
- # Fix for keeping unique IDs in subform
74
- id_control = "record_#{column.name}_#{[params[:eid], params[:id]].compact.join '_'}"
75
- id_control += scope_id(scope) if scope
76
-
77
- { :name => name, :class => "#{column.name}-input", :id => id_control}.merge(options)
78
- end
79
-
80
- def update_columns_options(column, scope, options)
81
- if column.update_columns
82
- form_action = params[:action] == 'edit' ? :update : :create
83
- url_params = {:action => 'render_field', :id => params[:id], :column => column.name}
84
- url_params[:eid] = params[:eid] if params[:eid]
85
- url_params[:controller] = controller.class.active_scaffold_controller_for(@record.class).controller_path if scope
86
- url_params[:scope] = scope if scope
87
-
88
- options[:class] = "#{options[:class]} update_form".strip
89
- options['data-update_url'] = url_for(url_params)
90
- options['data-update_send_form'] = true if column.send_form_on_update_column
91
- end
92
- options
93
- end
94
-
95
- ##
96
- ## Form input methods
97
- ##
98
-
99
- def active_scaffold_input_singular_association(column, html_options)
100
- associated = @record.send(column.association.name)
101
-
102
- select_options = options_for_association(column.association)
103
- select_options.unshift([ associated.to_label, associated.id ]) unless associated.nil? or select_options.find {|label, id| id == associated.id}
104
-
105
- method = column.name
106
- #html_options[:name] += '[id]'
107
- options = {:selected => associated.try(:id), :include_blank => as_(:_select_)}
108
-
109
- html_options.update(column.options[:html_options] || {})
110
- options.update(column.options)
111
- html_options[:name] = "#{html_options[:name]}[]" if (html_options[:multiple] == true && !html_options[:name].to_s.ends_with?("[]"))
112
- select(:record, method, select_options.uniq, options, html_options)
113
- end
114
-
115
- def active_scaffold_input_plural_association(column, options)
116
- associated_options = @record.send(column.association.name).collect {|r| [r.to_label, r.id]}
117
- select_options = associated_options | options_for_association(column.association)
118
- return content_tag(:span, as_(:no_options), :class => options[:class], :id => options[:id]) if select_options.empty?
119
-
120
- active_scaffold_checkbox_list(column, select_options, associated_options.collect {|a| a[1]}, options)
121
- end
122
-
123
- def active_scaffold_checkbox_list(column, select_options, associated_ids, options)
124
- html = content_tag :ul, :class => "#{options[:class]} checkbox-list", :id => options[:id] do
125
- content = "".html_safe
126
- select_options.each_with_index do |option, i|
127
- label, id = option
128
- this_id = "#{options[:id]}_#{i}_id"
129
- content << content_tag(:li) do
130
- check_box_tag("#{options[:name]}[]", id, associated_ids.include?(id), :id => this_id) <<
131
- content_tag(:label, h(label), :for => this_id)
132
- end
133
- end
134
- content
135
- end
136
- html << javascript_tag("new DraggableLists('#{options[:id]}')") if column.options[:draggable_lists]
137
- html
138
- end
139
-
140
- def active_scaffold_translated_option(column, text, value = nil)
141
- value = text if value.nil?
142
- [(text.is_a?(Symbol) ? column.active_record_class.human_attribute_name(text) : text), value]
143
- end
144
-
145
- def active_scaffold_input_enum(column, html_options)
146
- options = { :selected => @record.send(column.name) }
147
- options_for_select = column.options[:options].collect do |text, value|
148
- active_scaffold_translated_option(column, text, value)
149
- end
150
- html_options.update(column.options[:html_options] || {})
151
- options.update(column.options)
152
- select(:record, column.name, options_for_select, options, html_options)
153
- end
154
-
155
- def active_scaffold_input_select(column, html_options)
156
- if column.singular_association?
157
- active_scaffold_input_singular_association(column, html_options)
158
- elsif column.plural_association?
159
- active_scaffold_input_plural_association(column, html_options)
160
- else
161
- active_scaffold_input_enum(column, html_options)
162
- end
163
- end
164
-
165
- def active_scaffold_input_radio(column, html_options)
166
- html_options.update(column.options[:html_options] || {})
167
- column.options[:options].inject('') do |html, (text, value)|
168
- text, value = active_scaffold_translated_option(column, text, value)
169
- html << content_tag(:label, radio_button(:record, column.name, value, html_options.merge(:id => html_options[:id] + '-' + value.to_s)) + text)
170
- end.html_safe
171
- end
172
-
173
- def active_scaffold_input_checkbox(column, options)
174
- check_box(:record, column.name, options.merge(column.options))
175
- end
176
-
177
- def active_scaffold_input_password(column, options)
178
- options = active_scaffold_input_text_options(options)
179
- password_field :record, column.name, options.merge(column.options)
180
- end
181
-
182
- def active_scaffold_input_textarea(column, options)
183
- text_area(:record, column.name, options.merge(:cols => column.options[:cols], :rows => column.options[:rows], :size => column.options[:size]))
184
- end
185
-
186
- def active_scaffold_input_virtual(column, options)
187
- options = active_scaffold_input_text_options(options)
188
- text_field :record, column.name, options.merge(column.options)
189
- end
190
-
191
- #
192
- # Column.type-based inputs
193
- #
194
-
195
- def active_scaffold_input_boolean(column, options)
196
- select_options = []
197
- select_options << [as_(:_select_), nil] if !column.virtual? && column.column.null
198
- select_options << [as_(:true), true]
199
- select_options << [as_(:false), false]
200
-
201
- select_tag(options[:name], options_for_select(select_options, @record.send(column.name)), options)
202
- end
203
-
204
- def onsubmit
205
- end
206
-
207
- ##
208
- ## Form column override signatures
209
- ##
210
-
211
- # add functionality for overriding subform partials from association class path
212
- def override_subform_partial?(column, subform_partial)
213
- template_exists?(override_subform_partial(column, subform_partial), true)
214
- end
215
-
216
- def override_subform_partial(column, subform_partial)
217
- File.join(active_scaffold_controller_for(column.association.klass).controller_path, subform_partial) if column_renders_as(column) == :subform
218
- end
219
-
220
- def override_form_field_partial?(column)
221
- template_exists?(override_form_field_partial(column), true)
222
- end
223
-
224
- # the naming convention for overriding form fields with helpers
225
- def override_form_field_partial(column)
226
- path = active_scaffold_controller_for(column.active_record_class).controller_path
227
- File.join(path, "#{clean_column_name(column.name)}_form_column")
228
- end
229
-
230
- def override_form_field(column)
231
- method_with_class = override_form_field_name(column, true)
232
- return method_with_class if respond_to?(method_with_class)
233
- method = override_form_field_name(column)
234
- method if respond_to?(method)
235
- end
236
- alias_method :override_form_field?, :override_form_field
237
-
238
- # the naming convention for overriding form fields with helpers
239
- def override_form_field_name(column, class_prefix = false)
240
- "#{clean_class_name(column.active_record_class.name) + '_' if class_prefix}#{clean_column_name(column.name)}_form_column"
241
- end
242
-
243
- def override_input?(form_ui)
244
- respond_to?(override_input(form_ui))
245
- end
246
-
247
- # the naming convention for overriding form input types with helpers
248
- def override_input(form_ui)
249
- "active_scaffold_input_#{form_ui}"
250
- end
251
-
252
- def form_partial_for_column(column, renders_as = nil)
253
- renders_as ||= column_renders_as(column)
254
- if override_form_field_partial?(column)
255
- override_form_field_partial(column)
256
- elsif renders_as == :field or override_form_field?(column)
257
- "form_attribute"
258
- elsif renders_as == :subform
259
- "form_association"
260
- elsif renders_as == :hidden
261
- "form_hidden_attribute"
262
- end
263
- end
264
-
265
- def subform_partial_for_column(column)
266
- subform_partial = "#{active_scaffold_config_for(column.association.klass).subform.layout}_subform"
267
- if override_subform_partial?(column, subform_partial)
268
- override_subform_partial(column, subform_partial)
269
- else
270
- subform_partial
271
- end
272
- end
273
-
274
- ##
275
- ## Macro-level rendering decisions for columns
276
- ##
277
-
278
- def column_renders_as(column)
279
- if column.is_a? ActiveScaffold::DataStructures::ActionColumns
280
- return :subsection
281
- elsif column.active_record_class.locking_column.to_s == column.name.to_s or column.form_ui == :hidden
282
- return :hidden
283
- elsif column.association.nil? or column.form_ui or !active_scaffold_config_for(column.association.klass).actions.include?(:subform)
284
- return :field
285
- else
286
- return :subform
287
- end
288
- end
289
-
290
- def column_scope(column)
291
- if column.plural_association?
292
- "[#{column.name}][#{@record.id || generate_temporary_id}]"
293
- else
294
- "[#{column.name}]"
295
- end
296
- end
297
-
298
- def active_scaffold_add_existing_input(options)
299
- if ActiveScaffold.js_framework == :prototype && controller.respond_to?(:record_select_config)
300
- remote_controller = active_scaffold_controller_for(record_select_config.model).controller_path
301
- options.merge!(:controller => remote_controller)
302
- options.merge!(active_scaffold_input_text_options)
303
- record_select_field(options[:name], @record, options)
304
- else
305
- select_options = options_for_select(options_for_association(nested.association)) #unless column.through_association?
306
- select_options ||= options_for_select(active_scaffold_config.model.all.collect {|c| [h(c.to_label), c.id]})
307
- select_tag 'associated_id', ('<option value="">' + as_(:_select_) + '</option>' + select_options).html_safe unless select_options.empty?
308
- end
309
- end
310
-
311
- def active_scaffold_add_existing_label
312
- if controller.respond_to?(:record_select_config)
313
- record_select_config.model.model_name.human
314
- else
315
- active_scaffold_config.model.model_name.human
316
- end
317
- end
318
- end
319
- end
320
- end
@@ -1,123 +0,0 @@
1
- module ActiveScaffold
2
- module Helpers
3
- # A bunch of helper methods to produce the common view ids
4
- module IdHelpers
5
- def id_from_controller(controller)
6
- controller.to_s.gsub("/", "__").html_safe
7
- end
8
-
9
- def controller_id(controller = (params[:eid] || params[:parent_controller] || params[:controller]))
10
- controller_id ||= 'as_' + id_from_controller(controller)
11
- end
12
-
13
- def active_scaffold_id
14
- "#{controller_id}-active-scaffold"
15
- end
16
-
17
- def active_scaffold_content_id
18
- "#{controller_id}-content"
19
- end
20
-
21
- def active_scaffold_tbody_id
22
- "#{controller_id}-tbody"
23
- end
24
-
25
- def active_scaffold_messages_id(options = {})
26
- "#{options[:controller_id] || controller_id}-messages"
27
- end
28
-
29
- def active_scaffold_calculations_id(column = nil)
30
- "#{controller_id}-calculations#{'-' + column.name.to_s if column}"
31
- end
32
-
33
- def empty_message_id
34
- "#{controller_id}-empty-message"
35
- end
36
-
37
- def before_header_id
38
- "#{controller_id}-search-container"
39
- end
40
-
41
- def search_input_id
42
- "#{controller_id}-search-input"
43
- end
44
-
45
- def action_link_id(link_action,link_id)
46
- "#{controller_id}-#{link_action}-#{link_id}-link"
47
- end
48
-
49
- def active_scaffold_column_header_id(column)
50
- name = column.respond_to?(:name) ? column.name : column.to_s
51
- clean_id "#{controller_id}-#{name}-column"
52
- end
53
-
54
- def element_row_id(options = {})
55
- options[:action] ||= params[:action]
56
- options[:id] ||= params[:id]
57
- options[:id] ||= params[:parent_id]
58
- clean_id "#{options[:controller_id] || controller_id}-#{options[:action]}-#{options[:id]}-row"
59
- end
60
-
61
- def element_cell_id(options = {})
62
- options[:action] ||= params[:action]
63
- options[:id] ||= params[:id]
64
- options[:id] ||= params[:parent_id]
65
- options[:name] ||= params[:name]
66
- clean_id "#{controller_id}-#{options[:action]}-#{options[:id]}-#{options[:name]}-cell"
67
- end
68
-
69
- def element_form_id(options = {})
70
- options[:action] ||= params[:action]
71
- options[:id] ||= params[:id]
72
- options[:id] ||= params[:parent_id]
73
- clean_id "#{controller_id}-#{options[:action]}-#{options[:id]}-form"
74
- end
75
-
76
- def association_subform_id(column)
77
- klass = column.association.klass.to_s.underscore
78
- clean_id "#{controller_id}-associated-#{klass}"
79
- end
80
-
81
- def loading_indicator_id(options = {})
82
- options[:action] ||= params[:action]
83
- clean_id "#{controller_id}-#{options[:action]}-#{options[:id]}-loading-indicator"
84
- end
85
-
86
- def sub_section_id(options = {})
87
- options[:id] ||= params[:id]
88
- options[:id] ||= params[:parent_id]
89
- clean_id "#{controller_id}-#{options[:id]}-#{options[:sub_section]}-subsection"
90
- end
91
-
92
- def sub_form_id(options = {})
93
- options[:id] ||= params[:id]
94
- options[:id] ||= params[:parent_id]
95
- clean_id "#{controller_id}-#{options[:id]}-#{options[:association]}-subform"
96
- end
97
-
98
- def sub_form_list_id(options = {})
99
- options[:id] ||= params[:id]
100
- options[:id] ||= params[:parent_id]
101
- clean_id "#{controller_id}-#{options[:id]}-#{options[:association]}-subform-list"
102
- end
103
-
104
- def element_messages_id(options = {})
105
- options[:action] ||= params[:action]
106
- options[:id] ||= params[:id]
107
- options[:id] ||= params[:parent_id]
108
- clean_id "#{controller_id}-#{options[:action]}-#{options[:id]}-messages"
109
- end
110
-
111
- def action_iframe_id(options)
112
- "#{controller_id}-#{options[:action]}-#{options[:id]}-iframe"
113
- end
114
-
115
- private
116
-
117
- # whitelists id-safe characters
118
- def clean_id(val)
119
- val.gsub /[^-_0-9a-zA-Z]/, '-'
120
- end
121
- end
122
- end
123
- end
@@ -1,370 +0,0 @@
1
- # coding: utf-8
2
- module ActiveScaffold
3
- module Helpers
4
- # Helpers that assist with the rendering of a List Column
5
- module ListColumnHelpers
6
- def get_column_value(record, column)
7
- begin
8
- # check for an override helper
9
- value = if column_override? column
10
- # we only pass the record as the argument. we previously also passed the formatted_value,
11
- # but mike perham pointed out that prohibited the usage of overrides to improve on the
12
- # performance of our default formatting. see issue #138.
13
- send(column_override(column), record)
14
- # second, check if the dev has specified a valid list_ui for this column
15
- elsif column.list_ui and override_column_ui?(column.list_ui)
16
- send(override_column_ui(column.list_ui), column, record)
17
- elsif column.column and override_column_ui?(column.column.type)
18
- send(override_column_ui(column.column.type), column, record)
19
- else
20
- format_column_value(record, column)
21
- end
22
-
23
- value = '&nbsp;'.html_safe if value.nil? or (value.respond_to?(:empty?) and value.empty?) # fix for IE 6
24
- return value
25
- rescue Exception => e
26
- logger.error Time.now.to_s + "#{e.inspect} -- on the ActiveScaffold column = :#{column.name} in #{controller.class}"
27
- raise e
28
- end
29
- end
30
-
31
- # TODO: move empty_field_text and &nbsp; logic in here?
32
- # TODO: we need to distinguish between the automatic links *we* create and the ones that the dev specified. some logic may not apply if the dev specified the link.
33
- def render_list_column(text, column, record)
34
- if column.link
35
- link = column.link
36
- associated = record.send(column.association.name) if column.association
37
- url_options = params_for(:action => nil, :id => record.id)
38
-
39
- # setup automatic link
40
- if column.autolink? && column.singular_association? # link to inline form
41
- link = action_link_to_inline_form(column, record, associated, text)
42
- return text if link.nil?
43
- else
44
- url_options[:link] = text
45
- end
46
-
47
- if column_link_authorized?(link, column, record, associated)
48
- render_action_link(link, url_options, record)
49
- else
50
- "<a class='disabled'>#{text}</a>".html_safe
51
- end
52
- else
53
- text = active_scaffold_inplace_edit(record, column, {:formatted_column => text}) if inplace_edit?(record, column)
54
- text
55
- end
56
- end
57
-
58
- # setup the action link to inline form
59
- def action_link_to_inline_form(column, record, associated, text)
60
- link = column.link.clone
61
- link.label = text
62
- if column.polymorphic_association?
63
- polymorphic_controller = controller_path_for_activerecord(record.send(column.association.name).class)
64
- return link if polymorphic_controller.nil?
65
- link.controller = polymorphic_controller
66
- end
67
- configure_column_link(link, associated, column.actions_for_association_links)
68
- end
69
-
70
- def configure_column_link(link, associated, actions)
71
- if column_empty?(associated) # if association is empty, we only can link to create form
72
- if actions.include?(:new)
73
- link.action = 'new'
74
- link.crud_type = :create
75
- link.label = as_(:create_new)
76
- end
77
- elsif actions.include?(:edit)
78
- link.action = 'edit'
79
- link.crud_type = :update
80
- elsif actions.include?(:show)
81
- link.action = 'show'
82
- link.crud_type = :read
83
- elsif actions.include?(:list)
84
- link.action = 'index'
85
- link.crud_type = :read
86
- end
87
- link if link.action.present?
88
- end
89
-
90
- def column_link_authorized?(link, column, record, associated)
91
- if column.association
92
- associated_for_authorized = if associated.nil? || (associated.respond_to?(:blank?) && associated.blank?)
93
- column.association.klass
94
- elsif [:has_many, :has_and_belongs_to_many].include? column.association.macro
95
- associated.first
96
- else
97
- associated
98
- end
99
- authorized = associated_for_authorized.authorized_for?(:crud_type => link.crud_type)
100
- authorized = authorized and record.authorized_for?(:crud_type => :update, :column => column.name) if link.crud_type == :create
101
- authorized
102
- else
103
- record.authorized_for?(:crud_type => link.crud_type)
104
- end
105
- end
106
-
107
- # There are two basic ways to clean a column's value: h() and sanitize(). The latter is useful
108
- # when the column contains *valid* html data, and you want to just disable any scripting. People
109
- # can always use field overrides to clean data one way or the other, but having this override
110
- # lets people decide which way it should happen by default.
111
- #
112
- # Why is it not a configuration option? Because it seems like a somewhat rare request. But it
113
- # could eventually be an option in config.list (and config.show, I guess).
114
- def clean_column_value(v)
115
- h(v)
116
- end
117
-
118
- ##
119
- ## Overrides
120
- ##
121
- def active_scaffold_column_text(column, record)
122
- clean_column_value(truncate(record.send(column.name), :length => column.options[:truncate] || 50))
123
- end
124
-
125
- def active_scaffold_column_checkbox(column, record)
126
- options = {:disabled => true, :id => nil, :object => record}
127
- options.delete(:disabled) if inplace_edit?(record, column)
128
- check_box(:record, column.name, options)
129
- end
130
-
131
- def column_override_name(column, class_prefix = false)
132
- "#{clean_class_name(column.active_record_class.name) + '_' if class_prefix}#{clean_column_name(column.name)}_column"
133
- end
134
-
135
- def column_override(column)
136
- method_with_class = column_override_name(column, true)
137
- return method_with_class if respond_to?(method_with_class)
138
- method = column_override_name(column)
139
- method if respond_to?(method)
140
- end
141
- alias_method :column_override?, :column_override
142
-
143
- def override_column_ui?(list_ui)
144
- respond_to?(override_column_ui(list_ui))
145
- end
146
-
147
- # the naming convention for overriding column types with helpers
148
- def override_column_ui(list_ui)
149
- "active_scaffold_column_#{list_ui}"
150
- end
151
-
152
- ##
153
- ## Formatting
154
- ##
155
- def format_column_value(record, column, value = nil)
156
- value ||= record.send(column.name) unless record.nil?
157
- if value && column.association # cache association size before calling column_empty?
158
- associated_size = value.size if column.plural_association? and column.associated_number? # get count before cache association
159
- cache_association(value, column) if column.plural_association?
160
- end
161
- if column.association.nil? or column_empty?(value)
162
- if column.form_ui == :select && column.options[:options]
163
- text, val = column.options[:options].find {|text, val| (val.nil? ? text : val).to_s == value.to_s}
164
- value = active_scaffold_translated_option(column, text, val).first if text
165
- end
166
- if value.is_a? Numeric
167
- format_number_value(value, column.options)
168
- else
169
- format_value(value, column.options)
170
- end
171
- else
172
- format_association_value(value, column, associated_size)
173
- end
174
- end
175
-
176
- def format_number_value(value, options = {})
177
- value = case options[:format]
178
- when :size
179
- number_to_human_size(value, options[:i18n_options] || {})
180
- when :percentage
181
- number_to_percentage(value, options[:i18n_options] || {})
182
- when :currency
183
- number_to_currency(value, options[:i18n_options] || {})
184
- when :i18n_number
185
- number_with_delimiter(value, options[:i18n_options] || {})
186
- else
187
- value
188
- end
189
- clean_column_value(value)
190
- end
191
-
192
- def format_association_value(value, column, size)
193
- format_value case column.association.macro
194
- when :has_one, :belongs_to
195
- if column.polymorphic_association?
196
- "#{value.class.model_name.human}: #{value.to_label}"
197
- else
198
- value.to_label
199
- end
200
- when :has_many, :has_and_belongs_to_many
201
- if column.associated_limit.nil?
202
- firsts = value.collect { |v| v.to_label }
203
- else
204
- firsts = value.first(column.associated_limit)
205
- firsts.collect! { |v| v.to_label }
206
- firsts[column.associated_limit] = '…' if value.size > column.associated_limit
207
- end
208
- if column.associated_limit == 0
209
- size if column.associated_number?
210
- else
211
- joined_associated = firsts.join(active_scaffold_config.list.association_join_text)
212
- joined_associated << " (#{size})" if column.associated_number? and column.associated_limit and value.size > column.associated_limit
213
- joined_associated
214
- end
215
- end
216
- end
217
-
218
- def format_value(column_value, options = {})
219
- value = if column_empty?(column_value)
220
- active_scaffold_config.list.empty_field_text
221
- elsif column_value.is_a?(Time) || column_value.is_a?(Date)
222
- l(column_value, :format => options[:format] || :default)
223
- elsif [FalseClass, TrueClass].include?(column_value.class)
224
- as_(column_value.to_s.to_sym)
225
- else
226
- column_value.to_s
227
- end
228
- clean_column_value(value)
229
- end
230
-
231
- def cache_association(value, column)
232
- # we are not using eager loading, cache firsts records in order not to query the database in a future
233
- unless value.loaded?
234
- # load at least one record, is needed for column_empty? and checking permissions
235
- if column.associated_limit.nil?
236
- Rails.logger.warn "ActiveScaffold: Enable eager loading for #{column.name} association to reduce SQL queries"
237
- else
238
- value.target = value.find(:all, :limit => column.associated_limit + 1, :select => column.select_columns)
239
- end
240
- end
241
- end
242
-
243
- # ==========
244
- # = Inline Edit =
245
- # ==========
246
-
247
- def inplace_edit?(record, column)
248
- if column.inplace_edit
249
- editable = controller.send(:update_authorized?, record) if controller.respond_to?(:update_authorized?)
250
- editable = record.authorized_for?(:crud_type => :update, :column => column.name) if editable.nil? || editable == true
251
- editable
252
- end
253
- end
254
-
255
- def inplace_edit_cloning?(column)
256
- column.inplace_edit != :ajax and (override_form_field?(column) or column.form_ui or (column.column and override_input?(column.column.type)))
257
- end
258
-
259
- def format_inplace_edit_column(record,column)
260
- if column.list_ui == :checkbox
261
- active_scaffold_column_checkbox(column, record)
262
- else
263
- format_column_value(record, column)
264
- end
265
- end
266
-
267
- def active_scaffold_inplace_edit(record, column, options = {})
268
- formatted_column = options[:formatted_column] || format_column_value(record, column)
269
- id_options = {:id => record.id.to_s, :action => 'update_column', :name => column.name.to_s}
270
- tag_options = {:id => element_cell_id(id_options), :class => "in_place_editor_field",
271
- :title => as_(:click_to_edit), 'data-ie_id' => record.id.to_s}
272
-
273
- content_tag(:span, formatted_column, tag_options)
274
- end
275
-
276
- def inplace_edit_control(column)
277
- if inplace_edit?(active_scaffold_config.model, column) and inplace_edit_cloning?(column)
278
- old_record, @record = @record, new_model
279
- column = column.clone
280
- column.options = column.options.clone
281
- column.form_ui = :select if (column.association && column.form_ui.nil?)
282
- content_tag(:div, active_scaffold_input_for(column), :style => "display:none;", :class => inplace_edit_control_css_class).tap do
283
- @record = old_record
284
- end
285
- end
286
- end
287
-
288
- def inplace_edit_control_css_class
289
- "as_inplace_pattern"
290
- end
291
-
292
- def inplace_edit_tag_attributes(column)
293
- tag_options = {}
294
- tag_options['data-ie_url'] = url_for({:controller => params_for[:controller], :action => "update_column", :column => column.name, :id => '__id__'})
295
- tag_options['data-ie_cancel_text'] = column.options[:cancel_text] || as_(:cancel)
296
- tag_options['data-ie_loading_text'] = column.options[:loading_text] || as_(:loading)
297
- tag_options['data-ie_save_text'] = column.options[:save_text] || as_(:update)
298
- tag_options['data-ie_saving_text'] = column.options[:saving_text] || as_(:saving)
299
- tag_options['data-ie_rows'] = column.options[:rows] || 5 if column.column.try(:type) == :text
300
- tag_options['data-ie_cols'] = column.options[:cols] if column.options[:cols]
301
- tag_options['data-ie_size'] = column.options[:size] if column.options[:size]
302
-
303
- if column.list_ui == :checkbox
304
- tag_options['data-ie_mode'] = :inline_checkbox
305
- elsif inplace_edit_cloning?(column)
306
- tag_options['data-ie_mode'] = :clone
307
- elsif column.inplace_edit == :ajax
308
- url = url_for(:controller => params_for[:controller], :action => 'render_field', :id => '__id__', :column => column.name, :update_column => column.name, :in_place_editing => true, :escape => false)
309
- plural = column.plural_association? && !override_form_field?(column) && [:select, :record_select].include?(column.form_ui)
310
- tag_options['data-ie_render_url'] = url
311
- tag_options['data-ie_mode'] = :ajax
312
- tag_options['data-ie_plural'] = plural
313
- end
314
- tag_options
315
- end
316
-
317
- def mark_column_heading
318
- if active_scaffold_config.mark.mark_all_mode == :page then
319
- all_marked = true
320
- @page.items.each do |record|
321
- all_marked = false if !marked_records.entries.include?(record.id)
322
- end
323
- else
324
- all_marked = (marked_records.length >= @page.pager.count)
325
- end
326
- tag_options = {:id => "#{controller_id}_mark_heading", :class => "mark_heading in_place_editor_field"}
327
- tag_options['data-ie_url'] = url_for({:controller => params_for[:controller], :action => 'mark_all', :eid => params[:eid]})
328
- content_tag(:span, check_box_tag("#{controller_id}_mark_heading_span_input", !all_marked, all_marked), tag_options)
329
- end
330
-
331
- def render_column_heading(column, sorting, sort_direction)
332
- tag_options = {:id => active_scaffold_column_header_id(column), :class => column_heading_class(column, sorting), :title => column.description}
333
- tag_options.merge!(inplace_edit_tag_attributes(column)) if column.inplace_edit
334
- content_tag(:th, column_heading_value(column, sorting, sort_direction) + inplace_edit_control(column), tag_options)
335
- end
336
-
337
-
338
- def column_heading_value(column, sorting, sort_direction)
339
- if column.sortable?
340
- options = {:id => nil, :class => "as_sort",
341
- 'data-page-history' => controller_id,
342
- :remote => true, :method => :get}
343
- url_options = params_for(:action => :index, :page => 1,
344
- :sort => column.name, :sort_direction => sort_direction)
345
- link_to column.label, url_options, options
346
- else
347
- if column.name != :marked
348
- content_tag(:p, column.label)
349
- else
350
- mark_column_heading
351
- end
352
- end
353
- end
354
-
355
- def render_nested_view(action_links, url_options, record)
356
- rendered = []
357
- action_links.member.each do |link|
358
- if link.nested_link? && link.column && @nested_auto_open[link.column.name] && @records.length <= @nested_auto_open[link.column.name] && controller.respond_to?(:render_component_into_view)
359
- link_url_options = {:adapter => '_list_inline_adapter', :format => :js}.merge(action_link_url_options(link, url_options, record, options = {:reuse_eid => true}))
360
- link_id = get_action_link_id(link_url_options, record, link.column)
361
- rendered << (controller.send(:render_component_into_view, link_url_options) + javascript_tag("ActiveScaffold.ActionLink.get('#{link_id}').set_opened();"))
362
- end
363
- end
364
- rendered.join(' ').html_safe
365
- end
366
-
367
- end
368
- end
369
- end
370
-