active_scaffold 3.3.3 → 3.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (198) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +39 -0
  3. data/README.md +5 -3
  4. data/app/assets/images/active_scaffold/refresh.png +0 -0
  5. data/app/assets/javascripts/jquery/active_scaffold.js +182 -91
  6. data/app/assets/javascripts/jquery/date_picker_bridge.js.erb +14 -16
  7. data/app/assets/javascripts/jquery/draggable_lists.js +33 -26
  8. data/app/assets/javascripts/jquery/jquery.editinplace.js +3 -3
  9. data/app/assets/javascripts/prototype/active_scaffold.js +61 -19
  10. data/app/assets/stylesheets/active_scaffold_colors.css.scss +4 -0
  11. data/app/assets/stylesheets/active_scaffold_images.css.scss +3 -0
  12. data/app/assets/stylesheets/active_scaffold_layout.css +23 -2
  13. data/app/views/active_scaffold_overrides/_add_existing_form.html.erb +1 -3
  14. data/app/views/active_scaffold_overrides/_base_form.html.erb +7 -5
  15. data/app/views/active_scaffold_overrides/_field_search.html.erb +1 -2
  16. data/app/views/active_scaffold_overrides/_form.html.erb +6 -4
  17. data/app/views/active_scaffold_overrides/_form_association.html.erb +4 -3
  18. data/app/views/active_scaffold_overrides/_form_association_footer.html.erb +5 -5
  19. data/app/views/active_scaffold_overrides/_form_association_record.html.erb +8 -6
  20. data/app/views/active_scaffold_overrides/_horizontal_subform_header.html.erb +3 -2
  21. data/app/views/active_scaffold_overrides/_list.html.erb +8 -6
  22. data/app/views/active_scaffold_overrides/_list_column_headings.html.erb +1 -4
  23. data/app/views/active_scaffold_overrides/_list_pagination.html.erb +4 -4
  24. data/app/views/active_scaffold_overrides/_list_pagination_links.html.erb +1 -1
  25. data/app/views/active_scaffold_overrides/_list_record.html.erb +3 -3
  26. data/app/views/active_scaffold_overrides/_refresh_list.js.erb +8 -1
  27. data/app/views/active_scaffold_overrides/_search.html.erb +7 -13
  28. data/app/views/active_scaffold_overrides/_show_columns.html.erb +1 -1
  29. data/app/views/active_scaffold_overrides/on_create.js.erb +4 -4
  30. data/app/views/active_scaffold_overrides/render_field_inplace.html.erb +1 -1
  31. data/app/views/active_scaffold_overrides/row.js.erb +1 -1
  32. data/config/locales/de.yml +106 -95
  33. data/config/locales/en.yml +108 -97
  34. data/config/locales/es.yml +109 -98
  35. data/config/locales/fr.yml +108 -97
  36. data/config/locales/hu.yml +109 -98
  37. data/config/locales/ja.yml +100 -89
  38. data/config/locales/ru.yml +115 -104
  39. data/lib/active_scaffold.rb +18 -294
  40. data/lib/active_scaffold/actions/common_search.rb +50 -17
  41. data/lib/active_scaffold/actions/core.rb +93 -22
  42. data/lib/active_scaffold/actions/create.rb +15 -6
  43. data/lib/active_scaffold/actions/field_search.rb +68 -60
  44. data/lib/active_scaffold/actions/list.rb +49 -28
  45. data/lib/active_scaffold/actions/nested.rb +14 -6
  46. data/lib/active_scaffold/actions/search.rb +36 -35
  47. data/lib/active_scaffold/actions/show.rb +9 -4
  48. data/lib/active_scaffold/actions/subform.rb +1 -1
  49. data/lib/active_scaffold/actions/update.rb +22 -7
  50. data/lib/active_scaffold/active_record_permissions.rb +125 -118
  51. data/lib/active_scaffold/attribute_params.rb +84 -66
  52. data/lib/active_scaffold/bridges.rb +3 -3
  53. data/lib/active_scaffold/bridges/ancestry/ancestry_bridge.rb +10 -5
  54. data/lib/active_scaffold/bridges/cancan.rb +2 -1
  55. data/lib/active_scaffold/bridges/cancan/cancan_bridge.rb +13 -2
  56. data/lib/active_scaffold/bridges/carrierwave/form_ui.rb +11 -6
  57. data/lib/active_scaffold/bridges/chosen/helpers.rb +2 -2
  58. data/lib/active_scaffold/bridges/country_helper/country_helper_bridge.rb +45 -29
  59. data/lib/active_scaffold/bridges/date_picker/ext.rb +11 -6
  60. data/lib/active_scaffold/bridges/date_picker/helper.rb +5 -1
  61. data/lib/active_scaffold/bridges/dragonfly/form_ui.rb +10 -5
  62. data/lib/active_scaffold/bridges/dragonfly/list_ui.rb +6 -1
  63. data/lib/active_scaffold/bridges/file_column/form_ui.rb +12 -11
  64. data/lib/active_scaffold/bridges/paperclip/form_ui.rb +14 -6
  65. data/lib/active_scaffold/bridges/paperclip/list_ui.rb +1 -1
  66. data/lib/active_scaffold/bridges/record_select/helpers.rb +15 -12
  67. data/lib/active_scaffold/bridges/shared/date_bridge.rb +7 -8
  68. data/lib/active_scaffold/bridges/tiny_mce.rb +5 -3
  69. data/lib/active_scaffold/bridges/tiny_mce/helpers.rb +4 -5
  70. data/lib/active_scaffold/config/base.rb +4 -0
  71. data/lib/active_scaffold/config/core.rb +12 -5
  72. data/lib/active_scaffold/config/delete.rb +0 -2
  73. data/lib/active_scaffold/config/field_search.rb +1 -4
  74. data/lib/active_scaffold/config/form.rb +0 -2
  75. data/lib/active_scaffold/config/list.rb +31 -1
  76. data/lib/active_scaffold/config/search.rb +0 -3
  77. data/lib/active_scaffold/config/show.rb +0 -6
  78. data/lib/active_scaffold/config/subform.rb +1 -0
  79. data/lib/active_scaffold/configurable.rb +2 -2
  80. data/lib/active_scaffold/constraints.rb +11 -14
  81. data/lib/active_scaffold/core.rb +277 -0
  82. data/lib/active_scaffold/data_structures/action_columns.rb +18 -2
  83. data/lib/active_scaffold/data_structures/action_link.rb +25 -6
  84. data/lib/active_scaffold/data_structures/action_links.rb +9 -4
  85. data/lib/active_scaffold/data_structures/actions.rb +1 -1
  86. data/lib/active_scaffold/data_structures/column.rb +6 -6
  87. data/lib/active_scaffold/data_structures/columns.rb +2 -2
  88. data/lib/active_scaffold/data_structures/nested_info.rb +5 -1
  89. data/lib/active_scaffold/data_structures/sorting.rb +15 -5
  90. data/lib/active_scaffold/delayed_setup.rb +30 -0
  91. data/lib/active_scaffold/engine.rb +25 -0
  92. data/lib/active_scaffold/extensions/action_view_rendering.rb +1 -1
  93. data/lib/active_scaffold/extensions/left_outer_joins.rb +61 -21
  94. data/lib/active_scaffold/extensions/localize.rb +1 -1
  95. data/lib/active_scaffold/extensions/name_option_for_datetime.rb +13 -8
  96. data/lib/active_scaffold/extensions/paginator_extensions.rb +5 -1
  97. data/lib/active_scaffold/extensions/reverse_associations.rb +1 -0
  98. data/lib/active_scaffold/extensions/routing_mapper.rb +1 -1
  99. data/lib/active_scaffold/extensions/unsaved_record.rb +4 -6
  100. data/lib/active_scaffold/finder.rb +79 -27
  101. data/lib/active_scaffold/helpers/association_helpers.rb +48 -18
  102. data/lib/active_scaffold/helpers/controller_helpers.rb +19 -10
  103. data/lib/active_scaffold/helpers/form_column_helpers.rb +185 -87
  104. data/lib/active_scaffold/helpers/human_condition_helpers.rb +2 -1
  105. data/lib/active_scaffold/helpers/id_helpers.rb +14 -8
  106. data/lib/active_scaffold/helpers/list_column_helpers.rb +65 -56
  107. data/lib/active_scaffold/helpers/pagination_helpers.rb +5 -1
  108. data/lib/active_scaffold/helpers/search_column_helpers.rb +21 -18
  109. data/lib/active_scaffold/helpers/view_helpers.rb +102 -64
  110. data/lib/active_scaffold/responds_to_parent.rb +39 -64
  111. data/lib/active_scaffold/tableless.rb +129 -10
  112. data/lib/active_scaffold/version.rb +2 -2
  113. data/test/bridges/bridge_test.rb +1 -1
  114. data/test/bridges/date_picker_test.rb +2 -2
  115. data/test/bridges/paperclip_test.rb +10 -8
  116. data/test/bridges/tiny_mce_test.rb +2 -2
  117. data/test/company.rb +22 -10
  118. data/test/config/base_test.rb +1 -1
  119. data/test/config/core_test.rb +8 -6
  120. data/test/config/create_test.rb +6 -6
  121. data/test/config/delete_test.rb +4 -4
  122. data/test/config/field_search_test.rb +6 -6
  123. data/test/config/list_test.rb +7 -7
  124. data/test/config/nested_test.rb +8 -7
  125. data/test/config/search_test.rb +7 -7
  126. data/test/config/show_test.rb +5 -5
  127. data/test/config/subform_test.rb +1 -1
  128. data/test/config/update_test.rb +5 -4
  129. data/test/data_structures/action_columns_test.rb +15 -16
  130. data/test/data_structures/action_link_test.rb +10 -10
  131. data/test/data_structures/action_links_test.rb +6 -6
  132. data/test/data_structures/actions_test.rb +4 -4
  133. data/test/data_structures/association_column_test.rb +4 -4
  134. data/test/data_structures/column_test.rb +9 -9
  135. data/test/data_structures/columns_test.rb +7 -7
  136. data/test/data_structures/error_message_test.rb +2 -4
  137. data/test/data_structures/set_test.rb +13 -13
  138. data/test/data_structures/sorting_test.rb +8 -8
  139. data/test/data_structures/standard_column_test.rb +2 -2
  140. data/test/data_structures/validation_reflection_test.rb +8 -8
  141. data/test/data_structures/virtual_column_test.rb +5 -5
  142. data/test/extensions/active_record_test.rb +1 -1
  143. data/test/helpers/form_column_helpers_test.rb +5 -5
  144. data/test/helpers/list_column_helpers_test.rb +2 -1
  145. data/test/helpers/pagination_helpers_test.rb +1 -1
  146. data/test/misc/active_record_permissions_test.rb +23 -4
  147. data/test/misc/attribute_params_test.rb +304 -136
  148. data/test/misc/calculation_test.rb +55 -0
  149. data/test/misc/configurable_test.rb +22 -21
  150. data/test/misc/constraints_test.rb +10 -7
  151. data/test/misc/convert_numbers_format_test.rb +149 -0
  152. data/test/misc/finder_test.rb +17 -13
  153. data/test/misc/lang_test.rb +1 -1
  154. data/test/misc/tableless_test.rb +18 -0
  155. data/test/mock_app/app/controllers/addresses_controller.rb +4 -0
  156. data/test/mock_app/app/controllers/buildings_controller.rb +4 -0
  157. data/test/mock_app/app/controllers/cars_controller.rb +4 -0
  158. data/test/mock_app/app/controllers/contacts_controller.rb +4 -0
  159. data/test/mock_app/app/controllers/floors_controller.rb +6 -0
  160. data/test/mock_app/app/controllers/people_controller.rb +4 -0
  161. data/test/mock_app/app/models/address.rb +3 -0
  162. data/test/mock_app/app/models/building.rb +8 -0
  163. data/test/mock_app/app/models/car.rb +3 -0
  164. data/test/mock_app/app/models/contact.rb +3 -0
  165. data/test/mock_app/app/models/file_model.rb +19 -0
  166. data/test/mock_app/app/models/floor.rb +8 -0
  167. data/test/mock_app/app/models/person.rb +11 -0
  168. data/test/mock_app/config/application.rb +2 -0
  169. data/test/mock_app/config/environments/test.rb +1 -1
  170. data/test/mock_app/config/initializers/secret_token.rb +5 -1
  171. data/test/mock_app/config/routes.rb +1 -1
  172. data/test/mock_app/db/schema.rb +51 -0
  173. data/test/model_stub.rb +3 -3
  174. data/test/test_helper.rb +15 -12
  175. metadata +51 -50
  176. data/lib/active_scaffold/extensions/array.rb +0 -7
  177. data/lib/active_scaffold/extensions/cache_association.rb +0 -16
  178. data/lib/active_scaffold/extensions/usa_state.rb +0 -46
  179. data/lib/active_scaffold_env.rb +0 -13
  180. data/test/extensions/array_test.rb +0 -12
  181. data/test/mock_app/public/blank.html +0 -33
  182. data/test/mock_app/public/images/active_scaffold/DO_NOT_EDIT +0 -2
  183. data/test/mock_app/public/images/active_scaffold/default/add.gif +0 -0
  184. data/test/mock_app/public/images/active_scaffold/default/arrow_down.gif +0 -0
  185. data/test/mock_app/public/images/active_scaffold/default/arrow_up.gif +0 -0
  186. data/test/mock_app/public/images/active_scaffold/default/close.gif +0 -0
  187. data/test/mock_app/public/images/active_scaffold/default/cross.png +0 -0
  188. data/test/mock_app/public/images/active_scaffold/default/indicator-small.gif +0 -0
  189. data/test/mock_app/public/images/active_scaffold/default/indicator.gif +0 -0
  190. data/test/mock_app/public/images/active_scaffold/default/magnifier.png +0 -0
  191. data/test/mock_app/public/javascripts/active_scaffold/DO_NOT_EDIT +0 -2
  192. data/test/mock_app/public/javascripts/active_scaffold/default/active_scaffold.js +0 -532
  193. data/test/mock_app/public/javascripts/active_scaffold/default/dhtml_history.js +0 -867
  194. data/test/mock_app/public/javascripts/active_scaffold/default/form_enhancements.js +0 -117
  195. data/test/mock_app/public/javascripts/active_scaffold/default/rico_corner.js +0 -370
  196. data/test/mock_app/public/stylesheets/active_scaffold/DO_NOT_EDIT +0 -2
  197. data/test/mock_app/public/stylesheets/active_scaffold/default/stylesheet-ie.css +0 -35
  198. data/test/mock_app/public/stylesheets/active_scaffold/default/stylesheet.css +0 -848
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 33153bffc906bb3250c092c0e566b40ad97e8069
4
- data.tar.gz: f281d1909186146d7d937fc1f8592c66f27bac8c
3
+ metadata.gz: f45af2d20c0a1737e0bd7a2c7d5d777013c3a77d
4
+ data.tar.gz: 6c171bde1438fecf021bafa5a2ff4b8151abd220
5
5
  SHA512:
