active_scaffold 3.0.23 → 3.0.24

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 (62) hide show
  1. data/frontends/default/views/_action_group.html.erb +1 -1
  2. data/frontends/default/views/_action_group.html.erb~ +24 -0
  3. data/frontends/default/views/_form.html.erb~ +26 -0
  4. data/frontends/default/views/_form_association.html.erb~ +19 -0
  5. data/frontends/default/views/_form_association_footer.html.erb~ +16 -6
  6. data/frontends/default/views/_horizontal_subform.html.erb~ +29 -0
  7. data/frontends/default/views/_horizontal_subform_header.html.erb~ +3 -2
  8. data/frontends/default/views/_list_actions.html.erb~ +15 -0
  9. data/frontends/default/views/_list_inline_adapter.html.erb~ +10 -0
  10. data/frontends/default/views/_list_messages.html.erb~ +30 -0
  11. data/frontends/default/views/_list_pagination.html.erb~ +11 -0
  12. data/frontends/default/views/_list_pagination_links.html.erb~ +0 -0
  13. data/frontends/default/views/_render_field.js.erb~ +23 -0
  14. data/frontends/default/views/_row.html.erb~ +6 -0
  15. data/frontends/default/views/_vertical_subform.html.erb~ +12 -0
  16. data/frontends/default/views/edit_associated.js.erb~ +13 -0
  17. data/frontends/default/views/on_create.js.rjs +2 -2
  18. data/frontends/default/views/render_field.js.erb~ +1 -0
  19. data/lib/active_scaffold/actions/core.rb~ +13 -5
  20. data/lib/active_scaffold/actions/create.rb~ +149 -0
  21. data/lib/active_scaffold/actions/list.rb~ +196 -0
  22. data/lib/active_scaffold/actions/nested.rb +6 -2
  23. data/lib/active_scaffold/actions/nested.rb~ +252 -0
  24. data/lib/active_scaffold/actions/search.rb~ +49 -0
  25. data/lib/active_scaffold/actions/subform.rb~ +27 -0
  26. data/lib/active_scaffold/actions/update.rb~ +149 -0
  27. data/lib/active_scaffold/attribute_params.rb~ +202 -0
  28. data/lib/active_scaffold/bridges/record_select/{lib/record_select_bridge.rb~ → helpers.rb~} +7 -16
  29. data/lib/active_scaffold/bridges/shared/date_bridge.rb~ +209 -0
  30. data/lib/active_scaffold/config/create.rb +4 -4
  31. data/lib/active_scaffold/config/nested.rb +1 -0
  32. data/lib/active_scaffold/config/nested.rb~ +41 -0
  33. data/lib/active_scaffold/config/search.rb~ +74 -0
  34. data/lib/active_scaffold/constraints.rb~ +186 -0
  35. data/lib/active_scaffold/data_structures/action_columns.rb~ +140 -0
  36. data/lib/active_scaffold/data_structures/action_link.rb +4 -4
  37. data/lib/active_scaffold/data_structures/action_link.rb~ +179 -0
  38. data/lib/active_scaffold/data_structures/nested_info.rb~ +124 -0
  39. data/lib/active_scaffold/extensions/action_controller_rendering.rb~ +22 -0
  40. data/lib/active_scaffold/extensions/action_view_rendering.rb~ +108 -0
  41. data/lib/active_scaffold/extensions/cache_association.rb~ +12 -0
  42. data/lib/active_scaffold/extensions/reverse_associations.rb~ +64 -0
  43. data/lib/active_scaffold/extensions/routing_mapper.rb~ +34 -0
  44. data/lib/active_scaffold/extensions/unsaved_associated.rb~ +62 -0
  45. data/lib/active_scaffold/finder.rb~ +370 -0
  46. data/lib/active_scaffold/helpers/controller_helpers.rb~ +101 -0
  47. data/lib/active_scaffold/helpers/form_column_helpers.rb~ +321 -0
  48. data/lib/active_scaffold/helpers/id_helpers.rb~ +123 -0
  49. data/lib/active_scaffold/helpers/list_column_helpers.rb +9 -6
  50. data/lib/active_scaffold/helpers/list_column_helpers.rb~ +368 -0
  51. data/lib/active_scaffold/helpers/search_column_helpers.rb~ +94 -46
  52. data/lib/active_scaffold/helpers/view_helpers.rb +1 -1
  53. data/lib/active_scaffold/helpers/view_helpers.rb~ +353 -0
  54. data/lib/active_scaffold/version.rb +1 -1
  55. data/lib/active_scaffold.rb +1 -1
  56. data/lib/active_scaffold.rb~ +362 -0
  57. metadata +110 -76
  58. data/lib/active_scaffold/bridges/dragonfly/bridge.rb~ +0 -12
  59. data/lib/active_scaffold/bridges/dragonfly/lib/dragonfly_bridge.rb~ +0 -36
  60. data/lib/active_scaffold/bridges/dragonfly/lib/dragonfly_bridge_helpers.rb~ +0 -12
  61. data/lib/active_scaffold/bridges/dragonfly/lib/form_ui.rb~ +0 -27
  62. data/lib/active_scaffold/bridges/dragonfly/lib/list_ui.rb~ +0 -16
