active_scaffold 3.3.3 → 3.4.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 (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
  });