6
- metadata.gz: 09f9192c00510733988bf1c61ed16d1da71b465cdba3256549a4f96bd2133dbac1ddbcfb23db93978ca7fa863712fe46619c3cb23ed7c55fd17326aa32fbaa40
7
- data.tar.gz: 4c558220d20826e976986d4b5cf9c51571179a74e27394c69aee41ae43088f3960386ce403757fed4305d69a4c6cabae81a511802be82175484111292c0c2003
6
+ metadata.gz: 003e6d3d878fec9b8de7921dd2d292056eb21af6a1cc599f02016709b12f2bc5de62f5e558efe942873fb5f6915c445c99c4256cbbfb9ec8896163fb267778ab
7
+ data.tar.gz: a2e1b1ed3360944f8eadc4d519c9a6cc1a92cf394b658d6990081d2a47c3ade4c623daee33f429c380308ad06a02f08c35caf7f81f11a3ae0cefb778e04e0777
data/CHANGELOG CHANGED
@@ -1,3 +1,42 @@
1
+ = 3.4.0 (not released yet)
2
+ - Support rails4
3
+ - Quote selected columns
4
+ - More unobtrusive html views
5
+ - Move () in visibility toggle links inside so they can be overrided
6
+ - More helpers to support overriding
7
+ - Extend datepicker to load settings from data attributes before onReady event is fired
8
+ - Add weight to action links
9
+ - Add placeholder in search form
10
+ - load existing record on render_field when id is present
11
+ - Add helper to override subform label
12
+ - embedded? checks that it is displayed embedded, add loading_embedded? to check first loading of embedded
13
+ - Fix previous page link with search and sort options when they are not stored in session
14
+ - Fix updating column in main form when subform has column with same name
15
+ - Fix sort_by :method without conditions
16
+ - Add conditional_get_support and calculate_etag options to send etag and check it with stale? rails method, avoiding rendering views and loading all page items when page is cached
17
+ - Remove row action (method exists but not as action), index with id is enough
18
+ - Use to_param in action links
19
+ - Allow to pass an array value in conditions_from_params, not only single value for columns
20
+ - Display count items when pagination is disabled
21
+ - Check security in column groups in forms
22
+ - Add refresh_link option to :select form_ui
23
+ - Sort association options in select :form_ui using column.sort_by :sql
24
+ - Support :radio form_ui in association columns
25
+ - Improve XML/JSON/YAML: return primary key, associations and virtual columns (a method must exist in model)
26
+ - Add support for :label_method option for association columns so another method can be used instead of to_label
27
+ - Support update_columns in plural associations
28
+ - Support nil conditions in conditions_from_params: when column param is empty and is not a text column, nil condition will be used
29
+ - Support autopagination, first page is loaded in first request, then all pages are loaded and displayed by ajax automatically
30
+ - Support toggle collection action links, for links with reload list to filter, so active link is marked
31
+ - Support search and field_search at same time
32
+ - Support for overriding how download url is get for dragonfly attachment
33
+ - Trigger as:element_removed when ActiveScaffold.remove is called
34
+ - use preload instead of includes to preload associations without left join when not used for searching or sorting
35
+ - Allows for contents such as "<i class='fa fa-filter'></i> Filters <i class='fa fa-caret-down'></i>" to be placed in the locale yml.
36
+ - Add form_ui to html classes of li in forms
37
+ - Allow to set different :controller for record_select_autocomplete (when no association in column using record_select)
38
+ - Add :optional to create.persistent
39
+
1
40
  = 3.3.3
