active_scaffold_vho 3.0.25 → 3.0.26

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{active_scaffold_vho}
8
- s.version = "3.0.25"
8
+ s.version = "3.0.26"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Many, see README"]
12
- s.date = %q{2012-02-28}
12
+ s.date = %q{2012-05-12}
13
13
  s.description = %q{Save time and headaches, and create a more easily maintainable set of pages, with ActiveScaffold. ActiveScaffold handles all your CRUD (create, read, update, delete) user interface needs, leaving you more time to focus on more challenging (and interesting!) problems.}
14
14
  s.email = %q{activescaffold@googlegroups.com}
15
15
  s.extra_rdoc_files = [
@@ -1,4 +1,17 @@
1
1
  $(document).ready(function() {
2
+ $('form.as_form').live('ajax:before', function(event) {
3
+ var as_form = $(this).closest("form");
4
+ $(this).find('.association-record-new').each(function(index) {
5
+ var record_action = 'empty';
6
+
7
+ if(ActiveScaffold.form_elements_changed($(this).find('input, textarea, select'))) {
8
+ record_action = 'create';
9
+ }
10
+ $(this).find('input.associated_action').val(record_action);
11
+ });
12
+ return true;
13
+ });
14
+
2
15
  $('form.as_form').live('ajax:loading', function(event) {
3
16
  var as_form = $(this).closest("form");
4
17
  if (as_form && as_form.attr('data-loading') == 'true') {
@@ -34,6 +47,7 @@ $(document).ready(function() {
34
47
  } else {
35
48
  // hack: jquery requires if you request for javascript that javascript
36
49
  // is coming back, however rails has a different mantra
50
+ // Not needed anymore just included for backwards compatibility with jquery_vho
37
51
  if (action_link.position) {
38
52
  if (parseFloat($.fn.jquery) >= 1.5) {
39
53
  event.data_type = 'text';
@@ -48,6 +62,15 @@ $(document).ready(function() {
48
62
  }
49
63
  return true;
50
64
  });
65
+ $('a.as_action').live('ajax:beforeSend', function(event, xhr, settings) {
66
+ xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script);
67
+ var action_link = ActiveScaffold.ActionLink.get($(this));
68
+ if (action_link && action_link.position) {
69
+ settings.dataType = 'text';
70
+ settings.dataTypes = ['text'];
71
+ }
72
+ return true;
73
+ });
51
74
  $('a.as_action').live('ajax:success', function(event, response) {
52
75
  var action_link = ActiveScaffold.ActionLink.get($(this));
53
76
  if (action_link) {
@@ -85,6 +108,7 @@ $(document).ready(function() {
85
108
  var refresh_data = as_cancel.attr('data-refresh');
86
109
  if (refresh_data === 'true' && action_link.refresh_url) {
87
110
  event.data_url = action_link.refresh_url;
111
+ as_cancel.attr('href', action_link.refresh_url);
88
112
  if (action_link.position) event.data_type = 'html'
89
113
  } else if (refresh_data === 'false' || typeof(cancel_url) == 'undefined' || cancel_url.length == 0) {
90
114
  action_link.close();
@@ -93,6 +117,17 @@ $(document).ready(function() {
93
117
  }
94
118
  return true;
95
119
  });
120
+ $('a.as_cancel').live('ajax:beforeSend', function(event, xhr, settings) {
121
+ var as_cancel = $(this);
122
+ var action_link = ActiveScaffold.ActionLink.get($(this));
123
+ var refresh_data = as_cancel.attr('data-refresh');
124
+
125
+ if (action_link && action_link.position && refresh_data === 'true' && action_link.refresh_url) {
126
+ settings.dataType = 'html';
127
+ settings.dataTypes = ['html'];
128
+ }
129
+ return true;
130
+ });
96
131
  $('a.as_cancel').live('ajax:success', function(event, response) {
97
132
  var action_link = ActiveScaffold.find_action_link($(this));
98
133
 
@@ -140,11 +175,25 @@ $(document).ready(function() {
140
175
  $(this).prevAll('img.loading-indicator').css('visibility','hidden');
141
176
  return true;
142
177
  });
143
- $('input[type=button].as_add_existing').live('ajax:before', function(event) {
144
- var url = $(this).attr('href').replace('--ID--', $(this).prev().val());
145
- event.data_url = url;
146
- return true;
178
+ $('a.as_add_existing').live('ajax:before', function(event) {
179
+ var selected_id = $(this).prev().val();
180
+ if (selected_id) {
181
+ var url = $(this).attr('href').replace('--ID--', $(this).prev().val());
182
+ $(this).attr('href', url);
183
+ event.data_url = url;
184
+ return true;
185
+ } else {
186
+ return false;
187
+ }
188
+
147
189
  });
190
+ $('a.as_destroy_existing').live('click', function(event) {
191
+ var associated_record = $(this).closest('tr.association-record');
192
+ ActiveScaffold.delete_subform_record(associated_record);
193
+ event.stopPropagation();
194
+ return false;
195
+ });
196
+
148
197
  $('input.update_form, textarea.update_form, select.update_form').live('change', function(event) {
149
198
  var element = $(this);
150
199
  var as_form = element.closest('form.as_form');
@@ -229,6 +278,24 @@ $(document).ready(function() {
229
278
  ActiveScaffold.focus_first_element_of_form(as_form);
230
279
  return true;
231
280
  });
281
+ $('li.horizontal-sub-form').live('as:form_element_loaded', function(event) {
282
+ $(this).find('a.as_associated_form_link').each(function(index) {
283
+ ActiveScaffold.show($(this));
284
+ //Show select Box for add_existing as well
285
+ if($(this).has('as_add_existing')) {
286
+ ActiveScaffold.show($(this).prev());
287
+ }
288
+ })
289
+ return true;
290
+ });
291
+ $('li.sub-form').live('as:form_element_loaded', function(event) {
292
+ $(this).find('.association-record-new').each(function(index) {
293
+ $(this).find('input, textarea, select').each(function(index) {
294
+ $(this).data('value_was', $(this).val());
295
+ })
296
+ })
297
+ return true;
298
+ });
232
299
  $('span.mark_heading, span.in_place_editor_field[data-ie_mode="inline_checkbox"]').live('click', function(event) {
233
300
  ActiveScaffold.process_checkbox_inplace_edit($(this).find('input:checkbox'), ActiveScaffold.inplace_edit_options($(this)));
234
301
  return true;
@@ -240,12 +307,20 @@ $(document).ready(function() {
240
307
  return true;
241
308
  });
242
309
  $('tr.inline-adapter-autoopen').live('as:list_row_loaded', function(event) {
243
- var actionlink_id = $(event.target).attr('data-actionlinkid');
244
- if(actionlink_id) {
245
- var action_link = ActiveScaffold.ActionLink.get(actionlink_id);
246
- if (action_link) {
247
- action_link.set_opened();
248
- }
310
+ var actionlink_controllers = $(event.target).attr('data-actionlink-controllers');
311
+ if(actionlink_controllers) {
312
+ actionlink_controllers = actionlink_controllers.split('::');
313
+ $(this).prev('tr').find('a.index').each(function(index) {
314
+ var action_link = $(this);
315
+ for (var i = 0; i < actionlink_controllers.length; i++) {
316
+ if (actionlink_controllers[i] === action_link.attr('data-controller')) {
317
+ var as_action_link = ActiveScaffold.ActionLink.get(action_link);
318
+ if (as_action_link) {
319
+ as_action_link.set_opened();
320
+ }
321
+ }
322
+ }
323
+ });
249
324
  }
250
325
  return true;
251
326
  });
@@ -260,6 +335,7 @@ $(document).ready(function() {
260
335
  return true;
261
336
  });
262
337
  ActiveScaffold.trigger_load_events($('[data-as_load]'));
338
+ ActiveScaffold.load_embedded_conrollers();
263
339
 
264
340
  });
265
341
 
@@ -580,7 +656,8 @@ var ActiveScaffold = {
580
656
  if (errors.hasClass('association-record-errors')) {
581
657
  this.replace_html(errors, '');
582
658
  }
583
- this.remove(record);
659
+ record.find('input.associated_action').val('delete');
660
+ this.hide(record);
584
661
  },
585
662
 
586
663
  report_500_response: function(active_scaffold_id) {
@@ -841,6 +918,27 @@ var ActiveScaffold = {
841
918
  break;
842
919
  }
843
920
  });
921
+ },
922
+
923
+ load_embedded_conrollers: function(){
924
+ $.each($('a.as_link_to_component'), function(index) {
925
+ var div_element = $(this).closest('div.active-scaffold-component');
926
+ div_element.load($(this).attr('href').append_params({embedded: true}));
927
+ });
928
+ },
929
+
930
+ form_elements_changed: function(form_elements){
931
+ var form_elements_count = form_elements.length;
932
+ var i = 0;
933
+ var changed = false;
934
+
935
+ while(changed === false && i < form_elements_count) {
936
+ if($(form_elements[i]).val() != $(form_elements[i]).data('value_was')) {
937
+ changed = true;
938
+ }
939
+ i++;
940
+ }
941
+ return changed;
844
942
  }
845
943
  }
846
944
 
@@ -230,11 +230,22 @@ document.observe("dom:loaded", function() {
230
230
  if(loading_indicator) loading_indicator.style.visibility = 'hidden';
231
231
  return true;
232
232
  });
233
- document.on('ajax:before', 'input[type=button].as_add_existing', function(event) {
233
+ document.on('ajax:before', 'a.as_add_existing', function(event) {
234
234
  var button = event.findElement();
235
- var url = button.readAttribute('href').sub('--ID--', button.previous().getValue());
236
- event.memo.url = url;
237
- return true;
235
+ var selected_id = button.previous().getValue();
236
+ if (selected_id) {
237
+ var url = button.readAttribute('href').sub('--ID--', selected_id);
238
+ event.memo.url = url;
239
+ return true;
240
+ } else {
241
+ return false;
242
+ }
243
+ });
244
+ document.on('click', 'a.as_destroy_existing', function(event) {
245
+ var associated_record = event.findElement('tr.association-record');
246
+ ActiveScaffold.delete_subform_record(associated_record);
247
+ event.stop();
248
+ return false;
238
249
  });
239
250
  document.on('change', 'input.update_form, textarea.update_form, select.update_form', function(event) {
240
251
  var element = event.findElement();
@@ -314,13 +325,30 @@ document.observe("dom:loaded", function() {
314
325
  ActiveScaffold.focus_first_element_of_form(as_form);
315
326
  return true;
316
327
  });
328
+ document.on('as:form_element_loaded', 'li.horizontal-sub-form', function(event, element) {
329
+ element.select('a.as_associated_form_link').each(function(element) {
330
+ ActiveScaffold.show(element);
331
+ //Show select Box for add_existing as well
332
+ if(element.hasClassName('as_add_existing')) {
333
+ ActiveScaffold.show(element.previous());
334
+ }
335
+ });
336
+ return true;
337
+ });
317
338
  document.on('as:list_row_loaded', 'tr.inline-adapter-autoopen', function(event, element) {
318
- var actionlink_id = element.readAttribute('data-actionlinkid');
319
- if(actionlink_id) {
320
- var action_link = ActiveScaffold.ActionLink.get(actionlink_id);
321
- if (action_link) {
322
- action_link.set_opened();
323
- }
339
+ var actionlink_controllers = event.element().readAttribute('data-actionlink-controllers');
340
+ if(actionlink_controllers) {
341
+ actionlink_controllers = actionlink_controllers.split('::');
342
+ element.previous('tr').select('a.index').each(function(action_link) {
343
+ for (var i = 0; i < actionlink_controllers.length; i++) {
344
+ if (actionlink_controllers[i] === action_link.readAttribute('data-controller')) {
345
+ var as_action_link = ActiveScaffold.ActionLink.get(action_link);
346
+ if (as_action_link) {
347
+ as_action_link.set_opened();
348
+ }
349
+ }
350
+ }
351
+ });
324
352
  }
325
353
  return true;
326
354
  });
@@ -335,6 +363,7 @@ document.observe("dom:loaded", function() {
335
363
  return true;
336
364
  });
337
365
  ActiveScaffold.trigger_load_events($$('[data-as_load]'));
366
+ ActiveScaffold.load_embedded_conrollers();
338
367
  });
339
368
 
340
369
 
@@ -490,7 +519,7 @@ var ActiveScaffold = {
490
519
  tbody.insert({top: html});
491
520
  new_row = tbody.firstDescendant();
492
521
  } else if (options.insert_at == 'bottom') {
493
- var last_row = tbody.childElements().reverse().detect(function(node) { return node.hasClassName('record') || node.hasClassName('inline-adapter')});
522
+ var last_row = tbody.childElements().reverse().detect(function(node) {return node.hasClassName('record') || node.hasClassName('inline-adapter')});
494
523
  if (last_row) {
495
524
  last_row.insert({after: html});
496
525
  } else {
@@ -529,7 +558,8 @@ var ActiveScaffold = {
529
558
  if (errors.hasClassName('association-record-errors')) {
530
559
  this.replace_html(errors, '');
531
560
  }
532
- this.remove(record);
561
+ record.down('input.associated_action').value('delete');
562
+ this.hide(record);
533
563
  },
534
564
 
535
565
  report_500_response: function(active_scaffold_id) {
@@ -651,7 +681,7 @@ var ActiveScaffold = {
651
681
  var mark_checkboxes = $$('#' + element.readAttribute('id') + ' > tr.record td.marked-column input[type="checkbox"]');
652
682
  mark_checkboxes.each(function(item) {
653
683
  if(options.checked === true) {
654
- item.writeAttribute({ checked: 'checked' });
684
+ item.writeAttribute({checked: 'checked'});
655
685
  } else {
656
686
  item.removeAttribute('checked');
657
687
  }
@@ -660,7 +690,7 @@ var ActiveScaffold = {
660
690
  if(options.include_mark_all === true) {
661
691
  var mark_all_checkbox = element.previous('thead').down('th.marked-column_heading span input[type="checkbox"]');
662
692
  if(options.checked === true) {
663
- mark_all_checkbox.writeAttribute({ checked: 'checked' });
693
+ mark_all_checkbox.writeAttribute({checked: 'checked'});
664
694
  } else {
665
695
  mark_all_checkbox.removeAttribute('checked');
666
696
  }
@@ -698,6 +728,13 @@ var ActiveScaffold = {
698
728
  break;
699
729
  }
700
730
  });
731
+ },
732
+
733
+ load_embedded_conrollers: function(){
734
+ $$('a.as_link_to_component').each(function(element) {
735
+ var div_element = element.up('div.active-scaffold-component');
736
+ new Ajax.Updater(div_element, element.readAttribute('href').append_params({embedded: true}), {method: 'get', evalScripts: true});
737
+ });
701
738
  }
702
739
 
703
740
  }
@@ -10,17 +10,15 @@ show_add_new = column_show_add_new(column, associated, @record)
10
10
 
11
11
  return unless show_add_new or show_add_existing
12
12
 
13
- edit_associated_url = url_for(:action => 'edit_associated', :id => parent_record.id, :association => column.name, :associated_id => '--ID--', :escape => false, :eid => params[:eid], :parent_controller => params[:parent_controller], :parent_id => params[:parent_id]) if show_add_existing
14
- add_new_url = url_for(:action => 'edit_associated', :id => parent_record.id, :association => column.name, :escape => false, :eid => params[:eid], :parent_controller => params[:parent_controller], :parent_id => params[:parent_id]) if show_add_new
13
+ edit_associated_url = url_for(:action => 'edit_associated', :id => parent_record.id, :association => column.name, :associated_id => '--ID--', :escape => false, :eid => params[:eid], :parent_controller => params[:parent_controller], :parent_id => params[:parent_id]).html_safe if show_add_existing
14
+ add_new_url = url_for(:action => 'edit_associated', :id => parent_record.id, :association => column.name, :escape => false, :eid => params[:eid], :parent_controller => params[:parent_controller], :parent_id => params[:parent_id]).html_safe if show_add_new
15
15
 
16
16
  -%>
17
17
  <div class="footer-wrapper">
18
18
  <div class="footer">
19
19
  <% if show_add_new -%>
20
- <% add_label = column.plural_association? ? as_(:create_another, :model => column.association.klass.model_name.human) : as_(:replace_with_new)
21
- create_another_id = "#{sub_form_id(:association => column.name)}-create-another" %>
22
- <%= tag(:input, {:id => create_another_id, :type => 'button', :value => add_label, :href => add_new_url.html_safe, 'data-remote' => true, :style=> "display: none;"}) %>
23
- <%= javascript_tag("ActiveScaffold.show('#{create_another_id}');") %>
20
+ <% add_label = column.plural_association? ? as_(:create_another, :model => column.association.klass.model_name.human) : as_(:replace_with_new) %>
21
+ <%= link_to add_label, add_new_url, :class => 'as_associated_form_link', :remote => true, :style=> "display: none;" %>
24
22
  <% end -%>
25
23
 
26
24
  <%= '|' if show_add_new and show_add_existing %>
@@ -29,11 +27,9 @@ add_new_url = url_for(:action => 'edit_associated', :id => parent_record.id, :as
29
27
  <% if remote_controller and remote_controller.respond_to? :uses_record_select? and remote_controller.uses_record_select? -%>
30
28
  <%= link_to_record_select as_(:add_existing), remote_controller.controller_path, :onselect => "ActiveScaffold.record_select_onselect(#{edit_associated_url.to_json}, #{active_scaffold_id.to_json}, id);" -%>
31
29
  <% else -%>
32
- <% select_options = options_for_select(options_for_association(column.association))
33
- add_existing_id = "#{sub_form_id(:association => column.name)}-add-existing" %>
34
- <%= select_tag 'associated_id', '<option value="">'.html_safe + as_(:_select_) + '</option>'.html_safe + select_options %>
35
- <%= tag(:input, {:id => add_existing_id, :type => 'button', :value => as_(:add_existing), :href => edit_associated_url.html_safe, 'data-remote' => true, :class=> 'as_add_existing', :style => "display: none;"}) %>
36
- <%= javascript_tag("ActiveScaffold.show('#{add_existing_id}');") %>
30
+ <% select_options = options_for_select(options_for_association(column.association))%>
31
+ <%= select_tag 'associated_id', '<option value="">'.html_safe + as_(:_select_) + '</option>'.html_safe + select_options, :id => nil, :style => "display: none;" %>
32
+ <%= link_to as_(:add_existing), edit_associated_url, :remote => true, :class => 'as_associated_form_link as_add_existing', :style => "display: none;" %>
37
33
  <% end -%>
38
34
  <% end -%>
39
35
  </div>
@@ -5,6 +5,7 @@
5
5
  config = active_scaffold_config_for(@record.class)
6
6
  options = active_scaffold_input_options(config.columns[@record.class.primary_key], scope)
7
7
  tr_id = "association-#{options[:id]}"
8
+ associated_action = @record.new_record? ? :create_or_empty : :update
8
9
  %>
9
10
  <tr id="<%= tr_id %>" class="association-record <%= 'association-record-new' if @record.new_record? -%> <%= 'locked' if locked -%>">
10
11
  <% config.subform.columns.each :for => @record.class, :crud_type => crud_type, :flatten => true do |column| %>
@@ -25,13 +26,16 @@
25
26
  <% if show_actions -%>
26
27
  <td class="actions">
27
28
  <% if record_column.plural_association? and (@record.authorized_for?(:crud_type => :delete) or not [:destroy, :delete_all].include?(record_column.association.options[:dependent])) %>
28
- <% destroy_id = "#{options[:id]}-destroy" %>
29
- <%= link_to as_(:remove), '#', :class => 'destroy', :id => destroy_id , :onclick => "ActiveScaffold.delete_subform_record(\"#{tr_id}\"); return false;", :style=> "display: none;" %>
30
- <%= javascript_tag("ActiveScaffold.show('#{destroy_id}');") if !locked %>
29
+ <% link_classes = ['destroy', 'as_destroy_existing']
30
+ link_classes << 'as_associated_form_link' if !locked %>
31
+ <%= link_to as_(:remove), '#', :class => link_classes.join(' '), :style=> "display: none;" %>
31
32
  <% end %>
33
+ </td>
34
+ <% end -%>
35
+ <td>
32
36
  <% unless @record.new_record? %>
33
- <input type="hidden" name="<%= options[:name] -%>" id="<%= options[:id] -%>" value="<%= @record.id -%>" />
37
+ <input type="hidden" name="<%= options[:name] -%>" id="<%= options[:id] -%>" value="<%= @record.id -%>" />
34
38
  <% end -%>
39
+ <input type="hidden" name="<%= scope ? "record#{scope}[associated_action]" : "record[associated_action]" -%>" class="associated_action" value="<%= associated_action -%>" />
35
40
  </td>
36
- <% end -%>
37
41
  </tr>
@@ -6,6 +6,7 @@
6
6
  config = active_scaffold_config_for(@record.class)
7
7
  options = active_scaffold_input_options(config.columns[@record.class.primary_key], scope)
8
8
  tr_id = "association-#{options[:id]}"
9
+ associated_action = @record.new_record? ? :create_or_empty : :update
9
10
  -%>
10
11
  <ol id="<%= tr_id %>" class="association-record <%= 'association-record-new' if @record.new_record? -%> <%= 'locked' if locked -%>">
11
12
  <% config.subform.columns.each :for => @record, :crud_type => crud_type, :flatten => true do |column| %>
@@ -26,13 +27,16 @@
26
27
  <% if show_actions -%>
27
28
  <li class="actions">
28
29
  <% if record_column.plural_association? and (@record.authorized_for?(:crud_type => :delete) or not [:destroy, :delete_all].include?(record_column.association.options[:dependent])) %>
29
- <% destroy_id = "#{options[:id]}-destroy" %>
30
- <%= link_to as_(:remove), '#', :class => 'destroy', :id => destroy_id , :onclick => "ActiveScaffold.delete_subform_record(\"#{tr_id}\"); return false;", :style=> "display: none;" %>
31
- <%= javascript_tag("ActiveScaffold.show('#{destroy_id}');") if !locked %>
30
+ <% link_classes = ['destroy', 'as_destroy_existing']
31
+ link_classes << 'as_associated_form_link' if !locked %>
32
+ <%= link_to as_(:remove), '#', :class => link_classes.join(' '), :style=> "display: none;" %>
32
33
  <% end %>
34
+ </li>
35
+ <% end -%>
36
+ <li>
33
37
  <% unless @record.new_record? %>
34
- <input type="hidden" name="<%= options[:name] -%>" id="<%= options[:id] -%>" value="<%= @record.id -%>" />
38
+ <input type="hidden" name="<%= options[:name] -%>" id="<%= options[:id] -%>" value="<%= @record.id -%>" />
35
39
  <% end -%>
40
+ <input type="hidden" name="<%= scope ? "record#{scope}[associated_action]" : "record[associated_action]" -%>" class="associated_action" value="<%= associated_action -%>" />
36
41
  </li>
37
- <% end -%>
38
42
  </ol>
@@ -82,8 +82,6 @@ module ActiveRecordPermissions
82
82
  # options[:column] should be the name of a model attribute
83
83
  # options[:action] is the name of a method
84
84
  def authorized_for?(options = {})
85
- raise ArgumentError, "unknown crud type #{options[:crud_type]}" if options[:crud_type] and ![:create, :read, :update, :delete].include?(options[:crud_type])
86
-
87
85
  # column_authorized_for_crud_type? has the highest priority over other methods,
88
86
  # you can disable a crud verb and enable that verb for a column
89
87
  # (for example, disable update and enable inplace_edit in a column)
@@ -88,7 +88,7 @@ module ActiveScaffold
88
88
  end
89
89
 
90
90
  def manage_nested_record_from_params(parent_record, column, attributes)
91
- record = find_or_create_for_params(attributes, column, parent_record)
91
+ record = nested_record_for_action(parent_record, column, attributes)
92
92
  if record
93
93
  record_columns = active_scaffold_config_for(column.association.klass).subform.columns
94
94
  update_record_from_params(record, record_columns, attributes)
@@ -96,6 +96,23 @@ module ActiveScaffold
96
96
  end
97
97
  record
98
98
  end
99
+
100
+ def nested_record_for_action(parent_record, column, attributes)
101
+ associated_action = attributes.delete(:associated_action)
102
+
103
+ case associated_action.to_sym
104
+ when :create then create_nested_record(column, parent_record)
105
+ when :update then find_nested_record(attributes[:id], column, parent_record)
106
+ when :empty then nil
107
+ when :delete then nil
108
+ when :create_or_empty then
109
+ if column.show_blank_record && attributes_hash_is_empty?(attributes, column.association.klass)
110
+ nil
111
+ else
112
+ create_nested_record(column, parent_record)
113
+ end
114
+ end
115
+ end
99
116
 
100
117
  def column_value_from_param_value(parent_record, column, value)
101
118
  # convert the value, possibly by instantiating associated objects
@@ -150,33 +167,35 @@ module ActiveScaffold
150
167
  end
151
168
  end
152
169
 
153
- # Attempts to create or find an instance of klass (which must be an ActiveRecord object) from the
154
- # request parameters given. If params[:id] exists it will attempt to find an existing object
155
- # otherwise it will build a new one.
156
- def find_or_create_for_params(params, parent_column, parent_record)
157
- current = parent_record.send(parent_column.name)
170
+ def create_nested_record(parent_column, parent_record)
158
171
  klass = parent_column.association.klass
159
- return nil if parent_column.show_blank_record and attributes_hash_is_empty?(params, klass)
172
+
173
+ if klass.authorized_for?(:crud_type => :create)
174
+ if parent_column.singular_association?
175
+ return parent_record.send("build_#{parent_column.name}")
176
+ else
177
+ return parent_record.send(parent_column.name).build
178
+ end
179
+ end
180
+ end
160
181
 
161
- if params.has_key? :id
182
+ def find_nested_record(id, parent_column, parent_record)
183
+ klass = parent_column.association.klass
184
+ if id
185
+ current = parent_record.send(parent_column.name)
186
+ Rails.logger.info("find_nested_record: id: #{id}, curent: #{current.inspect}")
162
187
  # modifying the current object of a singular association
163
- if current and current.is_a? ActiveRecord::Base and current.id.to_s == params[:id]
188
+ if current && current.is_a?(ActiveRecord::Base) && current.id.to_s == id
164
189
  return current
165
190
  # modifying one of the current objects in a plural association
166
- elsif current and current.respond_to?(:any?) and current.any? {|o| o.id.to_s == params[:id]}
167
- return current.detect {|o| o.id.to_s == params[:id]}
191
+ elsif current && current.respond_to?(:any?) && current.any? {|o| o.id.to_s == id}
192
+ return current.detect {|o| o.id.to_s == id}
168
193
  # attaching an existing but not-current object
169
194
  else
170
- return klass.find(params[:id])
195
+ return klass.find(id)
171
196
  end
172
197
  else
173
- if klass.authorized_for?(:crud_type => :create)
174
- if parent_column.singular_association?
175
- return parent_record.send("build_#{parent_column.name}")
176
- else
177
- return parent_record.send(parent_column.name).build
178
- end
179
- end
198
+ Rails.logger.info("Activescaffold find_nested_record missing id")
180
199
  end
181
200
  end
182
201
 
@@ -67,15 +67,6 @@ module ActiveScaffold::DataStructures
67
67
  def confirm?
68
68
  @confirm ? true : false
69
69
  end
70
-
71
- # if the action uses a DHTML based (i.e. 2-phase) confirmation
72
- attr_writer :dhtml_confirm
73
- def dhtml_confirm
74
- @dhtml_confirm
75
- end
76
- def dhtml_confirm?
77
- @dhtml_confirm
78
- end
79
70
 
80
71
  # what method to call on the controller to see if this action_link should be visible
81
72
  # note that this is only the UI part of the security. to prevent URL hax0rz, you also need security on requests (e.g. don't execute update method unless authorized).
@@ -38,7 +38,8 @@ module ActionView::Rendering #:nodoc:
38
38
  # Defining options[:label] lets you completely customize the list title for the embedded scaffold.
39
39
  #
40
40
  def render_with_active_scaffold(*args, &block)
41
- if args.first == :super
41
+ options = args.first
42
+ if options == :super
42
43
  last_view = @view_stack.last
43
44
  options = args[1] || {}
44
45
  options[:locals] ||= {}
@@ -52,37 +53,31 @@ module ActionView::Rendering #:nodoc:
52
53
  result = render_without_active_scaffold options
53
54
  @view_stack.pop
54
55
  result
55
- elsif args.first.is_a?(Hash) and args.first[:active_scaffold]
56
+ elsif options.is_a?(Hash) && options[:active_scaffold]
56
57
  require 'digest/md5'
57
- options = args.first
58
58
 
59
59
  remote_controller = options[:active_scaffold]
60
60
  constraints = options[:constraints]
61
61
  conditions = options[:conditions]
62
62
  eid = Digest::MD5.hexdigest(params[:controller] + remote_controller.to_s + constraints.to_s + conditions.to_s)
63
- session["as:#{eid}"] = {:constraints => constraints, :conditions => conditions, :list => {:label => args.first[:label]}}
63
+ session["as:#{eid}"] = {:constraints => constraints, :conditions => conditions, :list => {:label => options[:label]}}
64
64
  options[:params] ||= {}
65
65
  options[:params].merge! :eid => eid, :embedded => true
66
66
 
67
67
  id = "as_#{eid}-content"
68
68
  url_options = {:controller => remote_controller.to_s, :action => 'index'}.merge(options[:params])
69
69
 
70
- if controller.respond_to?(:render_component_into_view)
70
+ unless controller.respond_to?(:render_component_into_view)
71
71
  controller.send(:render_component_into_view, url_options)
72
72
  else
73
- content_tag(:div, {:id => id}) do
73
+ url_options.delete(:embedded)
74
+ content_tag(:div, {:id => id, :class => 'active-scaffold-component'}) do
74
75
  url = url_for(url_options)
75
- link_to(remote_controller.to_s, url, {:remote => true, :id => id}) <<
76
- if ActiveScaffold.js_framework == :prototype
77
- javascript_tag("new Ajax.Updater('#{id}', '#{url}', {method: 'get', evalScripts: true});")
78
- elsif ActiveScaffold.js_framework == :jquery
79
- javascript_tag("$('##{id}').load('#{url}');")
80
- end
76
+ link_to(remote_controller.to_s, url, {:remote => true, :class => 'as_link_to_component'})
81
77
  end
82
78
  end
83
79
 
84
80
  else
85
- options = args.first
86
81
  if options.is_a?(Hash)
87
82
  current_view = {:view => options[:partial], :is_template => false} if options[:partial]
88
83
  current_view = {:view => options[:template], :is_template => !!options[:template]} if current_view.nil? && options[:template]
@@ -265,7 +265,8 @@ module ActiveScaffold
265
265
  :where => search_conditions,
266
266
  :joins => joins_for_finder,
267
267
  :includes => options[:count_includes]}
268
-
268
+
269
+
269
270
  finder_options.merge! custom_finder_options
270
271
 
271
272
  # NOTE: we must use :include in the count query, because some conditions may reference other tables
@@ -275,6 +276,9 @@ module ActiveScaffold
275
276
  # Converts count to an integer if ActiveRecord returned an OrderedHash
276
277
  # that happens when finder_options contains a :group key
277
278
  count = count.length if count.is_a? ActiveSupport::OrderedHash
279
+
280
+ full_includes = add_association_to_includes_for_sorting(options[:sorting], full_includes)
281
+
278
282
  finder_options.merge! :includes => full_includes
279
283
 
280
284
  # we build the paginator differently for method- and sql-based sorting
@@ -292,6 +296,21 @@ module ActiveScaffold
292
296
  end
293
297
  pager.page(options[:page])
294
298
  end
299
+
300
+ # if someone excludes association from includes in configuration
301
+ # and sorts by that that column... database will not be happy about it :-)
302
+ # just a safety check to prevent many many database queries
303
+ def add_association_to_includes_for_sorting(sorting, full_includes)
304
+ if sorting && sorting.sorts_by_method?
305
+ sorting_column = sorting.first.first
306
+ #wants to sort by assocation which is not included bad performance...
307
+ if sorting_column.association && !sorting_column.polymorphic_association? &&
308
+ sorting_column.includes.empty? && !full_includes.include?(sorting_column.association.name)
309
+ full_includes << sorting_column.association.name
310
+ end
311
+ end
312
+ full_includes
313
+ end
295
314
 
296
315
  def append_to_query(query, options)
297
316
  options.assert_valid_keys :where, :select, :group, :order, :limit, :offset, :joins, :includes, :lock, :readonly, :from
@@ -330,6 +349,7 @@ module ActiveScaffold
330
349
 
331
350
  # TODO: this should reside on the column, not the controller
332
351
  def sort_collection_by_column(collection, column, order)
352
+ Rails.logger.info("das hier ja was bin im sort_collection")
333
353
  sorter = column.sort[:method]
334
354
  collection = collection.sort_by { |record|
335
355
  value = (sorter.is_a? Proc) ? record.instance_eval(&sorter) : record.instance_eval(sorter)
@@ -351,15 +351,15 @@ module ActiveScaffold
351
351
 
352
352
  def render_nested_view(action_links, url_options, record)
353
353
  rendered = []
354
- link_id = nil
354
+ link_nested_controllers = []
355
355
  action_links.member.each do |link|
356
356
  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)
357
357
  link_url_options = {:embedded => true, :format => :js}.merge(action_link_url_options(link, url_options, record, options = {:reuse_eid => true}))
358
- link_id = get_action_link_id(link_url_options, record, link.column)
358
+ link_nested_controllers << link.controller.to_s if link.controller
359
359
  rendered << (controller.send(:render_component_into_view, link_url_options))
360
360
  end
361
361
  end
362
- content_tag(:tr, content_tag(:td, rendered.join(' ').html_safe), :class => "inline-adapter-autoopen", 'data-actionlinkid' => link_id, 'data-as_load'=>"tr");
362
+ content_tag(:tr, content_tag(:td, rendered.join(' ').html_safe), :class => "inline-adapter-autoopen", 'data-actionlink-controllers' => link_nested_controllers.join('::').html_safe, 'data-as_load'=>"tr");
363
363
  end
364
364
 
365
365
  end
@@ -160,7 +160,6 @@ module ActiveScaffold
160
160
  end
161
161
 
162
162
  def action_link_html_options(link, url_options, record, html_options)
163
- link_id = get_action_link_id(url_options, record, link.column)
164
163
  html_options.reverse_merge! link.html_options.merge(:class => link.action)
165
164
 
166
165
  # Needs to be in html_options to as the adding _method to the url is no longer supported by Rails
@@ -175,14 +174,7 @@ module ActiveScaffold
175
174
  html_options['data-popup'] = true
176
175
  html_options[:target] = '_blank'
177
176
  end
178
- html_options[:id] = link_id
179
177
  html_options[:remote] = true unless link.page? || link.popup?
180
- if link.dhtml_confirm?
181
- html_options[:class] += ' as_action' if !link.inline?
182
- html_options[:page_link] = 'true' if !link.inline?
183
- html_options[:dhtml_confirm] = link.dhtml_confirm.value
184
- html_options[:onclick] = link.dhtml_confirm.onclick_function(controller, link_id)
185
- end
186
178
  html_options[:class] += " #{link.html_options[:class]}" unless link.html_options[:class].blank?
187
179
  html_options
188
180
  end
@@ -242,6 +234,7 @@ module ActiveScaffold
242
234
  end
243
235
 
244
236
  def column_class(column, column_value, record)
237
+ @numeric_classes ||= [:decimal, :float, :integer]
245
238
  classes = []
246
239
  classes << "#{column.name}-column"
247
240
  if column.css_class.is_a?(Proc)
@@ -253,7 +246,7 @@ module ActiveScaffold
253
246
 
254
247
  classes << 'empty' if column_empty? column_value
255
248
  classes << 'sorted' if active_scaffold_config.list.user.sorting.sorts_on?(column)
256
- classes << 'numeric' if column.column and [:decimal, :float, :integer].include?(column.column.type)
249
+ classes << 'numeric' if column.column && @numeric_classes.include?(column.column.type)
257
250
  classes.join(' ').rstrip
258
251
  end
259
252
 
@@ -272,9 +265,10 @@ module ActiveScaffold
272
265
  end
273
266
 
274
267
  def column_empty?(column_value)
268
+ @empty_column_strings ||= ['&nbsp;', active_scaffold_config.list.empty_field_text]
275
269
  empty = column_value.nil?
276
270
  empty ||= column_value.empty? if column_value.respond_to? :empty?
277
- empty ||= ['&nbsp;', active_scaffold_config.list.empty_field_text].include? column_value if String === column_value
271
+ empty ||= @empty_column_strings.include?(column_value) if String === column_value
278
272
  return empty
279
273
  end
280
274
 
@@ -2,7 +2,7 @@ module ActiveScaffold
2
2
  module Version
3
3
  MAJOR = 3
4
4
  MINOR = 0
5
- PATCH = 25
5
+ PATCH = 26
6
6
 
7
7
  STRING = [MAJOR, MINOR, PATCH].compact.join('.')
8
8
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_scaffold_vho
3
3
  version: !ruby/object:Gem::Version
4
- hash: 53
4
+ hash: 51
5
5
  prerelease: false
6
6
  segments:
7
7
  - 3
8
8
  - 0
9
- - 25
10
- version: 3.0.25
9
+ - 26
10
+ version: 3.0.26
11
11
  platform: ruby
12
12
  authors:
13
13
  - Many, see README
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-02-28 00:00:00 +01:00
18
+ date: 2012-05-12 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency