active_scaffold 3.0.23 → 3.0.24

Sign up to get free protection for your applications and to get access to all the features.
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)