2
41
  - Allow to override select options in active_scaffold_search_select
3
42
  - Load effects from jQuery UI when using jquery-rails 3 gem
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  Overview
2
2
  ========
3
- ActiveScaffold provides a quick and powerful user interfaces for CRUD (create, read, update, delete) operations for Rails applications. It offers additonal features including searching, pagination & layout control.
3
+ [![travis tests](https://travis-ci.org/activescaffold/active_scaffold.png)](https://travis-ci.org/activescaffold/active_scaffold)
4
+
5
+ ActiveScaffold provides a quick and powerful user interfaces for CRUD (create, read, update, delete) operations for Rails applications. It offers additonal features including searching, pagination & layout control. Rails 3.2 and 4.x are supported. For rails 4 is recommended >= 4.0.5.
4
6
 
5
7
  Branch Details
6
8
  --------------
@@ -29,13 +31,13 @@ Add the following line to /app/assets/stylesheets/application.css
29
31
 
30
32
  *= require active_scaffold
31
33
 
32
- Run the app and visit localhost:3000/teams
34
+ Run the app and visit localhost:3000/users
33
35
 
34
36
  Configuration
35
37
  -------------
36
38
  See Wiki for instructions on customising ActiveScaffold and to find the full API details.
37
39
 
38
- Compatability Issues
40
+ Compatibility Issues
39
41
  --------------------
40
42
  jQuery 1.9 deprecates some methods that rails-3.2 branch still uses (NB: jQuery 1.9 is supported in 3.3.x, the master branch). You'll therefore need to ensure you use jQuery 1.8. You can do this by fixing version in your Gemfile:
41
43
 
@@ -1,4 +1,34 @@
1
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
+ */
2
32
  if (/1\.[2-7]\..*/.test(jQuery().jquery)) {
3
33
  var error = 'ActiveScaffold requires jquery 1.8.0 or greater, please use jquery-rails 2.1.x gem or greater';
4
34
  if (typeof console != 'undefined') console.error(error);
@@ -6,13 +36,9 @@ jQuery(document).ready(function($) {
6
36
  }
7
37
 
8
38
  jQuery(document).on('focus', ':input', function() { ActiveScaffold.last_focus = this; });
39
+ jQuery(document).on('blur', ':input', function(e) { ActiveScaffold.last_focus = e.relatedTarget; });
9
40
  jQuery(document).click(function(event) {
10
- jQuery('.action_group.dyn ul').remove();
11
- });
12
- jQuery(document).on('ajax:complete', '.action_group.dyn ul a', function(event) {
13
- var action_link = ActiveScaffold.find_action_link(event.target);
14
- if (action_link.loading_indicator) action_link.loading_indicator.css('visibility','hidden');
15
- jQuery(event.target).closest('.action_group.dyn ul').remove();
41
+ jQuery('.action_group.dyn ul').hide(); // only hide so action links loading still work
16
42
  });
17
43
  jQuery(document).on('ajax:beforeSend', 'form.as_form', function(event) {
18
44
  var as_form = jQuery(this).closest("form");
@@ -28,6 +54,9 @@ jQuery(document).ready(function($) {
28
54
  ActiveScaffold.enable_form(as_form);
29
55
  }
30
56
  });
57
+ jQuery(document).on('ajax:complete', 'form.live', function(event) {
58
+ ActiveScaffold.focus_first_element_of_form(jQuery(this).closest("form"));
59
+ });
31
60
  jQuery(document).on('ajax:error', 'form.as_form', function(event, xhr, status, error) {
32
61
  var as_div = jQuery(this).closest("div.active-scaffold");
33
62
  if (as_div.length) {
@@ -60,15 +89,13 @@ jQuery(document).ready(function($) {
60
89
  action_link.insert(response);
61
90
  if (action_link.hide_target) action_link.target.hide();
62
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
+ }
63
96
  action_link.enable();
64
97
  }
65
98
  jQuery(this).trigger('as:action_success', action_link);
66
- }
67
- return true;
68
- });
69
- jQuery(document).on('ajax:complete', 'a.as_action', function(event) {
70
- var action_link = ActiveScaffold.ActionLink.get(jQuery(this));
71
- if (action_link) {
72
99
  if (action_link.loading_indicator) action_link.loading_indicator.css('visibility','hidden');
73
100
  }
74
101
  return true;
@@ -95,16 +122,12 @@ jQuery(document).ready(function($) {
95
122
  }
96
123
  return true;
97
124
  });
98
- jQuery(document).on('ajax:success', 'a.as_cancel', function(event, response) {
99
- var action_link = ActiveScaffold.find_action_link(jQuery(this));
125
+ jQuery(document).on('ajax:success', 'a.as_cancel', function(event) {
126
+ var link = jQuery(this), action_link = ActiveScaffold.find_action_link(link);
100
127
 
101
- if (action_link) {
102
- if (action_link.position) {
103
- action_link.close();
104
- } else {
105
- response.evalResponse();
106
- }
107
- }
128
+ if (action_link && action_link.position) {
129
+ action_link.close();
130
+ } else if (link.hasClass('reset')) link.closest('form').get(0).reset();
108
131
  return true;
109
132
  });
110
133
  jQuery(document).on('ajax:error', 'a.as_cancel', function(event, xhr, status, error) {
@@ -124,6 +147,7 @@ jQuery(document).ready(function($) {
124
147
  jQuery(document).on('ajax:error', 'a.as_sort', function(event, xhr, status, error) {
125
148
  var as_scaffold = jQuery(this).closest('.active-scaffold');
126
149
  ActiveScaffold.report_500_response(as_scaffold, xhr);
150
+ jQuery(this).closest('th').removeClass('loading');
127
151
  return true;
128
152
  });
129
153
  jQuery(document).on('mouseenter mouseleave', 'td.in_place_editor_field', function(event) {
@@ -169,12 +193,37 @@ jQuery(document).ready(function($) {
169
193
  return true;
170
194
  } else return false;
171
195
  });
172
- jQuery(document).on('change', 'input.update_form:not(.recordselect), textarea.update_form, select.update_form', function(event) {
196
+ jQuery(document).on('ajax:complete', '.action_group.dyn ul a', function(event) {
197
+ var action_link = ActiveScaffold.find_action_link(event.target);
198
+ if (action_link.loading_indicator) action_link.loading_indicator.css('visibility','hidden');
199
+ jQuery(event.target).closest('.action_group.dyn ul').remove();
200
+ });
201
+
202
+ jQuery(document).on('change', 'input.update_form:not(.recordselect), textarea.update_form, select.update_form, .checkbox-list.update_form input:checkbox', function(event) {
173
203
  var element = jQuery(this);
174
- var value = element.is("input:checkbox:not(:checked)") ? null : element.val();
175
- ActiveScaffold.update_column(element, element.data('update_url'), element.data('update_send_form'), element.attr('id'), value);
204
+ var form_element = element.closest('.checkbox-list');
205
+ var value, additional_params;
206
+ if (form_element.is(".checkbox-list")) {
207
+ value = form_element.find(':checked').map(function(item){return $(this).val();}).toArray();
208
+ additional_params = (element.is(':checked') ? '_added=' : '_removed=') + element.val();
209
+ } else {
210
+ value = element.is("input:checkbox:not(:checked)") ? null : element.val();
211
+ form_element = element;
212
+ }
213
+ ActiveScaffold.update_column(form_element, form_element.data('update_url'), form_element.data('update_send_form'), element.attr('id'), value, additional_params);
176
214
  return true;
177
215
  });
216
+ jQuery(document).on('click', 'a.refresh-link', function(event) {
217
+ event.preventDefault();
218
+ var element = jQuery(this);
219
+ var form_element = element.prev();
220
+ var value;
221
+ if (form_element.is(".checkbox-list")) {
222
+ value = form_element.find(':checked').map(function(item){return $(this).val();}).toArray();
223
+ form_element = form_element.parent().find("input:checkbox"); // parent is needed for draggable-list, checked list may be empty
224
+ } else value = form_element.is("input:checkbox:not(:checked)") ? null : form_element.val();
225
+ ActiveScaffold.update_column(form_element, element.attr('href'), element.data('update_send_form'), form_element.attr('id'), value);
226
+ });
178
227
  jQuery(document).on('recordselect:change', 'input.recordselect.update_form', function(event, id, label) {
179
228
  var element = jQuery(this);
180
229
  ActiveScaffold.update_column(element, element.data('update_url'), element.data('update_send_form'), element.attr('id'), id);
@@ -219,7 +268,7 @@ jQuery(document).ready(function($) {
219
268
  });
220
269
  jQuery(document).on('click', '.hover_click a.as_action', function(event) {
221
270
  var element = jQuery(this).closest('.hover_click');
222
- if (element) {
271
+ if (element.length) {
223
272
  element.find('ul').hide();
224
273
  }
225
274
  return true;
@@ -230,8 +279,21 @@ jQuery(document).ready(function($) {
230
279
  e.preventDefault();
231
280
  });
232
281
 
282
+ ActiveScaffold.live_search(document);
283
+ ActiveScaffold.auto_paginate(document);
284
+ ActiveScaffold.draggable_lists('.draggable-lists');
285
+ jQuery(document).on('as:element_updated', function(e) {
286
+ ActiveScaffold.live_search(e.target);
287
+ ActiveScaffold.draggable_lists('.draggable-lists', e.target);
288
+ });
289
+ jQuery(document).on('as:action_success', 'a.as_action', function(e, action_link) {
290
+ ActiveScaffold.live_search(action_link.adapter);
291
+ ActiveScaffold.auto_paginate(action_link.adapter);
292
+ ActiveScaffold.draggable_lists('.draggable-lists', action_link.adapter);
293
+ });
233
294
  });
234
295
 
296
+
235
297
  /* Simple Inheritance
236
298
  http://ejohn.org/blog/simple-javascript-inheritance/
237
299
  */
@@ -304,51 +366,28 @@ jQuery(document).ready(function($) {
304
366
  Slight modifications by Elliot Winkler
305
367
  */
306
368
 
307
- if (typeof(jQuery.fn.delayedObserver) === 'undefined') {
308
- (function($) {
309
- var delayedObserverStack = [];
310
- var observed;
311
-
312
- function delayedObserverCallback(stackPos) {
313
- observed = delayedObserverStack[stackPos];
314
- if (observed.timer) return;
315
-
316
- observed.timer = setTimeout(function(){
317
- observed.timer = null;
318
- observed.callback(observed.obj.val(), observed.obj);
319
- }, observed.delay * 1000);
320
-
321
- observed.oldVal = observed.obj.val();
322
- }
323
-
324
- // going by
325
- // <http://www.cambiaresearch.com/c4/702b8cd1-e5b0-42e6-83ac-25f0306e3e25/Javascript-Char-Codes-Key-Codes.aspx>
326
- // I think these codes only work when using keyup or keydown
327
- function isNonPrintableKey(event) {
328
- var code = event.keyCode;
329
- return (
330
- event.metaKey ||
331
- (code >= 9 && code <= 16) || (code >= 27 && code <= 40) || (code >= 91 && code <= 93) || (code >= 112 && code <= 145)
332
- );
333
- }
334
-
335
- jQuery.fn.extend({
336
- delayedObserver:function(delay, callback){
337
- $this = jQuery(this);
338
-
339
- delayedObserverStack.push({
340
- obj: $this, timer: null, delay: delay,
341
- oldVal: $this.val(), callback: callback
342
- });
343
-
344
- stackPos = delayedObserverStack.length-1;
345
-
346
- $this.keyup(function(event) {
347
- if (isNonPrintableKey(event)) return;
348
- observed = delayedObserverStack[stackPos];
349
- if (observed.obj.val() == observed.obj.oldVal) return;
350
- else delayedObserverCallback(stackPos);
351
- });
369
+ if (typeof(jQuery.fn.delayedObserver) === 'undefined') {
370
+ (function($){
371
+ $.extend($.fn, {
372
+ delayedObserver: function(callback, delay, options){
373
+ return this.each(function(){
374
+ var el = $(this);
375
+ var op = options || {};
376
+ el.data('oldval', el.val())
377
+ .data('delay', delay || 0.5)
378
+ .data('condition', op.condition || function() { return ($(this).data('oldval') == $(this).val()); })
379
+ .data('callback', callback)
380
+ [(op.event||'keyup')](function(){
381
+ if (el.data('condition').apply(el)) { return; }
382
+ else {
383
+ if (el.data('timer')) { clearTimeout(el.data('timer')); }
384
+ el.data('timer', setTimeout(function(){
385
+ el.data('callback').apply(el);
386
+ }, el.data('delay') * 1000));
387
+ el.data('oldval', el.val());
388
+ }
389
+ });
390
+ });
352
391
  }
353
392
  });
354
393
  })(jQuery);
@@ -361,6 +400,22 @@ if (typeof(jQuery.fn.delayedObserver) === 'undefined') {
361
400
 
362
401
  var ActiveScaffold = {
363
402
  last_focus: null,
403
+ live_search: function(element) {
404
+ jQuery('form.search.live input[type=search]', element).delayedObserver(function() {
405
+ jQuery(this).parent().trigger("submit");
406
+ }, 0.5);
407
+ },
408
+ auto_paginate: function(element) {
409
+ var paginate_link = jQuery('.active-scaffold-pagination.auto-paginate a:first', element);
410
+ if (paginate_link.length) {
411
+ jQuery('.active-scaffold-pagination.auto-paginate', element).hide();
412
+ ActiveScaffold.auto_load_page(paginate_link.attr('href'), {auto_pagination: true});
413
+ }
414
+ },
415
+ auto_load_page: function(href, params) {
416
+ jQuery.get(href, params, null, 'script');
417
+ },
418
+
364
419
  records_for: function(tbody_id) {
365
420
  if (typeof(tbody_id) == 'string') tbody_id = '#' + tbody_id;
366
421
  return jQuery(tbody_id).children('.record');
@@ -431,8 +486,10 @@ var ActiveScaffold = {
431
486
  if (row.hasClass('even-record')) even_row = true;
432
487
 
433
488
  replaced = this.replace(row, html);
434
- if (even_row === true) replaced.addClass('even-record');
435
- ActiveScaffold.highlight(replaced);
489
+ if (replaced) {
490
+ if (even_row === true) replaced.addClass('even-record');
491
+ ActiveScaffold.highlight(replaced);
492
+ }
436
493
  },
437
494
 
438
495
  replace: function(element, html) {
@@ -440,22 +497,34 @@ var ActiveScaffold = {
440
497
  element = jQuery(element);
441
498
  var new_element = typeof(html) == 'string' ? jQuery.parseHTML(html.trim(), true) : html;
442
499
  new_element = jQuery(new_element);
443
- element.replaceWith(new_element);
444
- new_element.trigger('as:element_updated');
445
- return new_element;
500
+ if (element.length) {
501
+ element.replaceWith(new_element);
502
+ new_element.trigger('as:element_updated');
503
+ return new_element;
504
+ } else return null;
446
505
  },
447
506
 
448
507
  replace_html: function(element, html) {
449
508
  if (typeof(element) == 'string') element = '#' + element;
450
509
  element = jQuery(element);
451
- element.html(html);
510
+ if (element.length) {
511
+ element.html(html);
512
+ element.trigger('as:element_updated');
513
+ }
514
+ return element;
515
+ },
516
+
517
+ append: function(element, html) {
518
+ if (typeof(element) == 'string') element = '#' + element;
519
+ element = jQuery(element);
520
+ element.append(html);
452
521
  element.trigger('as:element_updated');
453
522
  return element;
454
523
  },
455
524
 
456
525
  remove: function(element, callback) {
457
526
  if (typeof(element) == 'string') element = '#' + element;
458
- jQuery(element).remove();
527
+ jQuery(element).trigger('as:element_removed').remove();
459
528
  if (callback) callback();
460
529
  },
461
530
 
@@ -486,6 +555,9 @@ var ActiveScaffold = {
486
555
  var loading_indicator = jQuery('#' + as_form.attr('id').replace(/-form$/, '-loading-indicator'));
487
556
  if (!skip_loading_indicator && loading_indicator) loading_indicator.css('visibility','visible');
488
557
  jQuery('input[type=submit]', as_form).attr('disabled', 'disabled');
558
+ jQuery('.sub-form a.destroy', as_form).addClass('disabled');
559
+ if (jQuery.fn.draggable) jQuery('.draggable-item', as_form).draggable('disable');
560
+ if (jQuery.fn.droppable) jQuery('.draggable-list', as_form).droppable('disable');
489
561
  // data-remote-disabled attr instead of set data because is used to in selector later
490
562
  jQuery("input:enabled,select:enabled,textarea:enabled", as_form).attr('disabled', 'disabled').attr('data-remove-disabled', true);
491
563
  },
@@ -496,12 +568,16 @@ var ActiveScaffold = {
496
568
  var loading_indicator = jQuery('#' + as_form.attr('id').replace(/-form$/, '-loading-indicator'));
497
569
  if (!skip_loading_indicator && loading_indicator) loading_indicator.css('visibility','hidden');
498
570
  jQuery('input[type=submit]', as_form).removeAttr('disabled');
571
+ jQuery('.sub-form a.destroy.disabled', as_form).removeClass('disabled');
572
+ if (jQuery.fn.draggable) jQuery('.draggable-item', as_form).draggable('enable');
573
+ if (jQuery.fn.droppable) jQuery('.draggable-list', as_form).droppable('enable');
499
574
  jQuery("input[data-remove-disabled],select[data-remove-disabled],textarea[data-remove-disabled]", as_form).removeAttr('disabled data-remove-disabled');
500
575
  },
501
576
 
502
577
  focus_first_element_of_form: function(form_element) {
503
578
  if (typeof(form_element) == 'string') form_element = '#' + form_element;
504
- jQuery(form_element + ":first *:input[type!=hidden]:first").focus();
579
+ var form_selector = jQuery(form_element).is('form') ? '' : 'form ';
580
+ jQuery(form_selector + ":input[type!=hidden]:first", jQuery(form_element)).focus();
505
581
  },
506
582
 
507
583
  create_record_row: function(active_scaffold_id, html, options) {
@@ -539,7 +615,7 @@ var ActiveScaffold = {
539
615
  this.highlight(new_row);
540
616
  },
541
617
 
542
- create_record_row_from_url: function(active_scaffold_id, url, options) {
618
+ create_record_row_from_url: function(action_link, url, options) {
543
619
  jQuery.get(url, function(row) {
544
620
  ActiveScaffold.create_record_row(action_link.scaffold(), row, options);
545
621
  action_link.close();
@@ -569,13 +645,14 @@ var ActiveScaffold = {
569
645
  this.remove(record);
570
646
  },
571
647
 
572
- report_500_response: function(active_scaffold_id) {
648
+ report_500_response: function(active_scaffold_id, xhr) {
573
649
  var server_error = jQuery(active_scaffold_id).find('td.messages-container p.server-error').first();
574
650
  if (server_error.is(':visible')) {
575
651
  ActiveScaffold.highlight(server_error);
576
652
  } else {
577
653
  server_error.show();
578
654
  }
655
+ if (xhr) server_error.find('.error-500')[xhr.status < 500 ? 'hide' : 'show']();
579
656
  ActiveScaffold.scroll_to(server_error, ActiveScaffold.config.scroll_on_close == 'checkInViewport');
580
657
  },
581
658
 
@@ -588,7 +665,11 @@ var ActiveScaffold = {
588
665
  display_dynamic_action_group: function(link, html) {
589
666
  if (typeof(link) == 'string') link = jQuery('#' + link);
590
667
  link.next('ul').remove();
591
- link.closest('td').addClass('action_group dyn');
668
+ if (link.closest('td.actions').length) link.closest('td').addClass('action_group dyn');
669
+ else {
670
+ if (link.parent('div.actions').length) link.wrap($('<div>'));
671
+ link.parent().addClass('action_group dyn');
672
+ }
592
673
  link.after(html);
593
674
  },
594
675
 
@@ -657,7 +738,7 @@ var ActiveScaffold = {
657
738
  var toggler = toggable.prev();
658
739
  var initial_label = (options.default_visible === true) ? options.hide_label : options.show_label;
659
740
 
660
- toggler.append(' (<a class="visibility-toggle" href="#">' + initial_label + '</a>)');
741
+ toggler.append(' <a class="visibility-toggle" href="#">' + initial_label + '</a>');
661
742
  toggler.children('a').click(function(e) {
662
743
  e.preventDefault();
663
744
  toggable.toggle();
@@ -691,13 +772,16 @@ var ActiveScaffold = {
691
772
  render_form_field: function(source, content, options) {
692
773
  if (typeof(source) == 'string') source = '#' + source;
693
774
  var source = jQuery(source);
694
- var element = source.closest('.sub-form-record');
775
+ var element = source.closest('.sub-form-record'), selector = '';
695
776
  if (element.length == 0) {
696
777
  element = source.closest('form > ol.form');
778
+ selector = 'li';
697
779
  }
698
- element = element.find('.' + options.field_class).first();
780
+ // find without entering new subforms
781
+ selector = options.is_subform ? '' : selector + ':not(.sub-form) ';
782
+ element = element.find(selector + '.' + options.field_class).first();
699
783
 
700
- if (element) {
784
+ if (element.length) {
701
785
  if (options.is_subform == false) {
702
786
  this.replace(element.closest('dl'), content);
703
787
  } else {
@@ -708,7 +792,7 @@ var ActiveScaffold = {
708
792
 
709
793
  record_select_onselect: function(edit_associated_url, active_scaffold_id, id){
710
794
  jQuery.ajax({
711
- url: edit_associated_url.split('--ID--').join(id),
795
+ url: edit_associated_url.replace('--ID--', id),
712
796
  error: function(xhr, textStatus, errorThrown){
713
797
  ActiveScaffold.report_500_response(active_scaffold_id, xhr)
714
798
  }
@@ -825,7 +909,7 @@ var ActiveScaffold = {
825
909
  }
826
910
  },
827
911
 
828
- update_column: function(element, url, send_form, source_id, val) {
912
+ update_column: function(element, url, send_form, source_id, val, additional_params) {
829
913
  if (!element) element = jQuery('#' + source_id);
830
914
  var as_form = element.closest('form.as_form');
831
915
  var params = null;
@@ -838,6 +922,7 @@ var ActiveScaffold = {
838
922
  else if (send_form != as_form) params = base.find(':input').serialize();
839
923
  else base.serialize();
840
924
  params += '&_method=&' + jQuery.param({"source_id": source_id});
925
+ if (additional_params) params += '&' + additional_params;
841
926
  } else {
842
927
  params = {value: val};
843
928
  params.source_id = source_id;
@@ -865,8 +950,12 @@ var ActiveScaffold = {
865
950
  });
866
951
  },
867
952
 
868
- draggable_lists: function(element) {
869
- jQuery('ul#' + element).draggable_lists();
953
+ draggable_lists: function(id_or_elements) {
954
+ var elements;
955
+ if (!jQuery.fn.draggableLists) return;
956
+ if (typeof(id_or_elements) == 'string') elements = jQuery('ul' + id_or_elements);
957
+ else elements = jQuery(elements);
958
+ elements.draggableLists();
870
959
  }
871
960
  }
872
961
 
@@ -1045,7 +1134,7 @@ ActiveScaffold.Actions.Record = ActiveScaffold.Actions.Abstract.extend({
1045
1134
  instantiate_link: function(link) {
1046
1135
  var l = new ActiveScaffold.ActionLink.Record(link, this.target, this.loading_indicator);
1047
1136
  var refresh = this.target.data('refresh');
1048
- if (refresh) l.refresh_url = refresh;
1137
+ if (refresh) l.refresh_url = this.target.closest('.records').data('refresh-record').replace('--ID--', refresh);
1049
1138
 
1050
1139
  if (l.position) {
1051
1140
  l.url = l.url.append_params({adapter: '_list_inline_adapter'});
@@ -1090,6 +1179,7 @@ ActiveScaffold.ActionLink.Record = ActiveScaffold.ActionLink.Abstract.extend({
1090
1179
  else {
1091
1180
  return false;
1092
1181
  }
1182
+ ActiveScaffold.focus_first_element_of_form(this.adapter);
1093
1183
  ActiveScaffold.highlight(this.adapter.find('td'));
1094
1184
  },
1095
1185
 
@@ -1157,6 +1247,7 @@ ActiveScaffold.ActionLink.Table = ActiveScaffold.ActionLink.Abstract.extend({
1157
1247
  else {
1158
1248
  throw 'Unknown position "' + this.position + '"'
1159
1249
  }
1250
+ ActiveScaffold.focus_first_element_of_form(this.adapter);
1160
1251
  ActiveScaffold.highlight(this.adapter.find('td').first().children());
1161
- },
1252
+ }
1162
1253
  });