active_scaffold-sequel 0.7.1 → 0.8.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 (36) hide show
  1. data/app/assets/javascripts/active_scaffold.js.erb +12 -14
  2. data/app/assets/javascripts/jquery/active_scaffold.js +610 -348
  3. data/app/assets/javascripts/jquery/date_picker_bridge.js.erb +37 -19
  4. data/app/assets/javascripts/jquery/draggable_lists.js +28 -27
  5. data/app/assets/javascripts/jquery/jquery.editinplace.js +145 -137
  6. data/app/assets/javascripts/jquery/tiny_mce_bridge.js +1 -1
  7. data/app/assets/stylesheets/{active_scaffold.css.scss → active_scaffold.scss} +0 -0
  8. data/app/assets/stylesheets/{active_scaffold_colors.css.scss → active_scaffold_colors.scss} +0 -0
  9. data/app/assets/stylesheets/{active_scaffold_images.css.scss → active_scaffold_images.scss} +0 -0
  10. data/frontends/default/views/_list.html.erb +1 -1
  11. data/frontends/default/views/_list_record.html.erb +2 -1
  12. data/frontends/default/views/_search.html.erb +1 -10
  13. data/frontends/default/views/add_existing.js.erb +0 -3
  14. data/lib/active_scaffold.rb +0 -12
  15. data/lib/active_scaffold/actions/list.rb +8 -3
  16. data/lib/active_scaffold/bridges/carrierwave/form_ui.rb +3 -8
  17. data/lib/active_scaffold/bridges/date_picker.rb +2 -3
  18. data/lib/active_scaffold/bridges/dragonfly/form_ui.rb +3 -7
  19. data/lib/active_scaffold/bridges/tiny_mce.rb +1 -5
  20. data/lib/active_scaffold/bridges/tiny_mce/helpers.rb +1 -5
  21. data/lib/active_scaffold/extensions/action_view_rendering.rb +1 -6
  22. data/lib/active_scaffold/extensions/routing_mapper.rb +1 -1
  23. data/lib/active_scaffold/helpers/controller_helpers.rb +2 -2
  24. data/lib/active_scaffold/helpers/form_column_helpers.rb +3 -10
  25. data/lib/active_scaffold/version.rb +2 -2
  26. data/vendor/assets/javascripts/getprototypeof.js +12 -0
  27. data/vendor/assets/javascripts/jquery-ui-timepicker-addon.js +1882 -1276
  28. metadata +71 -65
  29. checksums.yaml +0 -7
  30. data/app/assets/javascripts/prototype/active_scaffold.js +0 -1103
  31. data/app/assets/javascripts/prototype/dhtml_history.js +0 -870
  32. data/app/assets/javascripts/prototype/form_enhancements.js +0 -117
  33. data/app/assets/javascripts/prototype/rico_corner.js +0 -370
  34. data/app/assets/javascripts/prototype/tiny_mce_bridge.js +0 -7
  35. data/lib/active_scaffold/bridges/calendar_date_select.rb +0 -24
  36. data/lib/active_scaffold/bridges/calendar_date_select/as_cds_bridge.rb +0 -67
@@ -1,19 +1,17 @@
1
- <% case ActiveScaffold.js_framework %>
2
- <% when :jquery %>
3
- <% require_asset "jquery-ui" %>
4
- <% require_asset "jquery-ui-timepicker-addon" %>
1
+ <% require_asset "getprototypeof" %>
2
+ <% require_asset "jquery-ui/core" %>
3
+ <% require_asset "jquery-ui/effect" %>
4
+ <% require_asset "jquery-ui/sortable" %>
5
+ <% require_asset "jquery-ui/draggable" %>
6
+ <% require_asset "jquery-ui/droppable" %>
7
+ <% if ActiveScaffold::Bridges[:date_picker] %>
8
+ <% require_asset "jquery-ui/datepicker" %>
9
+ <% require_asset "jquery-ui-timepicker-addon" %>
10
+ <% require_asset "jquery/date_picker_bridge" %>
11
+ <% end %>
12
+ <% require_asset "jquery/draggable_lists" %>
5
13
  <% require_asset "jquery/active_scaffold" %>
6
14
  <% require_asset "jquery/jquery.editinplace" %>
7
- <% require_asset "jquery/date_picker_bridge" %>
8
- <% require_asset "jquery/draggable_lists" %>
9
- <% when :prototype %>
10
- <% require_asset "effects" %>
11
- <% require_asset "controls" %>
12
- <% require_asset "prototype/active_scaffold" %>
13
- <% require_asset "prototype/dhtml_history" %>
14
- <% require_asset "prototype/form_enhancements" %>
15
- <% require_asset "prototype/rico_corner" %>
16
- <% end %>
17
15
  ActiveScaffold.config = <%= ActiveScaffold.js_config.to_json %>;
18
16
  <% ActiveScaffold.javascripts.each {|js| require_asset js} %>
19
17
  <% ActiveScaffold::Bridges.all_javascripts.each {|js| require_asset js} %>
@@ -1,32 +1,76 @@
1
- jQuery(document).ready(function() {
2
- jQuery('form.as_form').live('ajax:beforeSend', function(event) {
1
+ jQuery(document).ready(function($) {
2
+ /* It should not be needed, latest chrome is caching by itself
3
+ if (ActiveScaffold.config.conditional_get) jQuery.ajaxSettings.ifModified = true;
4
+ jQuery(document).on('ajax:beforeSend', function(event, xhr, settings){
5
+ xhr.cacheUrl = settings.url;
6
+ });
7
+ jQuery(document).on('ajax:success', function(event, data, status, xhr){
8
+ var etag=xhr.getResponseHeader("etag");
9
+ if (etag && xhr.status==304) {
10
+ var key = etag + xhr.cacheUrl;
11
+ xhr.responseText=jQuery(document).data(key);
12
+ var conv = jQuery(document).data('type-'+key);
13
+ if (conv) conv(xhr.responseText);
14
+ }
15
+ });
16
+ jQuery(document).ajaxComplete(function(event, xhr, settings){
17
+ var etag=xhr.getResponseHeader("etag");
18
+ if (etag && settings.ifModified && xhr.responseText) {
19
+ var key = etag + xhr.cacheUrl;
20
+ jQuery(document).data(key, xhr.responseText);
21
+ var contentType = xhr.getResponseHeader('Content-Type');
22
+ for(s in settings.contents) {
23
+ if (settings.contents[s].test(contentType)) {
24
+ var conv = settings.converters['text '+s];
25
+ if (typeof conv == 'function') jQuery(document).data('type-'+key, conv);
26
+ break;
27
+ }
28
+ }
29
+ }
30
+ });
31
+ */
32
+ if (/1\.[2-7]\..*/.test(jQuery().jquery)) {
33
+ var error = 'ActiveScaffold requires jquery 1.8.0 or greater, please use jquery-rails 2.1.x gem or greater';
34
+ if (typeof console != 'undefined') console.error(error);
35
+ else alert(error);
36
+ }
37
+
38
+ jQuery(document).on('focus', ':input', function() { ActiveScaffold.last_focus = this; });
39
+ jQuery(document).on('blur', ':input', function(e) { ActiveScaffold.last_focus = e.relatedTarget; });
40
+ jQuery(document).click(function(event) {
41
+ jQuery('.action_group.dyn > ul').hide(); // only hide so action links loading still work
42
+ });
43
+ jQuery(document).on('ajax:beforeSend', 'form.as_form', function(event) {
3
44
  var as_form = jQuery(this).closest("form");
4
- if (as_form && as_form.attr('data-loading') == 'true') {
45
+ if (as_form.data('loading') == true) {
5
46
  ActiveScaffold.disable_form(as_form);
6
47
  }
7
48
  return true;
8
49
  });
9
-
10
- jQuery('form.as_form').live('ajax:complete', function(event) {
50
+
51
+ jQuery(document).on('ajax:complete', 'form.as_form', function(event) {
11
52
  var as_form = jQuery(this).closest("form");
12
- if (as_form && as_form.attr('data-loading') == 'true') {
53
+ if (as_form.data('loading') == true) {
13
54
  ActiveScaffold.enable_form(as_form);
14
55
  }
15
56
  });
16
- jQuery('form.as_form').live('ajax:error', function(event, xhr, status, error) {
57
+ jQuery(document).on('ajax:complete', 'form.live', function(event) {
58
+ ActiveScaffold.focus_first_element_of_form(jQuery(this).closest("form"));
59
+ });
60
+ jQuery(document).on('ajax:error', 'form.as_form', function(event, xhr, status, error) {
17
61
  var as_div = jQuery(this).closest("div.active-scaffold");
18
- if (as_div) {
19
- ActiveScaffold.report_500_response(as_div)
62
+ if (as_div.length) {
63
+ ActiveScaffold.report_500_response(as_div, xhr);
20
64
  }
21
65
  });
22
- jQuery('form.as_form.as_remote_upload').live('submit', function(event) {
66
+ jQuery(document).on('submit', 'form.as_form:not([data-remote])', function(event) {
23
67
  var as_form = jQuery(this).closest("form");
24
- if (as_form && as_form.attr('data-loading') == 'true') {
68
+ if (as_form.data('loading') == true) {
25
69
  setTimeout("ActiveScaffold.disable_form('" + as_form.attr('id') + "')", 10);
26
70
  }
27
71
  return true;
28
72
  });
29
- jQuery('a.as_action').live('ajax:before', function(event) {
73
+ jQuery(document).on('ajax:before', 'a.as_action', function(event) {
30
74
  var action_link = ActiveScaffold.ActionLink.get(jQuery(this));
31
75
  if (action_link) {
32
76
  if (action_link.is_disabled()) {
@@ -38,170 +82,210 @@ jQuery(document).ready(function() {
38
82
  }
39
83
  return true;
40
84
  });
41
- jQuery('a.as_action.marked_records_action').live('ajax:before', function(event) {
42
- var action_link = jQuery(this);
43
- var marked_records = 'marked_records=' + ActiveScaffold.marked_records.join('%2C');
44
- var regexp = /(\?|&)marked_records=[^&]*/g;
45
- var match;
46
- if (action_link.search[0] == '?') {
47
- match = regexp.exec(action_link.search);
48
- if (match) {
49
- action_link.search = action_link.search.slice(0, match.index) + match[1] + marked_records + action_link.search.slice(regexp.lastIndex, action_link.search.length);
50
- } else {
51
- action_link.search = action_link.search + '&' + marked_records;
52
- }
53
- } else {
54
- action_link.search = '?' + marked_records;
55
- }
56
- return true;
57
- });
58
- jQuery('a.as_action.marked_records_action').live('ajax:complete', function(event) {
59
- var action_link = jQuery(this);
60
- ActiveScaffold.mark_records(action_link.readAttribute('data-tbody_id'), false);
61
- ActiveScaffold.marked_records = [];
62
- return true;
63
- });
64
- jQuery('a.as_action').live('ajax:success', function(event, response) {
85
+ jQuery(document).on('ajax:success', 'a.as_action', function(event, response) {
65
86
  var action_link = ActiveScaffold.ActionLink.get(jQuery(this));
66
87
  if (action_link) {
67
88
  if (action_link.position) {
68
89
  action_link.insert(response);
69
90
  if (action_link.hide_target) action_link.target.hide();
70
91
  } else {
92
+ if (action_link.tag.hasClass('toggle')) {
93
+ action_link.tag.closest('.action_group,.actions').find('.toggle.active').removeClass('active');
94
+ action_link.tag.addClass('active');
95
+ }
71
96
  action_link.enable();
72
97
  }
73
98
  jQuery(this).trigger('as:action_success', action_link);
99
+ if (action_link.loading_indicator) action_link.loading_indicator.css('visibility','hidden');
74
100
  }
75
101
  return true;
76
102
  });
77
- jQuery('a.as_action').live('ajax:complete', function(event) {
103
+ jQuery(document).on('ajax:error', 'a.as_action', function(event, xhr, status, error) {
78
104
  var action_link = ActiveScaffold.ActionLink.get(jQuery(this));
79
105
  if (action_link) {
80
- if (action_link.loading_indicator) action_link.loading_indicator.css('visibility','hidden');
106
+ ActiveScaffold.report_500_response(action_link.scaffold_id(), xhr);
107
+ action_link.enable();
81
108
  }
82
109
  return true;
83
110
  });
84
- jQuery('a.as_action').live('ajax:error', function(event, xhr, status, error) {
85
- var action_link = ActiveScaffold.ActionLink.get(jQuery(this));
86
- if (action_link) {
87
- ActiveScaffold.report_500_response(action_link.scaffold_id());
88
- action_link.enable();
111
+ jQuery(document).on('ajax:before', 'a.as_action.marked_records_action', function(event) {
112
+ var action_link = jQuery(this);
113
+ var marked_records = 'marked_records=' + ActiveScaffold.marked_records.join('%2C');
114
+ var regexp = /(\?|&)marked_records=[^&]*/g;
115
+ var match;
116
+ var search = action_link.prop('search');
117
+ if (search[0] == '?') {
118
+ match = regexp.exec(search);
119
+ if (match) {
120
+ action_link.prop('search', search.slice(0, match.index) + match[1] + marked_records + search.slice(regexp.lastIndex, search.length));
121
+ } else {
122
+ action_link.prop('search', search + '&' + marked_records);
123
+ }
124
+ } else {
125
+ action_link.prop('search', '?' + marked_records);
89
126
  }
90
127
  return true;
91
128
  });
92
- jQuery('a.as_cancel').live('ajax:before', function(event) {
129
+ jQuery(document).on('ajax:complete', 'a.as_action.marked_records_action', function(event) {
130
+ var action_link = jQuery(this);
131
+ ActiveScaffold.mark_records(action_link.attr('data-tbody_id'), false);
132
+ ActiveScaffold.marked_records = [];
133
+ return true;
134
+ });
135
+ jQuery(document).on('ajax:before', 'a.as_cancel', function(event) {
93
136
  var as_cancel = jQuery(this);
94
- var action_link = ActiveScaffold.find_action_link(as_cancel);
95
-
137
+ var action_link = ActiveScaffold.find_action_link(as_cancel);
138
+
96
139
  if (action_link) {
97
140
  var cancel_url = as_cancel.attr('href');
98
- var refresh_data = as_cancel.attr('data-refresh');
99
- if (refresh_data !== 'true' || !cancel_url) {
141
+ var refresh_data = action_link.tag.data('cancel-refresh') || as_cancel.data('refresh');
142
+ if (!refresh_data || !cancel_url) {
100
143
  action_link.close();
101
144
  return false;
102
145
  }
103
146
  }
104
147
  return true;
105
148
  });
106
- jQuery('a.as_cancel').live('ajax:success', function(event, response) {
107
- var action_link = ActiveScaffold.find_action_link(jQuery(this));
108
-
109
- if (action_link) {
110
- if (action_link.position) {
111
- action_link.close(response);
112
- } else {
113
- response.evalResponse();
114
- }
149
+ jQuery(document).on('ajax:success', 'a.as_cancel', function(event) {
150
+ var link = jQuery(this), action_link = ActiveScaffold.find_action_link(link);
151
+
152
+ if (action_link && action_link.position) {
153
+ action_link.close();
154
+ } else if (link.hasClass('reset')) {
155
+ var form = link.closest('form');
156
+ if (form.is('.search')) form.find(':input:visible:not([type=submit])').val('');
157
+ else form.trigger('reset');
115
158
  }
116
159
  return true;
117
160
  });
118
- jQuery('a.as_cancel').live('ajax:error', function(event, xhr, status, error) {
161
+ jQuery(document).on('ajax:error', 'a.as_cancel', function(event, xhr, status, error) {
119
162
  var action_link = ActiveScaffold.find_action_link(jQuery(this));
120
163
  if (action_link) {
121
- ActiveScaffold.report_500_response(action_link.scaffold_id());
164
+ ActiveScaffold.report_500_response(action_link.scaffold_id(), xhr);
122
165
  }
123
166
  return true;
124
167
  });
125
- jQuery('a.as_sort').live('ajax:before', function(event) {
168
+ jQuery(document).on('ajax:before', 'a.as_sort', function(event) {
126
169
  var as_sort = jQuery(this);
127
- var history_controller_id = as_sort.attr('data-page-history');
170
+ var history_controller_id = as_sort.data('page-history');
128
171
  if (history_controller_id) addActiveScaffoldPageToHistory(as_sort.attr('href'), history_controller_id);
129
172
  as_sort.closest('th').addClass('loading');
130
173
  return true;
131
174
  });
132
- jQuery('a.as_sort').live('ajax:error', function(event, xhr, status, error) {
175
+ jQuery(document).on('ajax:error', 'a.as_sort', function(event, xhr, status, error) {
133
176
  var as_scaffold = jQuery(this).closest('.active-scaffold');
134
- ActiveScaffold.report_500_response(as_scaffold);
177
+ ActiveScaffold.report_500_response(as_scaffold, xhr);
178
+ jQuery(this).closest('th').removeClass('loading');
135
179
  return true;
136
180
  });
137
- jQuery('span.mark_record_field,span.mark_heading,span.in_place_editor_field').live('hover', function(event) {
138
- jQuery(this).data(); // $ 1.4.2 workaround
139
- if (event.type == 'mouseenter') {
140
- if (typeof(jQuery(this).data('editInPlace')) === 'undefined') jQuery(this).addClass("hover");
141
- }
142
- if (event.type == 'mouseleave') {
143
- if (typeof(jQuery(this).data('editInPlace')) === 'undefined') jQuery(this).removeClass("hover");
144
- }
145
- return true;
146
- });
147
- jQuery('span.mark_record_field').live('click', function(event) {
148
- ActiveScaffold.mark_span(jQuery(this));
181
+ jQuery(document).on('click', 'span.mark_record_field', function(event) {
182
+ ActiveScaffold.mark_span(this);
149
183
  });
150
- jQuery('span.mark_heading').live('click', function(event) {
184
+ jQuery(document).on('click', 'span.mark_heading', function(event) {
151
185
  var span = jQuery(this);
152
- var checkbox = span.find('input[type="checkbox"]').first();
186
+ var checkbox = span.find('input[type="checkbox"]').eq(0);
153
187
  var tbody_id = span.attr('data-tbody_id');
154
- if (checkbox.checked) {
188
+ if (checkbox.prop('checked')) {
155
189
  ActiveScaffold.mark_records(tbody_id, true);
156
190
  } else {
157
191
  ActiveScaffold.mark_records(tbody_id, false);
158
192
  }
159
193
  });
160
- jQuery('span.in_place_editor_field').live('click', function(event) {
161
- ActiveScaffold.in_place_editor_field_clicked(jQuery(this));
194
+ jQuery(document).on('mouseenter mouseleave', 'span.mark_record_field,span.mark_heading,td.in_place_editor_field', function(event) {
195
+ var td = jQuery(this), span = td.find('span.in_place_editor_field');
196
+ if (event.type == 'mouseenter') {
197
+ if (td.hasClass('empty') || typeof(span.data('editInPlace')) === 'undefined') td.find('span').addClass("hover");
198
+ }
199
+ if (event.type == 'mouseleave') {
200
+ if (td.hasClass('empty') || typeof(span.data('editInPlace')) === 'undefined') td.find('span').removeClass("hover");
201
+ }
202
+ return true;
203
+ });
204
+ jQuery(document).on('click', 'td.in_place_editor_field, th.as_marked-column_heading', function(event) {
205
+ var span = jQuery(this).find('span.in_place_editor_field');
206
+ span.data('addEmptyOnCancel', jQuery(this).hasClass('empty'));
207
+ jQuery(this).removeClass('empty');
208
+ if (span.data('editInPlace')) span.trigger('click.editInPlace');
209
+ else ActiveScaffold.in_place_editor_field_clicked(span);
162
210
  });
163
- jQuery('a.as_paginate').live('ajax:before',function(event) {
211
+ jQuery(document).on('ajax:before', 'a.as_paginate',function(event) {
164
212
  var as_paginate = jQuery(this);
165
- var history_controller_id = as_paginate.attr('data-page-history');
213
+ var history_controller_id = as_paginate.data('page-history');
166
214
  if (history_controller_id) addActiveScaffoldPageToHistory(as_paginate.attr('href'), history_controller_id);
167
215
  as_paginate.prevAll('img.loading-indicator').css('visibility','visible');
168
216
  return true;
169
217
  });
170
- jQuery('a.as_paginate').live('ajax:error', function(event, xhr, status, error) {
218
+ jQuery(document).on('ajax:error', 'a.as_paginate', function(event, xhr, status, error) {
171
219
  var as_scaffold = jQuery(this).closest('.active-scaffold');
172
- ActiveScaffold.report_500_response(as_scaffold);
220
+ ActiveScaffold.report_500_response(as_scaffold, xhr);
173
221
  return true;
174
222
  });
175
- jQuery('a.as_paginate').live('ajax:complete', function(event) {
223
+ jQuery(document).on('ajax:complete', 'a.as_paginate', function(event) {
176
224
  jQuery(this).prevAll('img.loading-indicator').css('visibility','hidden');
177
225
  return true;
178
226
  });
179
- jQuery('a.as_add_existing, a.as_replace_existing').live('ajax:before', function(event) {
180
- var id = jQuery(this).prev().val();
227
+ jQuery(document).on('ajax:before', 'a.as_add_existing, a.as_replace_existing', function(event) {
228
+ var prev = jQuery(this).prev();
229
+ if (!prev.is(':input')) prev = prev.find(':input');
230
+ var id = prev.val();
181
231
  if (id) {
182
232
  if (!jQuery(this).data('href')) jQuery(this).data('href', jQuery(this).attr('href'));
183
233
  jQuery(this).attr('href', jQuery(this).data('href').replace('--ID--', id));
184
234
  return true;
185
235
  } else return false;
186
236
  });
187
- jQuery('input.update_form:not(.recordselect), textarea.update_form, select.update_form').live('change', function(event) {
237
+ jQuery(document).on('ajax:complete', '.action_group.dyn > ul a', function(event) {
238
+ var action_link = ActiveScaffold.find_action_link(event.target);
239
+ if (action_link.loading_indicator) action_link.loading_indicator.css('visibility','hidden');
240
+ jQuery(event.target).closest('.action_group.dyn > ul').remove();
241
+ });
242
+
243
+ jQuery(document).on('change', 'input.update_form:not(.recordselect), textarea.update_form, select.update_form, .checkbox-list.update_form input:checkbox', function(event) {
188
244
  var element = jQuery(this);
189
- var value = element.is("input:checkbox:not(:checked)") ? null : element.val();
190
- ActiveScaffold.update_column(element, element.attr('data-update_url'), element.attr('data-update_send_form'), element.attr('id'), value);
245
+ var form_element = element.closest('.checkbox-list');
246
+ var value, additional_params;
247
+ if (form_element.is(".checkbox-list")) {
248
+ value = form_element.find(':checked').map(function(item){return $(this).val();}).toArray();
249
+ additional_params = (element.is(':checked') ? '_added=' : '_removed=') + element.val();
250
+ } else {
251
+ value = element.is("input:checkbox:not(:checked)") ? null : element.val();
252
+ form_element = element;
253
+ }
254
+ ActiveScaffold.update_column(form_element, form_element.data('update_url'), form_element.data('update_send_form'), element.attr('id'), value, additional_params);
191
255
  return true;
192
256
  });
193
- jQuery('input.recordselect.update_form').live('recordselect:change', function(event, id, label) {
257
+ jQuery(document).on('click', 'a.refresh-link', function(event) {
258
+ event.preventDefault();
194
259
  var element = jQuery(this);
195
- ActiveScaffold.update_column(element, element.attr('data-update_url'), element.attr('data-update_send_form'), element.attr('id'), id);
260
+ var form_element = element.prev();
261
+ var value;
262
+ if (form_element.is(".checkbox-list")) {
263
+ value = form_element.find(':checked').map(function(item){return $(this).val();}).toArray();
264
+ form_element = form_element.parent().find("input:checkbox"); // parent is needed for draggable-list, checked list may be empty
265
+ } else value = form_element.is("input:checkbox:not(:checked)") ? null : form_element.val();
266
+ ActiveScaffold.update_column(form_element, element.attr('href'), element.data('update_send_form'), form_element.attr('id'), value);
267
+ });
268
+ jQuery(document).on('click', 'a.visibility-toggle', function(e) {
269
+ var link = jQuery(this), toggable = jQuery('#' + link.data('toggable'));
270
+ e.preventDefault();
271
+ toggable.toggle();
272
+ link.html((toggable.is(':hidden')) ? link.data('show') : link.data('hide'));
273
+ return false;
274
+ });
275
+ jQuery(document).on('recordselect:change', 'input.recordselect.update_form', function(event, id, label) {
276
+ var element = jQuery(this);
277
+ ActiveScaffold.update_column(element, element.data('update_url'), element.data('update_send_form'), element.attr('id'), id);
196
278
  return true;
197
279
  });
198
-
199
- jQuery('select.as_search_range_option').live('change', function(event) {
200
- ActiveScaffold[jQuery(this).val() == 'BETWEEN' ? 'show' : 'hide'](jQuery(this).parent().find('.as_search_range_between'));
280
+
281
+ jQuery(document).on('change', 'select.as_search_range_option', function(event) {
282
+ var element = jQuery(this);
283
+ ActiveScaffold[element.val() == 'BETWEEN' ? 'show' : 'hide'](element.closest('dd').find('.as_search_range_between'));
284
+ ActiveScaffold[(element.val() == 'null' || element.val() == 'not_null') ? 'hide' : 'show'](element.attr('id').replace(/_opt/, '_numeric'));
201
285
  return true;
202
286
  });
203
-
204
- jQuery('select.as_search_range_option').live('change', function(event) {
287
+
288
+ jQuery(document).on('change', 'select.as_search_date_time_option', function(event) {
205
289
  var element = jQuery(this);
206
290
  ActiveScaffold[!(element.val() == 'PAST' || element.val() == 'FUTURE' || element.val() == 'RANGE') ? 'show' : 'hide'](element.attr('id').replace(/_opt/, '_numeric'));
207
291
  ActiveScaffold[(element.val() == 'PAST' || element.val() == 'FUTURE') ? 'show' : 'hide'](element.attr('id').replace(/_opt/, '_trend'));
@@ -209,18 +293,18 @@ jQuery(document).ready(function() {
209
293
  return true;
210
294
  });
211
295
 
212
- jQuery('select.as_update_date_operator').live('change', function(event) {
296
+ jQuery(document).on('change', 'select.as_update_date_operator', function(event) {
213
297
  ActiveScaffold[jQuery(this).val() == 'REPLACE' ? 'show' : 'hide'](jQuery(this).next());
214
298
  ActiveScaffold[jQuery(this).val() == 'REPLACE' ? 'hide' : 'show'](jQuery(this).next().next());
215
299
  return true;
216
300
  });
217
301
 
218
- jQuery('a[data-popup]').live('click', function(e) {
219
- window.open(jQuery(this).attr('href'));
220
- e.preventDefault();
302
+ jQuery(document).on('click', '.active-scaffold .sub-form a.destroy', function(event) {
303
+ event.preventDefault();
304
+ ActiveScaffold.delete_subform_record($(this).data('delete-id'));
221
305
  });
222
306
 
223
- jQuery('.hover_click').live("click", function(event) {
307
+ jQuery(document).on("click", '.hover_click', function(event) {
224
308
  var element = jQuery(this);
225
309
  var ul_element = element.children('ul').first();
226
310
  if (ul_element.is(':visible')) {
@@ -230,15 +314,42 @@ jQuery(document).ready(function() {
230
314
  }
231
315
  return false;
232
316
  });
233
- jQuery('.hover_click a.as_action').live('click', function(event) {
317
+ jQuery(document).on('click', '.hover_click a.as_action', function(event) {
234
318
  var element = jQuery(this).closest('.hover_click');
235
- if (element) {
319
+ if (element.length) {
236
320
  element.find('ul').hide();
237
321
  }
238
322
  return true;
239
323
  });
324
+
325
+ jQuery(document).on('click', '.message a.close', function(e) {
326
+ ActiveScaffold.hide(jQuery(this).closest('.message'));
327
+ e.preventDefault();
328
+ });
329
+
330
+ /* setup some elements on page/form load */
331
+ ActiveScaffold.load_embedded(document);
332
+ ActiveScaffold.enable_js_form_buttons(document);
333
+ ActiveScaffold.live_search(document);
334
+ ActiveScaffold.auto_paginate(document);
335
+ ActiveScaffold.draggable_lists('.draggable-lists', document);
336
+ if (ActiveScaffold.config.warn_changes) ActiveScaffold.setup_warn_changes();
337
+ jQuery(document).on('as:element_updated', function(e) {
338
+ ActiveScaffold.load_embedded(e.target);
339
+ ActiveScaffold.enable_js_form_buttons(e.target);
340
+ ActiveScaffold.live_search(e.target);
341
+ ActiveScaffold.draggable_lists('.draggable-lists', e.target);
342
+ });
343
+ jQuery(document).on('as:action_success', 'a.as_action', function(e, action_link) {
344
+ ActiveScaffold.load_embedded(action_link.adapter);
345
+ ActiveScaffold.enable_js_form_buttons(action_link.adapter);
346
+ ActiveScaffold.live_search(action_link.adapter);
347
+ ActiveScaffold.auto_paginate(action_link.adapter);
348
+ ActiveScaffold.draggable_lists('.draggable-lists', action_link.adapter);
349
+ });
240
350
  });
241
351
 
352
+
242
353
  /* Simple Inheritance
243
354
  http://ejohn.org/blog/simple-javascript-inheritance/
244
355
  */
@@ -247,17 +358,17 @@ jQuery(document).ready(function() {
247
358
 
248
359
  // The base Class implementation (does nothing)
249
360
  this.Class = function(){};
250
-
361
+
251
362
  // Create a new Class that inherits from this class
252
363
  Class.extend = function(prop) {
253
364
  var _super = this.prototype;
254
-
365
+
255
366
  // Instantiate a base class (but only create the instance,
256
367
  // don't run the init constructor)
257
368
  initializing = true;
258
369
  var prototype = new this();
259
370
  initializing = false;
260
-
371
+
261
372
  // Copy the properties over onto the new prototype
262
373
  for (var name in prop) {
263
374
  // Check if we're overwriting an existing function
@@ -266,38 +377,38 @@ jQuery(document).ready(function() {
266
377
  (function(name, fn){
267
378
  return function() {
268
379
  var tmp = this._super;
269
-
380
+
270
381
  // Add a new ._super() method that is the same method
271
382
  // but on the super-class
272
383
  this._super = _super[name];
273
-
384
+
274
385
  // The method only need to be bound temporarily, so we
275
386
  // remove it when we're done executing
276
- var ret = fn.apply(this, arguments);
387
+ var ret = fn.apply(this, arguments);
277
388
  this._super = tmp;
278
-
389
+
279
390
  return ret;
280
391
  };
281
392
  })(name, prop[name]) :
282
393
  prop[name];
283
394
  }
284
-
395
+
285
396
  // The dummy class constructor
286
397
  function Class() {
287
398
  // All construction is actually done in the init method
288
399
  if ( !initializing && this.init )
289
400
  this.init.apply(this, arguments);
290
401
  }
291
-
402
+
292
403
  // Populate our constructed prototype object
293
404
  Class.prototype = prototype;
294
-
405
+
295
406
  // Enforce the constructor to be what we expect
296
407
  Class.constructor = Class;
297
408
 
298
409
  // And make this class extendable
299
410
  Class.extend = arguments.callee;
300
-
411
+
301
412
  return Class;
302
413
  };
303
414
  })();
@@ -305,60 +416,38 @@ jQuery(document).ready(function() {
305
416
  /*
306
417
  $ delayed observer
307
418
  (c) 2007 - Maxime Haineault (max@centdessin.com)
308
-
419
+
309
420
  Special thanks to Stephen Goguen & Tane Piper.
310
-
421
+
311
422
  Slight modifications by Elliot Winkler
312
423
  */
313
424
 
314
- if (typeof(jQuery.fn.delayedObserver) === 'undefined') {
315
- (function() {
316
- var delayedObserverStack = [];
317
- var observed;
318
-
319
- function delayedObserverCallback(stackPos) {
320
- observed = delayedObserverStack[stackPos];
321
- if (observed.timer) return;
322
-
323
- observed.timer = setTimeout(function(){
324
- observed.timer = null;
325
- observed.callback(observed.obj.val(), observed.obj);
326
- }, observed.delay * 1000);
327
-
328
- observed.oldVal = observed.obj.val();
329
- }
330
-
331
- // going by
332
- // <http://www.cambiaresearch.com/c4/702b8cd1-e5b0-42e6-83ac-25f0306e3e25/Javascript-Char-Codes-Key-Codes.aspx>
333
- // I think these codes only work when using keyup or keydown
334
- function isNonPrintableKey(event) {
335
- var code = event.keyCode;
336
- return (
337
- event.metaKey ||
338
- (code >= 9 && code <= 16) || (code >= 27 && code <= 40) || (code >= 91 && code <= 93) || (code >= 112 && code <= 145)
339
- );
340
- }
341
-
342
- jQuery.fn.extend({
343
- delayedObserver:function(delay, callback){
344
- $this = jQuery(this);
345
-
346
- delayedObserverStack.push({
347
- obj: $this, timer: null, delay: delay,
348
- oldVal: $this.val(), callback: callback
349
- });
350
-
351
- stackPos = delayedObserverStack.length-1;
352
-
353
- $this.keyup(function(event) {
354
- if (isNonPrintableKey(event)) return;
355
- observed = delayedObserverStack[stackPos];
356
- if (observed.obj.val() == observed.obj.oldVal) return;
357
- else delayedObserverCallback(stackPos);
358
- });
425
+ if (typeof(jQuery.fn.delayedObserver) === 'undefined') {
426
+ (function($){
427
+ $.extend($.fn, {
428
+ delayedObserver: function(callback, delay, options){
429
+ return this.each(function(){
430
+ var el = $(this);
431
+ var op = options || {};
432
+ el.data('oldval', el.val())
433
+ .data('delay', delay || 0.5)
434
+ .data('condition', op.condition || function() { return ($(this).data('oldval') == $(this).val()); })
435
+ .data('callback', callback)
436
+ [(op.event||'keyup')](function(){
437
+ if (el.data('condition').apply(el)) { return; }
438
+ else {
439
+ if (el.data('timer')) { clearTimeout(el.data('timer')); }
440
+ el.data('timer', setTimeout(function(){
441
+ var callback = el.data('callback')
442
+ if (callback) callback.apply(el);
443
+ }, el.data('delay') * 1000));
444
+ el.data('oldval', el.val());
445
+ }
446
+ });
447
+ });
359
448
  }
360
449
  });
361
- })();
450
+ })(jQuery);
362
451
  };
363
452
 
364
453
 
@@ -367,6 +456,34 @@ if (typeof(jQuery.fn.delayedObserver) === 'undefined') {
367
456
  */
368
457
 
369
458
  var ActiveScaffold = {
459
+ last_focus: null,
460
+ live_search: function(element) {
461
+ jQuery('form.search.live input[type=search]', element).delayedObserver(function() {
462
+ jQuery(this).parent().trigger("submit");
463
+ }, ActiveScaffold.config.live_search_delay || 0.5);
464
+ },
465
+ auto_paginate: function(element) {
466
+ var paginate_link = jQuery('.active-scaffold-pagination.auto-paginate a:first', element);
467
+ if (paginate_link.length) {
468
+ jQuery('.active-scaffold-pagination.auto-paginate', element).hide();
469
+ ActiveScaffold.auto_load_page(paginate_link.attr('href'), {auto_pagination: true});
470
+ }
471
+ },
472
+ auto_load_page: function(href, params) {
473
+ jQuery.get(href, params, null, 'script');
474
+ },
475
+ enable_js_form_buttons: function(element) {
476
+ jQuery('.as-js-button', element).show();
477
+ },
478
+ load_embedded: function(element) {
479
+ jQuery('.active-scaffold-component .load-embedded', element).each(function(index, item) {
480
+ item = jQuery(item);
481
+ item.closest('.active-scaffold-component').load(item.attr('href'), function() {
482
+ jQuery(this).trigger('as:element_updated');
483
+ });
484
+ });
485
+ },
486
+
370
487
  records_for: function(tbody_id) {
371
488
  if (typeof(tbody_id) == 'string') tbody_id = '#' + tbody_id;
372
489
  return jQuery(tbody_id).children('.record');
@@ -374,7 +491,7 @@ var ActiveScaffold = {
374
491
  stripe: function(tbody_id) {
375
492
  var even = false;
376
493
  var rows = this.records_for(tbody_id);
377
-
494
+
378
495
  rows.each(function (index, row_node) {
379
496
  row = jQuery(row_node);
380
497
  if (row_node.tagName != 'SCRIPT'
@@ -387,27 +504,30 @@ var ActiveScaffold = {
387
504
  else row.removeClass("even-record");
388
505
 
389
506
  even = !even;
390
- }
507
+ }
391
508
  });
392
509
  },
393
510
  hide_empty_message: function(tbody) {
394
511
  if (this.records_for(tbody).length != 0) {
395
- var empty_message_node = jQuery(tbody).parent().find('tbody.messages p.empty-message')
396
- if (empty_message_node) empty_message_node.hide();
512
+ jQuery(tbody).parent().find('tbody.messages p.empty-message').hide();
397
513
  }
398
514
  },
399
515
  reload_if_empty: function(tbody, url) {
400
516
  if (this.records_for(tbody).length == 0) {
401
- jQuery.getScript(url);
517
+ this.reload(url);
402
518
  }
403
519
  },
520
+ reload: function(url) {
521
+ jQuery.getScript(url);
522
+ },
404
523
  removeSortClasses: function(scaffold) {
405
524
  if (typeof(scaffold) == 'string') scaffold = '#' + scaffold;
406
525
  scaffold = jQuery(scaffold)
407
- scaffold.find('td.sorted').each(function(element) {
408
- element.removeClass("sorted");
526
+ scaffold.find('td.sorted').each(function(index, element) {
527
+ jQuery(element).removeClass("sorted");
409
528
  });
410
- scaffold.find('th.sorted').each(function(element) {
529
+ scaffold.find('th.sorted').each(function(index, element) {
530
+ element = jQuery(element);
411
531
  element.removeClass("sorted");
412
532
  element.removeClass("asc");
413
533
  element.removeClass("desc");
@@ -415,213 +535,279 @@ var ActiveScaffold = {
415
535
  },
416
536
  decrement_record_count: function(scaffold) {
417
537
  // decrement the last record count, firsts record count are in nested lists
418
- if (typeof(scaffold) == 'string') scaffold = '#' + scaffold;
419
- scaffold = jQuery(scaffold)
538
+ if (typeof(scaffold) == 'string') scaffold = '#' + scaffold;
539
+ scaffold = jQuery(scaffold);
420
540
  count = scaffold.find('span.active-scaffold-records').last();
421
541
  if (count) count.html(parseInt(count.html(), 10) - 1);
422
542
  },
423
543
  increment_record_count: function(scaffold) {
424
544
  // increment the last record count, firsts record count are in nested lists
425
545
  if (typeof(scaffold) == 'string') scaffold = '#' + scaffold;
426
- scaffold = jQuery(scaffold)
546
+ scaffold = jQuery(scaffold);
427
547
  count = scaffold.find('span.active-scaffold-records').last();
428
548
  if (count) count.html(parseInt(count.html(), 10) + 1);
429
549
  },
430
550
  update_row: function(row, html) {
431
551
  var even_row = false;
432
552
  var replaced = null;
433
- if (typeof(row) == 'string') row = '#' + row;
553
+ if (typeof(row) == 'string') row = '#' + row;
434
554
  row = jQuery(row);
435
555
  if (row.hasClass('even-record')) even_row = true;
436
556
 
437
557
  replaced = this.replace(row, html);
438
- if (even_row === true) replaced.addClass('even-record');
439
- ActiveScaffold.highlight(replaced);
558
+ if (replaced) {
559
+ if (even_row === true) replaced.addClass('even-record');
560
+ ActiveScaffold.highlight(replaced);
561
+ }
440
562
  },
441
-
563
+
442
564
  replace: function(element, html) {
443
- if (typeof(element) == 'string') element = '#' + element;
565
+ if (typeof(element) == 'string') element = '#' + element;
566
+ element = jQuery(element);
567
+ var new_element = typeof(html) == 'string' ? jQuery.parseHTML(jQuery.trim(html), true) : html;
568
+ new_element = jQuery(new_element);
569
+ if (element.length) {
570
+ element.replaceWith(new_element);
571
+ new_element.trigger('as:element_updated');
572
+ return new_element;
573
+ } else return null;
574
+ },
575
+
576
+ replace_html: function(element, html) {
577
+ if (typeof(element) == 'string') element = '#' + element;
444
578
  element = jQuery(element);
445
- element.replaceWith(html);
446
- if (element.attr('id')) {
447
- element = jQuery('#' + element.attr('id'));
579
+ if (element.length) {
580
+ element.html(html);
581
+ element.trigger('as:element_updated');
448
582
  }
449
583
  return element;
450
584
  },
451
-
452
- replace_html: function(element, html) {
453
- if (typeof(element) == 'string') element = '#' + element;
585
+
586
+ append: function(element, html) {
587
+ if (typeof(element) == 'string') element = '#' + element;
454
588
  element = jQuery(element);
455
- element.html(html);
589
+ element.append(html);
590
+ element.trigger('as:element_updated');
456
591
  return element;
457
592
  },
458
-
459
- remove: function(element) {
460
- if (typeof(element) == 'string') element = '#' + element;
461
- jQuery(element).remove();
593
+
594
+ remove: function(element, callback) {
595
+ if (typeof(element) == 'string') element = '#' + element;
596
+ jQuery(element).trigger('as:element_removed').remove();
597
+ if (callback) callback();
598
+ },
599
+
600
+ update_inplace_edit: function(element, value, empty) {
601
+ if (typeof(element) == 'string') element = '#' + element;
602
+ this.replace_html(jQuery(element), value);
603
+ jQuery(element).closest('td')[empty ? 'addClass' : 'removeClass']('empty');
462
604
  },
463
-
605
+
464
606
  hide: function(element) {
465
607
  if (typeof(element) == 'string') element = '#' + element;
466
608
  jQuery(element).hide();
467
609
  },
468
-
610
+
469
611
  show: function(element) {
470
612
  if (typeof(element) == 'string') element = '#' + element;
471
613
  jQuery(element).show();
472
614
  },
473
-
615
+
474
616
  reset_form: function(element) {
475
617
  if (typeof(element) == 'string') element = '#' + element;
476
618
  jQuery(element).get(0).reset();
477
619
  },
478
-
479
- disable_form: function(as_form) {
620
+
621
+ disable_form: function(as_form, skip_loading_indicator) {
480
622
  if (typeof(as_form) == 'string') as_form = '#' + as_form;
481
623
  as_form = jQuery(as_form)
482
624
  var loading_indicator = jQuery('#' + as_form.attr('id').replace(/-form$/, '-loading-indicator'));
483
- if (loading_indicator) loading_indicator.css('visibility','visible');
625
+ if (!skip_loading_indicator && loading_indicator) loading_indicator.css('visibility','visible');
484
626
  jQuery('input[type=submit]', as_form).attr('disabled', 'disabled');
485
- as_form[0].disabled_fields = jQuery("input:enabled,select:enabled,textarea:enabled", as_form).attr('disabled', 'disabled');
627
+ jQuery('.sub-form a.destroy', as_form).addClass('disabled');
628
+ if (jQuery.fn.droppable) jQuery('.draggable-list', as_form).sortable('disable');
629
+ // data-remote-disabled attr instead of set data because is used to in selector later
630
+ jQuery("input:enabled,select:enabled,textarea:enabled", as_form).attr('disabled', 'disabled').attr('data-remove-disabled', true);
486
631
  },
487
-
488
- enable_form: function(as_form) {
632
+
633
+ enable_form: function(as_form, skip_loading_indicator) {
489
634
  if (typeof(as_form) == 'string') as_form = '#' + as_form;
490
635
  as_form = jQuery(as_form)
491
636
  var loading_indicator = jQuery('#' + as_form.attr('id').replace(/-form$/, '-loading-indicator'));
492
- if (loading_indicator) loading_indicator.css('visibility','hidden');
637
+ if (!skip_loading_indicator && loading_indicator) loading_indicator.css('visibility','hidden');
493
638
  jQuery('input[type=submit]', as_form).removeAttr('disabled');
494
- as_form[0].disabled_fields.removeAttr('disabled');
495
- },
496
-
497
- focus_first_element_of_form: function(form_element) {
639
+ jQuery('.sub-form a.destroy.disabled', as_form).removeClass('disabled');
640
+ if (jQuery.fn.droppable) jQuery('.draggable-list', as_form).sortable('enable');
641
+ jQuery("input[data-remove-disabled],select[data-remove-disabled],textarea[data-remove-disabled]", as_form).removeAttr('disabled data-remove-disabled');
642
+ },
643
+
644
+ focus_first_element_of_form: function(form_element, form_selector) {
498
645
  if (typeof(form_element) == 'string') form_element = '#' + form_element;
499
- jQuery(form_element + ":first *:input[type!=hidden]:first").focus();
646
+ if (typeof(form_selector) == 'undefined') form_selector = jQuery(form_element).is('form') ? '' : 'form ';
647
+ jQuery(form_selector + ":input:visible:first", jQuery(form_element)).focus();
500
648
  },
501
-
649
+
502
650
  create_record_row: function(active_scaffold_id, html, options) {
503
651
  if (typeof(active_scaffold_id) == 'string') active_scaffold_id = '#' + active_scaffold_id;
504
- tbody = jQuery(active_scaffold_id).find('tbody.records');
505
-
652
+ tbody = jQuery(active_scaffold_id).find('tbody.records').first();
653
+ var new_row;
654
+
506
655
  if (options.insert_at == 'top') {
507
656
  tbody.prepend(html);
508
- var new_row = tbody.children('tr.record:first-child');
657
+ new_row = tbody.children('tr.record:first-child');
509
658
  } else if (options.insert_at == 'bottom') {
510
659
  var rows = tbody.children('tr.record, tr.inline-adapter');
511
- var new_row = null;
512
660
  if (rows.length > 0) {
513
661
  new_row = rows.last().after(html).next();
514
662
  } else {
515
663
  new_row = tbody.append(html).children().last();
516
664
  }
665
+ } else if (typeof options.insert_at == 'object') {
666
+ var insert_method, get_method, row, id;
667
+ if (options.insert_at.after) {
668
+ insert_method = 'after';
669
+ get_method = 'next';
670
+ } else {
671
+ insert_method = 'before';
672
+ get_method = 'prev';
673
+ }
674
+ if (id = options.insert_at[insert_method]) row = tbody.children('#' + id);
675
+ if (row && row.length) {
676
+ new_row = row[insert_method](html)[get_method]();
677
+ }
517
678
  }
518
679
  this.stripe(tbody);
519
680
  this.hide_empty_message(tbody);
520
681
  this.increment_record_count(tbody.closest('div.active-scaffold'));
521
- ActiveScaffold.highlight(new_row);
682
+ this.highlight(new_row);
683
+ new_row.trigger('as:element_created');
684
+ },
685
+
686
+ create_record_row_from_url: function(action_link, url, options) {
687
+ jQuery.get(url, function(row) {
688
+ ActiveScaffold.create_record_row(action_link.scaffold(), row, options);
689
+ action_link.close();
690
+ });
522
691
  },
523
-
692
+
524
693
  delete_record_row: function(row, page_reload_url) {
525
694
  if (typeof(row) == 'string') row = '#' + row;
526
695
  row = jQuery(row);
527
696
  var tbody = row.closest('tbody.records');
528
-
529
- var current_action_node = row.find('td.actions a.disabled').first();
530
- if (current_action_node) {
531
- var action_link = ActiveScaffold.ActionLink.get(current_action_node);
532
- if (action_link) {
533
- action_link.close_previous_adapter();
534
- }
535
- }
536
-
537
- row.remove();
538
- this.stripe(tbody);
539
- this.decrement_record_count(tbody.closest('div.active-scaffold'));
540
- this.reload_if_empty(tbody, page_reload_url);
697
+
698
+ row.find('a.disabled').each(function() {;
699
+ var action_link = ActiveScaffold.ActionLink.get(this);
700
+ if (action_link) action_link.close();
701
+ });
702
+
703
+ ActiveScaffold.remove(row, function() {
704
+ ActiveScaffold.stripe(tbody);
705
+ ActiveScaffold.decrement_record_count(tbody.closest('div.active-scaffold'));
706
+ if (page_reload_url) ActiveScaffold.reload_if_empty(tbody, page_reload_url);
707
+ });
541
708
  },
542
709
 
543
710
  delete_subform_record: function(record) {
544
711
  if (typeof(record) == 'string') record = '#' + record;
545
- record = jQuery(record);
546
- var errors = record.prev();
547
- if (errors.hasClass('association-record-errors')) {
548
- this.remove(errors);
549
- }
550
- var associated = jQuery(record).next();
712
+ record = jQuery(record).closest('.sub-form-record');
551
713
  this.remove(record);
552
- while (associated.hasClass('associated-record')) {
553
- record = associated;
554
- associated = jQuery(record).next();
555
- this.remove(record);
556
- }
557
714
  },
558
715
 
559
- report_500_response: function(active_scaffold_id) {
560
- server_error = jQuery(active_scaffold_id).find('td.messages-container p.server-error');
561
- if (!jQuery(server_error).is(':visible')) {
716
+ report_500_response: function(active_scaffold_id, xhr) {
717
+ var server_error = jQuery(active_scaffold_id).find('td.messages-container p.server-error').first();
718
+ if (server_error.is(':visible')) {
719
+ ActiveScaffold.highlight(server_error);
720
+ } else {
562
721
  server_error.show();
563
722
  }
723
+ if (xhr) server_error.find('.error-500')[xhr.status < 500 ? 'hide' : 'show']();
724
+ ActiveScaffold.scroll_to(server_error, ActiveScaffold.config.scroll_on_close == 'checkInViewport');
564
725
  },
565
-
726
+
566
727
  find_action_link: function(element) {
567
728
  if (typeof(element) == 'string') element = '#' + element;
568
- var as_adapter = jQuery(element).closest('.as_adapter');
569
- return ActiveScaffold.ActionLink.get(as_adapter);
729
+ element = jQuery(element);
730
+ return ActiveScaffold.ActionLink.get(element.is('.actions a') ? element : element.closest('.as_adapter'));
570
731
  },
571
-
572
- scroll_to: function(element) {
732
+
733
+ display_dynamic_action_group: function(link, html) {
734
+ var container;
735
+ if (typeof(link) == 'string') link = jQuery('#' + link);
736
+ if (link.closest('td.actions').length) {
737
+ container = link.closest('td').addClass('action_group dyn');
738
+ } else {
739
+ if (link.parent('div.actions').length) link.wrap(jQuery('<div>'));
740
+ container = link.parent().addClass('action_group dyn');
741
+ }
742
+ container.find('> ul').remove();
743
+ container.append(html);
744
+ },
745
+
746
+ scroll_to: function(element, checkInViewport) {
747
+ if (typeof checkInViewport == 'undefined') checkInViewport = true;
573
748
  if (typeof(element) == 'string') element = '#' + element;
574
- var form_offset = jQuery(element).offset(),
575
- destination = form_offset.top;
576
- jQuery(document).scrollTop(destination);
749
+ var form_offset = jQuery(element).offset().top;
750
+ if (checkInViewport) {
751
+ var docViewTop = jQuery(window).scrollTop(),
752
+ docViewBottom = docViewTop + jQuery(window).height();
753
+ // If it's in viewport , don't scroll;
754
+ if (form_offset + jQuery(element).height() <= docViewBottom && form_offset >= docViewTop) return;
755
+ }
756
+
757
+ jQuery(document).scrollTop(form_offset);
577
758
  },
578
-
759
+
579
760
  process_checkbox_inplace_edit: function(checkbox, options) {
580
- var checked = checkbox.is(':checked');
761
+ var checked = checkbox.is(':checked'), td = checkbox.closest('td');
581
762
  if (checked === true) options['params'] += '&value=1';
582
763
  jQuery.ajax({
583
764
  url: options.url,
584
765
  type: "POST",
585
766
  data: options['params'],
586
767
  dataType: options.ajax_data_type,
587
- after: function(request){
768
+ beforeSend: function(request, settings) {
769
+ if (options.beforeSend) options.beforeSend.call(checkbox, request, settings);
588
770
  checkbox.attr('disabled', 'disabled');
771
+ td.closest('tr').find('td.actions .loading-indicator').css('visibility','visible');
589
772
  },
590
773
  complete: function(request){
591
774
  checkbox.removeAttr('disabled');
775
+ },
776
+ success: function(request){
777
+ td.closest('tr').find('td.actions .loading-indicator').css('visibility','hidden');
592
778
  }
593
779
  });
594
780
  },
595
-
781
+
596
782
  read_inplace_edit_heading_attributes: function(column_heading, options) {
597
- if (column_heading.attr('data-ie_cancel_text')) options.cancel_button = '<button class="inplace_cancel">' + column_heading.attr('data-ie_cancel_text') + "</button>";
598
- if (column_heading.attr('data-ie_loading_text')) options.loading_text = column_heading.attr('data-ie_loading_text');
599
- if (column_heading.attr('data-ie_saving_text')) options.saving_text = column_heading.attr('data-ie_saving_text');
600
- if (column_heading.attr('data-ie_save_text')) options.save_button = '<button class="inplace_save">' + column_heading.attr('data-ie_save_text') + "</button>";
601
- if (column_heading.attr('data-ie_rows')) options.textarea_rows = column_heading.attr('data-ie_rows');
602
- if (column_heading.attr('data-ie_cols')) options.textarea_cols = column_heading.attr('data-ie_cols');
603
- if (column_heading.attr('data-ie_size')) options.text_size = column_heading.attr('data-ie_size');
604
- },
605
-
783
+ if (column_heading.data('ie-cancel-text')) options.cancel_button = '<button class="inplace_cancel">' + column_heading.data('ie-cancel-text') + "</button>";
784
+ if (column_heading.data('ie-loading-text')) options.loading_text = column_heading.data('ie-loading-text');
785
+ if (column_heading.data('ie-saving-text')) options.saving_text = column_heading.data('ie-saving-text');
786
+ if (column_heading.data('ie-save-text')) options.save_button = '<button class="inplace_save">' + column_heading.data('ie-save-text') + "</button>";
787
+ if (column_heading.data('ie-rows')) options.textarea_rows = column_heading.data('ie-rows');
788
+ if (column_heading.data('ie-cols')) options.textarea_cols = column_heading.data('ie-cols');
789
+ if (column_heading.data('ie-size')) options.text_size = column_heading.data('ie-size');
790
+ },
791
+
606
792
  create_inplace_editor: function(span, options) {
607
793
  span.removeClass('hover');
608
794
  span.editInPlace(options);
609
795
  span.trigger('click.editInPlace');
610
796
  },
611
-
797
+
612
798
  highlight: function(element) {
613
799
  if (typeof(element) == 'string') element = jQuery('#' + element);
614
800
  if (typeof(element.effect) == 'function') {
615
- element.effect("highlight", {}, 3000);
801
+ element.effect("highlight", jQuery.extend({}, ActiveScaffold.config.highlight), 3000);
616
802
  }
617
803
  },
618
-
804
+
619
805
  create_visibility_toggle: function(element, options) {
620
806
  if (typeof(element) == 'string') element = '#' + element;
621
807
  var toggable = jQuery(element);
622
808
  var toggler = toggable.prev();
623
809
  var initial_label = (options.default_visible === true) ? options.hide_label : options.show_label;
624
-
810
+
625
811
  toggler.append(' (<a class="visibility-toggle" href="#">' + initial_label + '</a>)');
626
812
  toggler.children('a').click(function() {
627
813
  toggable.toggle();
@@ -629,34 +815,42 @@ var ActiveScaffold = {
629
815
  return false;
630
816
  });
631
817
  },
632
-
818
+
633
819
  create_associated_record_form: function(element, content, options) {
634
820
  if (typeof(element) == 'string') element = '#' + element;
635
821
  var element = jQuery(element);
822
+ content = jQuery(content);
636
823
  if (options.singular == false) {
637
824
  if (!(options.id && jQuery('#' + options.id).size() > 0)) {
638
- element.append(content);
825
+ var tfoot = element.children('tfoot');
826
+ if (tfoot.length) tfoot.before(content);
827
+ else element.append(content);
639
828
  }
640
829
  } else {
641
- var current = jQuery('#' + element.attr('id') + ' .association-record')
830
+ var current = jQuery('#' + element.attr('id') + ' .sub-form-record')
642
831
  if (current[0]) {
643
832
  this.replace(current[0], content);
644
833
  } else {
645
834
  element.prepend(content);
646
835
  }
647
836
  }
837
+ ActiveScaffold.focus_first_element_of_form(content, '');
838
+ content.trigger('as:element_created');
648
839
  },
649
-
840
+
650
841
  render_form_field: function(source, content, options) {
651
842
  if (typeof(source) == 'string') source = '#' + source;
652
843
  var source = jQuery(source);
653
- var element = source.closest('.association-record');
844
+ var element = source.closest('.sub-form-record'), selector = '';
654
845
  if (element.length == 0) {
655
846
  element = source.closest('form > ol.form');
847
+ selector = 'li';
656
848
  }
657
- element = element.find('.' + options.field_class + ":first");
849
+ // find without entering new subforms
850
+ selector = options.is_subform ? '' : selector + ':not(.sub-form) ';
851
+ element = element.find(selector + '.' + options.field_class).first();
658
852
 
659
- if (element) {
853
+ if (element.length) {
660
854
  if (options.is_subform == false) {
661
855
  this.replace(element.closest('dl'), content);
662
856
  } else {
@@ -664,35 +858,21 @@ var ActiveScaffold = {
664
858
  }
665
859
  }
666
860
  },
667
-
668
- sortable: function(element, controller, options, url_params) {
669
- if (typeof(element) == 'string') element = '#' + element;
670
- var element = jQuery(element);
671
- var sortable_options = {};
672
- if (options.update === true) {
673
- url_params.authenticity_token = jQuery('meta[name=csrf-param]').attr('content');
674
- sortable_options.update = function(event, ui) {
675
- var url = controller + '/' + options.action + '?'
676
- url += jQuery(this).sortable('serialize',{key: encodeURIComponent(jQuery(this).attr('id') + '[]'), expression:/^[^_-](?:[A-Za-z0-9_-]*)-(.*)-row$/});
677
- jQuery.post(url.append_params(url_params));
678
- }
679
- }
680
- element.sortable(sortable_options);
681
- },
682
861
 
683
862
  record_select_onselect: function(edit_associated_url, active_scaffold_id, id){
684
863
  jQuery.ajax({
685
- url: edit_associated_url.split('--ID--').join(id),
864
+ url: edit_associated_url.replace('--ID--', id),
686
865
  error: function(xhr, textStatus, errorThrown){
687
- ActiveScaffold.report_500_response(active_scaffold_id)
866
+ ActiveScaffold.report_500_response(active_scaffold_id, xhr)
688
867
  }
689
868
  });
690
869
  },
691
870
 
692
871
  mark_span: function(span, mark_flag) {
693
- var record_id = span.attr('data-ie_id');
694
- var checkbox = span.find('input[type="checkbox"]').first();
695
- if (mark_flag == false || (typeof(mark_flag) == 'undefined' && !checkbox.checked)) {
872
+ var element = jQuery(span);
873
+ var record_id = element.attr('data-ie_id');
874
+ var checkbox = element.find('input[type="checkbox"]').eq(0);
875
+ if (mark_flag == false || (typeof(mark_flag) == 'undefined' && !checkbox.prop('checked'))) {
696
876
  ActiveScaffold.unmark_record(record_id);
697
877
  } else {
698
878
  ActiveScaffold.mark_record(record_id);
@@ -701,11 +881,11 @@ var ActiveScaffold = {
701
881
  },
702
882
 
703
883
  mark_records: function(tbody_id, mark_flag) {
704
- var spans = $('#' + tbody_id + ' > tr.record td.marked-column span.mark_record_field');
884
+ var spans = jQuery('#' + tbody_id + ' > tr.record td.marked-column span.mark_record_field');
705
885
  var checkbox;
706
886
  for (var i = 0; i < spans.length; i++) {
707
887
  checkbox = ActiveScaffold.mark_span(spans[i], mark_flag);
708
- checkbox.checked = mark_flag;
888
+ checkbox.prop('checked', mark_flag);
709
889
  }
710
890
  },
711
891
 
@@ -724,12 +904,21 @@ var ActiveScaffold = {
724
904
  },
725
905
 
726
906
  in_place_editor_field_clicked: function(span) {
727
- span.data(); // $ 1.4.2 workaround
907
+ // test editor is open
728
908
  if (typeof(span.data('editInPlace')) === 'undefined') {
729
909
  var options = {show_buttons: true,
730
910
  hover_class: 'hover',
731
911
  element_id: 'editor_id',
732
912
  ajax_data_type: "script",
913
+ delegate: {
914
+ willCloseEditInPlace: function(span, options) {
915
+ if (span.data('addEmptyOnCancel')) span.closest('td').addClass('empty');
916
+ span.closest('tr').find('td.actions .loading-indicator').css('visibility','visible');
917
+ },
918
+ didCloseEditInPlace: function(span, options) {
919
+ span.closest('tr').find('td.actions .loading-indicator').css('visibility','hidden');
920
+ }
921
+ },
733
922
  update_value: 'value'},
734
923
  csrf_param = jQuery('meta[name=csrf-param]').first(),
735
924
  csrf_token = jQuery('meta[name=csrf-token]').first(),
@@ -737,7 +926,7 @@ var ActiveScaffold = {
737
926
  column_heading = null;
738
927
 
739
928
  if(!(my_parent.is('td') || my_parent.is('th'))){
740
- my_parent = span.parents('td').eq(0);
929
+ my_parent = span.parents('td').eq(0);
741
930
  }
742
931
 
743
932
  if (my_parent.is('td')) {
@@ -747,25 +936,25 @@ var ActiveScaffold = {
747
936
  column_heading = my_parent;
748
937
  }
749
938
 
750
- var render_url = column_heading.attr('data-ie_render_url'),
751
- mode = column_heading.attr('data-ie_mode'),
752
- record_id = span.attr('data-ie_id');
939
+ var render_url = column_heading.data('ie-render-url'),
940
+ mode = column_heading.data('ie-mode'),
941
+ record_id = span.data('ie-id') || '';
753
942
 
754
943
  ActiveScaffold.read_inplace_edit_heading_attributes(column_heading, options);
755
944
 
756
- if (span.attr('data-ie_url')) {
757
- options.url = span.attr('data-ie_url').replace(/__id__/, record_id);
945
+ if (span.data('ie-url')) {
946
+ options.url = span.data('ie-url').replace(/__id__/, record_id);
758
947
  } else {
759
- options.url = column_heading.attr('data-ie_url').replace(/__id__/, record_id);
948
+ options.url = column_heading.data('ie-url').replace(/__id__/, record_id);
760
949
  }
761
950
 
762
951
  if (csrf_param) options['params'] = csrf_param.attr('content') + '=' + csrf_token.attr('content');
763
952
 
764
- if (span.closest('div.active-scaffold').attr('data-eid')) {
953
+ if (span.closest('div.active-scaffold').data('eid')) {
765
954
  if (options['params'].length > 0) {
766
955
  options['params'] += "&";
767
956
  }
768
- options['params'] += ("eid=" + span.closest('div.active-scaffold').attr('data-eid'));
957
+ options['params'] += ("eid=" + span.closest('div.active-scaffold').data('eid'));
769
958
  }
770
959
 
771
960
  if (mode === 'clone') {
@@ -776,9 +965,29 @@ var ActiveScaffold = {
776
965
 
777
966
  if (render_url) {
778
967
  var plural = false;
779
- if (column_heading.attr('data-ie_plural')) plural = true;
968
+ if (column_heading.data('ie-plural')) plural = true;
780
969
  options.field_type = 'remote';
781
970
  options.editor_url = render_url.replace(/__id__/, record_id)
971
+ if (!options.delegate) options.delegate = {}
972
+ options.delegate.didOpenEditInPlace = function(dom) { dom.trigger('as:element_updated'); }
973
+ }
974
+ var actions, forms;
975
+ options.beforeSend = function(xhr, settings) {
976
+ switch (span.data('ie-update')) {
977
+ case 'update_row':
978
+ actions = span.closest('tr').find('.actions a:not(.disabled)').addClass('disabled');
979
+ break;
980
+ case 'update_table':
981
+ var table = span.closest('.as_content');
982
+ actions = table.find('.actions a:not(.disabled)').addClass('disabled');
983
+ forms = table.find('.as_form');
984
+ ActiveScaffold.disable_form(forms);
985
+ break;
986
+ }
987
+ }
988
+ options.error = options.success = function() {
989
+ if (actions) actions.removeClass('disabled');
990
+ if (forms) ActiveScaffold.enable_form(forms);
782
991
  }
783
992
  if (mode === 'inline_checkbox') {
784
993
  ActiveScaffold.process_checkbox_inplace_edit(span.find('input:checkbox'), options);
@@ -787,18 +996,21 @@ var ActiveScaffold = {
787
996
  }
788
997
  }
789
998
  },
790
-
791
- update_column: function(element, url, send_form, source_id, val) {
999
+
1000
+ update_column: function(element, url, send_form, source_id, val, additional_params) {
792
1001
  if (!element) element = jQuery('#' + source_id);
793
1002
  var as_form = element.closest('form.as_form');
794
1003
  var params = null;
795
1004
 
796
1005
  if (send_form) {
797
- var selector;
1006
+ var selector, base = as_form;
1007
+ if (send_form == 'row') base = element.closest('.association-record, form');
798
1008
  if (selector = element.data('update_send_form_selector'))
799
- params = as_form.find(selector).serialize();
800
- else params = as_form.serialize();
801
- params += '&' + jQuery.param({"source_id": source_id});
1009
+ params = base.find(selector).serialize();
1010
+ else if (base != as_form) params = base.find(':input').serialize();
1011
+ else params = base.serialize();
1012
+ params += '&_method=&' + jQuery.param({"source_id": source_id});
1013
+ if (additional_params) params += '&' + additional_params;
802
1014
  } else {
803
1015
  params = {value: val};
804
1016
  params.source_id = source_id;
@@ -807,25 +1019,54 @@ var ActiveScaffold = {
807
1019
  jQuery.ajax({
808
1020
  url: url,
809
1021
  data: params,
810
- beforeSend: function(event) {
1022
+ type: 'post',
1023
+ beforeSend: function(xhr, settings) {
811
1024
  element.nextAll('img.loading-indicator').css('visibility','visible');
812
1025
  ActiveScaffold.disable_form(as_form);
1026
+ if ($.rails.fire(element, 'ajax:beforeSend', [xhr, settings])) {
1027
+ element.trigger('ajax:send', xhr);
1028
+ } else {
1029
+ return false;
1030
+ }
813
1031
  },
814
- complete: function(event) {
1032
+ success: function(data, status, xhr) {
1033
+ as_form.find('#'+element.attr('id')).trigger('ajax:success', [data, status, xhr]);
1034
+ },
1035
+ complete: function(xhr, status) {
1036
+ element = as_form.find('#'+element.attr('id'));
815
1037
  element.nextAll('img.loading-indicator').css('visibility','hidden');
816
- ActiveScaffold.enable_form(as_form);
1038
+ element.trigger('ajax:complete', [xhr, status]);
1039
+ if (ActiveScaffold.last_focus) jQuery(ActiveScaffold.last_focus).focus().select();
817
1040
  },
818
1041
  error: function (xhr, status, error) {
1042
+ element = as_form.find('#'+element.attr('id'));
819
1043
  var as_div = element.closest("div.active-scaffold");
820
- if (as_div) {
821
- ActiveScaffold.report_500_response(as_div);
822
- }
1044
+ if (as_div) ActiveScaffold.report_500_response(as_div, xhr);
1045
+ element.trigger('ajax:error', [xhr, status, error]);
823
1046
  }
824
1047
  });
825
1048
  },
826
-
827
- draggable_lists: function(element) {
828
- jQuery('#' + element).draggable_lists();
1049
+
1050
+ draggable_lists: function(selector_or_elements, parent) {
1051
+ var elements;
1052
+ if (!jQuery.fn.draggableLists) return;
1053
+ if (typeof(selector_or_elements) == 'string') elements = jQuery(selector_or_elements, parent);
1054
+ else elements = jQuery(selector_or_elements);
1055
+ elements.draggableLists();
1056
+ },
1057
+
1058
+ setup_warn_changes: function() {
1059
+ var need_confirm = false;
1060
+ var unload_message = $('meta[name=unload-message]').attr('content') || ActiveScaffold.config.unload_message || "This page contains unsaved data that will be lost if you leave this page.";
1061
+ $(document).on('change input', '.active-scaffold form:not(.search) input, .active-scaffold form:not(.search) textarea, .active-scaffold form:not(.search) select', function() {
1062
+ $(this).closest('form').addClass('need-confirm');
1063
+ });
1064
+ $(document).on('click', '.active-scaffold .as_cancel:not([data-remote])', function() {
1065
+ $(this).closest('form').removeClass('need-confirm');
1066
+ });
1067
+ window.onbeforeunload = function() {
1068
+ if ($('form.need-confirm').length) return unload_message;
1069
+ }
829
1070
  }
830
1071
  }
831
1072
 
@@ -854,8 +1095,8 @@ String.prototype.append_params = function(params) {
854
1095
  for(var key in params) {
855
1096
  if (key) url += (key + '=' + params[key] + '&');
856
1097
  }
857
-
858
- // the loop leaves a comma dangling at the end of string, chop it off
1098
+
1099
+ // the loop leaves a comma dangling at the end of string, chop it off
859
1100
  url = url.substring(0, url.length-1);
860
1101
  return url;
861
1102
  };
@@ -870,7 +1111,7 @@ ActiveScaffold.Actions.Abstract = Class.extend({
870
1111
  this.target = jQuery(target);
871
1112
  this.loading_indicator = jQuery(loading_indicator);
872
1113
  this.options = options;
873
- var _this = this;
1114
+ var _this = this;
874
1115
  this.links = jQuery.map(links, function(link) {
875
1116
  var my_link = _this.instantiate_link(link);
876
1117
  return my_link;
@@ -894,19 +1135,19 @@ ActiveScaffold.ActionLink = {
894
1135
  element.data(); // $ 1.4.2 workaround
895
1136
  if (typeof(element.data('action_link')) === 'undefined' && !element.hasClass('as_adapter')) {
896
1137
  var parent = element.closest('.actions');
897
- if (parent.length === 0) {
1138
+ if (parent.length === 0 || parent.is('td')) {
898
1139
  // maybe an column action_link
899
- parent = element.parent();
1140
+ parent = element.closest('tr.record');
900
1141
  }
901
- if (parent && parent.is('td')) {
1142
+ if (parent.is('tr')) {
902
1143
  // record action
903
- parent = parent.closest('tr.record');
904
1144
  var target = parent.find('a.as_action');
905
1145
  var loading_indicator = parent.find('td.actions .loading-indicator');
1146
+ if (!loading_indicator.length) loading_indicator = element.parent().find('.loading-indicator');
906
1147
  new ActiveScaffold.Actions.Record(target, parent, loading_indicator);
907
1148
  } else if (parent && parent.is('div')) {
908
1149
  //table action
909
- new ActiveScaffold.Actions.Table(parent.find('a.as_action'), parent.closest('div.active-scaffold').find('tbody.before-header'), parent.find('.loading-indicator'));
1150
+ new ActiveScaffold.Actions.Table(parent.find('a.as_action'), parent.closest('div.active-scaffold').find('tbody.before-header').first(), parent.find('.loading-indicator').first());
910
1151
  }
911
1152
  element = jQuery(element);
912
1153
  }
@@ -920,29 +1161,34 @@ ActiveScaffold.ActionLink.Abstract = Class.extend({
920
1161
  init: function(a, target, loading_indicator) {
921
1162
  this.tag = jQuery(a);
922
1163
  this.url = this.tag.attr('href');
923
- this.method = this.tag.attr('data-method') || 'get';
1164
+ this.method = this.tag.data('method') || 'get';
924
1165
  this.target = target;
925
1166
  this.loading_indicator = loading_indicator;
926
1167
  this.hide_target = false;
927
- this.position = this.tag.attr('data-position');
928
- this.action = this.tag.attr('data-action');
1168
+ this.position = this.tag.data('position');
1169
+ this.action = this.tag.data('action');
929
1170
 
930
1171
  this.tag.data('action_link', this);
931
1172
  return this;
932
1173
  },
933
1174
 
934
1175
  open: function(event) {
1176
+ this.tag.click();
935
1177
  },
936
-
1178
+
937
1179
  insert: function(content) {
938
1180
  throw 'unimplemented'
939
1181
  },
940
1182
 
941
1183
  close: function() {
942
- this.enable();
943
- this.adapter.remove();
944
- if (this.hide_target) this.target.show();
945
- if (ActiveScaffold.config.scroll_on_close) ActiveScaffold.scroll_to(this.target);
1184
+ if (this.adapter) {
1185
+ var link = this;
1186
+ ActiveScaffold.remove(this.adapter, function() {
1187
+ link.enable();
1188
+ if (link.hide_target) link.target.show();
1189
+ if (ActiveScaffold.config.scroll_on_close) ActiveScaffold.scroll_to(link.target.attr('id'), ActiveScaffold.config.scroll_on_close == 'checkInViewport');
1190
+ });
1191
+ }
946
1192
  },
947
1193
 
948
1194
  reload: function() {
@@ -976,7 +1222,7 @@ ActiveScaffold.ActionLink.Abstract = Class.extend({
976
1222
  scaffold: function() {
977
1223
  return this.tag.closest('div.active-scaffold');
978
1224
  },
979
-
1225
+
980
1226
  update_flash_messages: function(messages) {
981
1227
  message_node = jQuery(this.scaffold_id().replace(/-active-scaffold/, '-messages'));
982
1228
  if (message_node) message_node.html(messages);
@@ -985,7 +1231,10 @@ ActiveScaffold.ActionLink.Abstract = Class.extend({
985
1231
  this.adapter = element;
986
1232
  this.adapter.addClass('as_adapter');
987
1233
  this.adapter.data('action_link', this);
988
- if (this.refresh_url) jQuery('.as_cancel[data-refresh=true]', this.adapter).attr('href', this.refresh_url);
1234
+ if (this.refresh_url) jQuery('.as_cancel', this.adapter).attr('href', this.refresh_url);
1235
+ },
1236
+ keep_open: function() {
1237
+ return this.tag.data('keep-open');
989
1238
  }
990
1239
  });
991
1240
 
@@ -995,9 +1244,9 @@ ActiveScaffold.ActionLink.Abstract = Class.extend({
995
1244
  ActiveScaffold.Actions.Record = ActiveScaffold.Actions.Abstract.extend({
996
1245
  instantiate_link: function(link) {
997
1246
  var l = new ActiveScaffold.ActionLink.Record(link, this.target, this.loading_indicator);
998
- var refresh = this.target.attr('data-refresh');
999
- if (refresh) l.refresh_url = refresh;
1000
-
1247
+ var refresh = this.target.data('refresh');
1248
+ if (refresh) l.refresh_url = this.target.closest('.records').data('refresh-record').replace('--ID--', refresh);
1249
+
1001
1250
  if (l.position) {
1002
1251
  l.url = l.url.append_params({adapter: '_list_inline_adapter'});
1003
1252
  l.tag.attr('href', l.url);
@@ -1011,9 +1260,8 @@ ActiveScaffold.ActionLink.Record = ActiveScaffold.ActionLink.Abstract.extend({
1011
1260
  close_previous_adapter: function() {
1012
1261
  var _this = this;
1013
1262
  jQuery.each(this.set.links, function(index, item) {
1014
- if (item.url != _this.url && item.is_disabled() && item.adapter) {
1015
- item.enable();
1016
- item.adapter.remove();
1263
+ if (item.url != _this.url && item.is_disabled() && !item.keep_open() && item.adapter) {
1264
+ ActiveScaffold.remove(item.adapter, function () { item.enable(); });
1017
1265
  }
1018
1266
  });
1019
1267
  },
@@ -1026,6 +1274,11 @@ ActiveScaffold.ActionLink.Record = ActiveScaffold.ActionLink.Abstract.extend({
1026
1274
  this.hide_target = true;
1027
1275
  }
1028
1276
 
1277
+ var colspan = this.target.children().length;
1278
+ if (content && this.position) {
1279
+ content = jQuery(content);
1280
+ content.find('.inline-adapter-cell:first').attr('colspan', colspan);
1281
+ }
1029
1282
  if (this.position == 'after') {
1030
1283
  this.target.after(content);
1031
1284
  this.set_adapter(this.target.next());
@@ -1037,14 +1290,22 @@ ActiveScaffold.ActionLink.Record = ActiveScaffold.ActionLink.Abstract.extend({
1037
1290
  else {
1038
1291
  return false;
1039
1292
  }
1293
+ ActiveScaffold.focus_first_element_of_form(this.adapter);
1040
1294
  ActiveScaffold.highlight(this.adapter.find('td'));
1041
1295
  },
1042
1296
 
1043
- close: function(refreshed_content) {
1044
- if (refreshed_content) {
1045
- ActiveScaffold.update_row(this.target, refreshed_content);
1046
- }
1297
+ close: function(refreshed_content_or_reload) {
1047
1298
  this._super();
1299
+ if (refreshed_content_or_reload) {
1300
+ if (typeof refreshed_content_or_reload == 'string') {
1301
+ ActiveScaffold.update_row(this.target, refreshed_content_or_reload);
1302
+ } else if (this.refresh_url) {
1303
+ var target = this.target;
1304
+ jQuery.get(this.refresh_url, function(e, status, response) {
1305
+ ActiveScaffold.update_row(target, response.responseText);
1306
+ });
1307
+ }
1308
+ }
1048
1309
  },
1049
1310
 
1050
1311
  enable: function() {
@@ -1062,7 +1323,7 @@ ActiveScaffold.ActionLink.Record = ActiveScaffold.ActionLink.Abstract.extend({
1062
1323
  item.tag.addClass('disabled');
1063
1324
  });
1064
1325
  },
1065
-
1326
+
1066
1327
  set_opened: function() {
1067
1328
  if (this.position == 'after') {
1068
1329
  this.set_adapter(this.target.next());
@@ -1097,6 +1358,7 @@ ActiveScaffold.ActionLink.Table = ActiveScaffold.ActionLink.Abstract.extend({
1097
1358
  else {
1098
1359
  throw 'Unknown position "' + this.position + '"'
1099
1360
  }
1361
+ ActiveScaffold.focus_first_element_of_form(this.adapter);
1100
1362
  ActiveScaffold.highlight(this.adapter.find('td').first().children());
1101
1363
  }
1102
1364
  });