@@ -0,0 +1,101 @@
1
+ module ActiveScaffold
2
+ module Helpers
3
+ module ControllerHelpers
4
+ def self.included(controller)
5
+ controller.class_eval { helper_method :params_for, :main_path_to_return, :render_parent?, :render_parent_options, :render_parent_action, :nested_singular_association?, :build_associated}
6
+ end
7
+
8
+ include ActiveScaffold::Helpers::IdHelpers
9
+
10
+ def params_for(options = {})
11
+ # :adapter and :position are one-use rendering arguments. they should not propagate.
12
+ # :sort, :sort_direction, and :page are arguments that stored in the session. they need not propagate.
13
+ # and wow. no we don't want to propagate :record.
14
+ # :commit is a special rails variable for form buttons
15
+ blacklist = [:adapter, :position, :sort, :sort_direction, :page, :record, :commit, :_method, :authenticity_token, :iframe]
16
+ unless @params_for
17
+ @params_for = {}
18
+ params.select { |key, value| blacklist.exclude? key.to_sym if key }.each {|key, value| @params_for[key.to_sym] = value.duplicable? ? value.clone : value}
19
+ @params_for[:controller] = '/' + @params_for[:controller].to_s unless @params_for[:controller].to_s.first(1) == '/' # for namespaced controllers
20
+ @params_for.delete(:id) if @params_for[:id].nil?
21
+ end
22
+ @params_for.merge(options)
23
+ end
24
+
25
+ # Parameters to generate url to the main page (override if the ActiveScaffold is used as a component on another controllers page)
26
+ def main_path_to_return
27
+ if params[:return_to]
28
+ params[:return_to]
29
+ else
30
+ parameters = {}
31
+ if params[:parent_controller]
32
+ parameters[:controller] = params[:parent_controller]
33
+ parameters[:eid] = params[:parent_controller]
34
+ end
35
+ if nested?
36
+ parameters[:controller] = nested.parent_scaffold.controller_path
37
+ parameters[:eid] = nil
38
+ end
39
+ if params[:parent_sti]
40
+ parameters[:controller] = params[:parent_sti]
41
+ parameters[:eid] = nil
42
+ end
43
+ parameters[:parent_column] = nil
44
+ parameters[:parent_id] = nil
45
+ parameters[:action] = "index"
46
+ parameters[:id] = nil
47
+ parameters[:associated_id] = nil
48
+ parameters[:utf8] = nil
49
+ params_for(parameters)
50
+ end
51
+ end
52
+
53
+ def nested_singular_association?
54
+ nested? && (nested.belongs_to? || nested.has_one?)
55
+ end
56
+
57
+ def render_parent?
58
+ nested_singular_association? || params[:parent_sti]
59
+ end
60
+
61
+ def render_parent_options
62
+ if nested_singular_association?
63
+ {:controller => nested.parent_scaffold.controller_path, :action => :row, :id => nested.parent_id}
64
+ elsif params[:parent_sti]
65
+ options = {:controller => params[:parent_sti], :action => render_parent_action(params[:parent_sti])}
66
+ if render_parent_action(params[:parent_sti]) == :index
67
+ options.merge(params.slice(:eid))
68
+ else
69
+ options.merge({:id => @record.id})
70
+ end
71
+ end
72
+ end
73
+
74
+ def render_parent_action(controller_path = nil)
75
+ begin
76
+ @parent_action = :row
77
+ parent_controller = "#{controller_path.to_s.camelize}Controller".constantize
78
+ @parent_action = :index if action_name == 'create' && parent_controller.active_scaffold_config.actions.include?(:create) && parent_controller.active_scaffold_config.create.refresh_list == true
79
+ @parent_action = :index if action_name == 'update' && parent_controller.active_scaffold_config.actions.include?(:update) && parent_controller.active_scaffold_config.update.refresh_list == true
80
+ @parent_action = :index if action_name == 'destroy' && parent_controller.active_scaffold_config.actions.include?(:delete) && parent_controller.active_scaffold_config.delete.refresh_list == true
81
+ rescue ActiveScaffold::ControllerNotFound
82
+ end if @parent_action.nil?
83
+ @parent_action
84
+ end
85
+
86
+ def build_associated(column, record)
87
+ child = column.singular_association? ? record.send(:"build_#{column.name}") : record.send(column.name).build
88
+ if record.new_record? && (reflection = record.class.reflect_on_association(column.name)).try(:reverse)
89
+ reverse_macro = child.class.reflect_on_association(reflection.reverse).macro
90
+ if [:has_one, :belongs_to].include?(reverse_macro) # singular
91
+ child.send(:"#{reflection.reverse}=", record)
92
+ # TODO: Might want to extend with this branch in the future
93
+ # else # plural
94
+ # child.send(:"#{reflection.reverse}") << record
95
+ end
96
+ end
97
+ child
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,321 @@
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
+ options[:class] << " checkbox-list"
125
+ html = content_tag :ul, :class => options[:class], :id => options[:id] do
126
+ content = "".html_safe
127
+ select_options.each_with_index do |option, i|
128
+ label, id = option
129
+ this_id = "#{options[:id]}_#{i}_id"
130
+ content << content_tag(:li) do
131
+ check_box_tag("#{options[:name]}[]", id, associated_ids.include?(id), :id => this_id) <<
132
+ content_tag(:label, h(label), :for => this_id)
133
+ end
134
+ end
135
+ content
136
+ end
137
+ html << javascript_tag("new DraggableLists('#{options[:id]}')") if column.options[:draggable_lists]
138
+ html
139
+ end
140
+
141
+ def active_scaffold_translated_option(column, text, value = nil)
142
+ value = text if value.nil?
143
+ [(text.is_a?(Symbol) ? column.active_record_class.human_attribute_name(text) : text), value]
144
+ end
145
+
146
+ def active_scaffold_input_enum(column, html_options)
147
+ options = { :selected => @record.send(column.name) }
148
+ options_for_select = column.options[:options].collect do |text, value|
149
+ active_scaffold_translated_option(column, text, value)
150
+ end
151
+ html_options.update(column.options[:html_options] || {})
152
+ options.update(column.options)
153
+ select(:record, column.name, options_for_select, options, html_options)
154
+ end
155
+
156
+ def active_scaffold_input_select(column, html_options)
157
+ if column.singular_association?
158
+ active_scaffold_input_singular_association(column, html_options)
159
+ elsif column.plural_association?
160
+ active_scaffold_input_plural_association(column, html_options)
161
+ else
162
+ active_scaffold_input_enum(column, html_options)
163
+ end
164
+ end
165
+
166
+ def active_scaffold_input_radio(column, html_options)
167
+ html_options.update(column.options[:html_options] || {})
168
+ column.options[:options].inject('') do |html, (text, value)|
169
+ text, value = active_scaffold_translated_option(column, text, value)
170
+ html << content_tag(:label, radio_button(:record, column.name, value, html_options.merge(:id => html_options[:id] + '-' + value.to_s)) + text)
171
+ end.html_safe
172
+ end
173
+
174
+ def active_scaffold_input_checkbox(column, options)
175
+ check_box(:record, column.name, options.merge(column.options))
176
+ end
177
+
178
+ def active_scaffold_input_password(column, options)
179
+ options = active_scaffold_input_text_options(options)
180
+ password_field :record, column.name, options.merge(column.options)
181
+ end
182
+
183
+ def active_scaffold_input_textarea(column, options)
184
+ text_area(:record, column.name, options.merge(:cols => column.options[:cols], :rows => column.options[:rows], :size => column.options[:size]))
185
+ end
186
+
187
+ def active_scaffold_input_virtual(column, options)
188
+ options = active_scaffold_input_text_options(options)
189
+ text_field :record, column.name, options.merge(column.options)
190
+ end
191
+
192
+ #
193
+ # Column.type-based inputs
194
+ #
195
+
196
+ def active_scaffold_input_boolean(column, options)
197
+ select_options = []
198
+ select_options << [as_(:_select_), nil] if !column.virtual? && column.column.null
199
+ select_options << [as_(:true), true]
200
+ select_options << [as_(:false), false]
201
+
202
+ select_tag(options[:name], options_for_select(select_options, @record.send(column.name)), options)
203
+ end
204
+
205
+ def onsubmit
206
+ end
207
+
208
+ ##
209
+ ## Form column override signatures
210
+ ##
211
+
212
+ # add functionality for overriding subform partials from association class path
213
+ def override_subform_partial?(column, subform_partial)
214
+ template_exists?(override_subform_partial(column, subform_partial), true)
215
+ end
216
+
217
+ def override_subform_partial(column, subform_partial)
218
+ File.join(active_scaffold_controller_for(column.association.klass).controller_path, subform_partial) if column_renders_as(column) == :subform
219
+ end
220
+
221
+ def override_form_field_partial?(column)
222
+ template_exists?(override_form_field_partial(column), true)
223
+ end
224
+
225
+ # the naming convention for overriding form fields with helpers
226
+ def override_form_field_partial(column)
227
+ path = active_scaffold_controller_for(column.active_record_class).controller_path
228
+ File.join(path, "#{clean_column_name(column.name)}_form_column")
229
+ end
230
+
231
+ def override_form_field(column)
232
+ method_with_class = override_form_field_name(column, true)
233
+ return method_with_class if respond_to?(method_with_class)
234
+ method = override_form_field_name(column)
235
+ method if respond_to?(method)
236
+ end
237
+ alias_method :override_form_field?, :override_form_field
238
+
239
+ # the naming convention for overriding form fields with helpers
240
+ def override_form_field_name(column, class_prefix = false)
241
+ "#{clean_class_name(column.active_record_class.name) + '_' if class_prefix}#{clean_column_name(column.name)}_form_column"
242
+ end
243
+
244
+ def override_input?(form_ui)
245
+ respond_to?(override_input(form_ui))
246
+ end
247
+
248
+ # the naming convention for overriding form input types with helpers
249
+ def override_input(form_ui)
250
+ "active_scaffold_input_#{form_ui}"
251
+ end
252
+
253
+ def form_partial_for_column(column, renders_as = nil)
254
+ renders_as ||= column_renders_as(column)
255
+ if override_form_field_partial?(column)
256
+ override_form_field_partial(column)
257
+ elsif renders_as == :field or override_form_field?(column)
258
+ "form_attribute"
259
+ elsif renders_as == :subform
260
+ "form_association"
261
+ elsif renders_as == :hidden
262
+ "form_hidden_attribute"
263
+ end
264
+ end
265
+
266
+ def subform_partial_for_column(column)
267
+ subform_partial = "#{active_scaffold_config_for(column.association.klass).subform.layout}_subform"
268
+ if override_subform_partial?(column, subform_partial)
269
+ override_subform_partial(column, subform_partial)
270
+ else
271
+ subform_partial
272
+ end
273
+ end
274
+
275
+ ##
276
+ ## Macro-level rendering decisions for columns
277
+ ##
278
+
279
+ def column_renders_as(column)
280
+ if column.is_a? ActiveScaffold::DataStructures::ActionColumns
281
+ return :subsection
282
+ elsif column.active_record_class.locking_column.to_s == column.name.to_s or column.form_ui == :hidden
283
+ return :hidden
284
+ elsif column.association.nil? or column.form_ui or !active_scaffold_config_for(column.association.klass).actions.include?(:subform)
285
+ return :field
286
+ else
287
+ return :subform
288
+ end
289
+ end
290
+
291
+ def column_scope(column)
292
+ if column.plural_association?
293
+ "[#{column.name}][#{@record.id || generate_temporary_id}]"
294
+ else
295
+ "[#{column.name}]"
296
+ end
297
+ end
298
+
299
+ def active_scaffold_add_existing_input(options)
300
+ if ActiveScaffold.js_framework == :prototype && controller.respond_to?(:record_select_config)
301
+ remote_controller = active_scaffold_controller_for(record_select_config.model).controller_path
302
+ options.merge!(:controller => remote_controller)
303
+ options.merge!(active_scaffold_input_text_options)
304
+ record_select_field(options[:name], @record, options)
305
+ else
306
+ select_options = options_for_select(options_for_association(nested.association)) #unless column.through_association?
307
+ select_options ||= options_for_select(active_scaffold_config.model.all.collect {|c| [h(c.to_label), c.id]})
308
+ select_tag 'associated_id', ('<option value="">' + as_(:_select_) + '</option>' + select_options).html_safe unless select_options.empty?
309
+ end
310
+ end
311
+
312
+ def active_scaffold_add_existing_label
313
+ if controller.respond_to?(:record_select_config)
314
+ record_select_config.model.model_name.human
315
+ else
316
+ active_scaffold_config.model.model_name.human
317
+ end
318
+ end
319
+ end
320
+ end
321
+ end
@@ -0,0 +1,123 @@
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
@@ -34,13 +34,14 @@ module ActiveScaffold
34
34
  if column.link
35
35
  link = column.link
36
36
  associated = record.send(column.association.name) if column.association
37
- url_options = params_for(:action => nil, :id => record.id, :link => text)
37
+ url_options = params_for(:action => nil, :id => record.id)
38
38
 
39
39
  # setup automatic link
40
40
  if column.autolink? && column.singular_association? # link to inline form
41
- link = action_link_to_inline_form(column, record, associated)
42
- return text if link.crud_type.nil?
43
- url_options[:link] = as_(:create_new) if link.crud_type == :create
41
+ link = action_link_to_inline_form(column, record, associated, text)
42
+ return text if link.nil?
43
+ else
44
+ url_options[:link] = text
44
45
  end
45
46
 
46
47
  if column_link_authorized?(link, column, record, associated)
@@ -55,8 +56,9 @@ module ActiveScaffold
55
56
  end
56
57
 
57
58
  # setup the action link to inline form
58
- def action_link_to_inline_form(column, record, associated)
59
+ def action_link_to_inline_form(column, record, associated, text)
59
60
  link = column.link.clone
61
+ link.label = text
60
62
  if column.polymorphic_association?
61
63
  polymorphic_controller = controller_path_for_activerecord(record.send(column.association.name).class)
62
64
  return link if polymorphic_controller.nil?
@@ -70,6 +72,7 @@ module ActiveScaffold
70
72
  if actions.include?(:new)
71
73
  link.action = 'new'
72
74
  link.crud_type = :create
75
+ link.label = as_(:create_new)
73
76
  end
74
77
  elsif actions.include?(:edit)
75
78
  link.action = 'edit'
@@ -81,7 +84,7 @@ module ActiveScaffold
81
84
  link.action = 'index'
82
85
  link.crud_type = :read
83
86
  end
84
- link
87
+ link if link.action.present?
85
88
  end
86
89
 
87
90
  def column_link_authorized?(link, column, record, associated)