active_scaffold 3.6.20 → 3.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (135) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.rdoc +47 -0
  3. data/README.md +29 -16
  4. data/app/assets/javascripts/jquery/active_scaffold.js +106 -68
  5. data/app/assets/javascripts/jquery/active_scaffold_chosen.js +6 -5
  6. data/app/assets/javascripts/jquery/tiny_mce_bridge.js +18 -4
  7. data/app/assets/stylesheets/active_scaffold_layout.css +13 -2
  8. data/app/views/active_scaffold_overrides/_base_form.html.erb +5 -1
  9. data/app/views/active_scaffold_overrides/_field_search.html.erb +1 -0
  10. data/app/views/active_scaffold_overrides/_form_association_record.html.erb +2 -1
  11. data/app/views/active_scaffold_overrides/_render_field.js.erb +24 -13
  12. data/config/locales/de.yml +6 -3
  13. data/config/locales/en.yml +3 -0
  14. data/config/locales/es.yml +3 -0
  15. data/config/locales/fr.yml +9 -6
  16. data/config/locales/hu.yml +20 -17
  17. data/config/locales/ja.yml +83 -80
  18. data/config/locales/ru.yml +17 -14
  19. data/lib/active_scaffold/actions/common_search.rb +2 -2
  20. data/lib/active_scaffold/actions/core.rb +30 -10
  21. data/lib/active_scaffold/actions/field_search.rb +9 -6
  22. data/lib/active_scaffold/actions/nested.rb +7 -7
  23. data/lib/active_scaffold/actions/update.rb +3 -3
  24. data/lib/active_scaffold/attribute_params.rb +22 -70
  25. data/lib/active_scaffold/bridges/active_storage/active_storage_helpers.rb +0 -3
  26. data/lib/active_scaffold/bridges/active_storage/form_ui.rb +6 -6
  27. data/lib/active_scaffold/bridges/active_storage/list_ui.rb +7 -7
  28. data/lib/active_scaffold/bridges/active_storage.rb +3 -0
  29. data/lib/active_scaffold/bridges/ancestry/ancestry_bridge.rb +2 -2
  30. data/lib/active_scaffold/bridges/bitfields/bitfields_bridge.rb +2 -2
  31. data/lib/active_scaffold/bridges/calendar_date_select/as_cds_bridge.rb +12 -14
  32. data/lib/active_scaffold/bridges/carrierwave/form_ui.rb +2 -2
  33. data/lib/active_scaffold/bridges/carrierwave/list_ui.rb +1 -1
  34. data/lib/active_scaffold/bridges/chosen/helpers.rb +10 -10
  35. data/lib/active_scaffold/bridges/country_select/country_select_bridge_helper.rb +7 -7
  36. data/lib/active_scaffold/bridges/date_picker/ext.rb +20 -9
  37. data/lib/active_scaffold/bridges/date_picker/helper.rb +9 -9
  38. data/lib/active_scaffold/bridges/date_picker.rb +2 -0
  39. data/lib/active_scaffold/bridges/dragonfly/form_ui.rb +3 -3
  40. data/lib/active_scaffold/bridges/dragonfly/list_ui.rb +5 -5
  41. data/lib/active_scaffold/bridges/file_column/form_ui.rb +1 -1
  42. data/lib/active_scaffold/bridges/file_column/list_ui.rb +3 -3
  43. data/lib/active_scaffold/bridges/file_column/test/functional/file_column_keep_test.rb +1 -1
  44. data/lib/active_scaffold/bridges/paper_trail/actions.rb +4 -1
  45. data/lib/active_scaffold/bridges/paperclip/form_ui.rb +3 -3
  46. data/lib/active_scaffold/bridges/paperclip/list_ui.rb +1 -1
  47. data/lib/active_scaffold/bridges/record_select/helpers.rb +17 -17
  48. data/lib/active_scaffold/bridges/tiny_mce/helpers.rb +6 -6
  49. data/lib/active_scaffold/bridges/tiny_mce.rb +1 -1
  50. data/lib/active_scaffold/bridges/usa_state_select/usa_state_select_helper.rb +6 -11
  51. data/lib/active_scaffold/bridges.rb +0 -3
  52. data/lib/active_scaffold/config/core.rb +1 -1
  53. data/lib/active_scaffold/config/field_search.rb +9 -1
  54. data/lib/active_scaffold/config/form.rb +9 -1
  55. data/lib/active_scaffold/constraints.rb +22 -7
  56. data/lib/active_scaffold/core.rb +6 -10
  57. data/lib/active_scaffold/data_structures/action_columns.rb +0 -25
  58. data/lib/active_scaffold/data_structures/action_links.rb +1 -1
  59. data/lib/active_scaffold/data_structures/association/abstract.rb +8 -0
  60. data/lib/active_scaffold/data_structures/association/active_mongoid.rb +8 -0
  61. data/lib/active_scaffold/data_structures/association/active_record.rb +1 -13
  62. data/lib/active_scaffold/data_structures/association/mongoid.rb +21 -8
  63. data/lib/active_scaffold/data_structures/column.rb +139 -28
  64. data/lib/active_scaffold/data_structures/columns.rb +12 -12
  65. data/lib/active_scaffold/data_structures/nested_info.rb +12 -0
  66. data/lib/active_scaffold/data_structures/sorting.rb +1 -1
  67. data/lib/active_scaffold/engine.rb +15 -1
  68. data/lib/active_scaffold/extensions/action_view_rendering.rb +13 -5
  69. data/lib/active_scaffold/extensions/cow_proxy.rb +1 -1
  70. data/lib/active_scaffold/extensions/routing_mapper.rb +1 -0
  71. data/lib/active_scaffold/extensions/unsaved_record.rb +9 -3
  72. data/lib/active_scaffold/finder.rb +147 -28
  73. data/lib/active_scaffold/helpers/action_link_helpers.rb +1 -1
  74. data/lib/active_scaffold/helpers/controller_helpers.rb +9 -4
  75. data/lib/active_scaffold/helpers/form_column_helpers.rb +153 -107
  76. data/lib/active_scaffold/helpers/human_condition_helpers.rb +48 -14
  77. data/lib/active_scaffold/helpers/list_column_helpers.rb +37 -20
  78. data/lib/active_scaffold/helpers/search_column_helpers.rb +137 -55
  79. data/lib/active_scaffold/helpers/show_column_helpers.rb +6 -6
  80. data/lib/active_scaffold/helpers/view_helpers.rb +1 -1
  81. data/lib/active_scaffold/orm_checks.rb +21 -1
  82. data/lib/active_scaffold/registry.rb +10 -15
  83. data/lib/active_scaffold/tableless.rb +10 -79
  84. data/lib/active_scaffold/version.rb +2 -2
  85. data/lib/active_scaffold.rb +3 -9
  86. data/lib/generators/active_scaffold/install_generator.rb +2 -2
  87. data/test/bridges/bridge_test.rb +1 -1
  88. data/test/bridges/date_picker_test.rb +3 -2
  89. data/test/bridges/paperclip_test.rb +18 -14
  90. data/test/bridges/tiny_mce_test.rb +5 -3
  91. data/test/config/base_test.rb +1 -1
  92. data/test/config/core_test.rb +1 -1
  93. data/test/config/create_test.rb +1 -1
  94. data/test/config/delete_test.rb +1 -1
  95. data/test/config/field_search_test.rb +1 -1
  96. data/test/config/list_test.rb +1 -1
  97. data/test/config/nested_test.rb +1 -1
  98. data/test/config/search_test.rb +1 -1
  99. data/test/config/show_test.rb +1 -1
  100. data/test/config/subform_test.rb +1 -1
  101. data/test/config/update_test.rb +1 -1
  102. data/test/data_structures/action_columns_test.rb +1 -1
  103. data/test/data_structures/action_link_test.rb +1 -1
  104. data/test/data_structures/action_links_test.rb +1 -1
  105. data/test/data_structures/actions_test.rb +1 -1
  106. data/test/data_structures/association_column_test.rb +1 -1
  107. data/test/data_structures/column_test.rb +1 -1
  108. data/test/data_structures/columns_test.rb +1 -1
  109. data/test/data_structures/set_test.rb +1 -1
  110. data/test/data_structures/sorting_test.rb +1 -1
  111. data/test/data_structures/standard_column_test.rb +1 -1
  112. data/test/data_structures/validation_reflection_test.rb +1 -1
  113. data/test/data_structures/virtual_column_test.rb +1 -1
  114. data/test/extensions/active_record_test.rb +1 -1
  115. data/test/helpers/form_column_helpers_test.rb +7 -5
  116. data/test/helpers/pagination_helpers_test.rb +1 -1
  117. data/test/helpers/search_column_helpers_test.rb +2 -1
  118. data/test/misc/active_record_permissions_test.rb +1 -1
  119. data/test/misc/attribute_params_test.rb +1 -1
  120. data/test/misc/calculation_test.rb +1 -1
  121. data/test/misc/configurable_test.rb +1 -1
  122. data/test/misc/constraints_test.rb +2 -1
  123. data/test/misc/convert_numbers_format_test.rb +1 -1
  124. data/test/misc/finder_test.rb +39 -1
  125. data/test/misc/lang_test.rb +1 -1
  126. data/test/misc/parse_datetime_test.rb +1 -1
  127. data/test/misc/tableless_test.rb +1 -1
  128. data/test/test_helper.rb +4 -4
  129. metadata +5 -17
  130. data/config/brakeman.ignore +0 -26
  131. data/config/brakeman.yml +0 -3
  132. data/config/i18n-tasks.yml +0 -121
  133. data/lib/active_scaffold/bridges/shared/date_bridge.rb +0 -221
  134. data/lib/active_scaffold/delayed_setup.rb +0 -41
  135. data/lib/active_scaffold/extensions/left_outer_joins.rb +0 -43
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5a6a07cc017cbfdb8a278a7297ac61d6e6d4f3802240a157a366b2829cf3661e
4
- data.tar.gz: 00d4f1bcbacca4e2a04f87db162be697ebd82f73aae9b23dbd1ffd3e43614610
3
+ metadata.gz: d7debc9ce2befd3f2d71287600caa1d45a0667064315e6666564feaf4cc7dd9e
4
+ data.tar.gz: 47315a56e65cad1164aba74b672aaeba53d404c2e82106a7765f51fd2f059d34
5
5
  SHA512:
6
- metadata.gz: 78f5e7472c1cbb36fd40c6f0a3b06f797e87e2969127d5506eee6f7b25d1f2b794c35684f477b1204e08d9c2c696b78c3c849b481d3b43c169ecf16b7f99c0f6
7
- data.tar.gz: 98f6fed6e5ac8512b74e27155285c0b81f0cd422e0cfbab3f0a01ba5e4a9e92a32cb8f4a199ef8118e71aceb188f9137e5d8bed48bc9ee0903ad420b92e771b5
6
+ metadata.gz: fbf8863ff656077485d071eebef80706b91d34c474f9f08f4edd1a1e98448eeb24b5ef4df36e8c06e5edb72da60b1ccf9e32e3e73972dcc6466d3fe653bea22c
7
+ data.tar.gz: 1cd3b5d872b7f62be2a7eebfbb8b974ac8fa4cd2ff30ced0cbb37352f6e6a4990f6a616a527d4b41b1af47f8851ce959d81259796ceed061c994eeb20218b93c
data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,50 @@
1
+ - Nullable boolean columns default to use :boolean form_ui instead of :checkbox
2
+ - Display the value set in options[:include_blank] for boolean columns when value is nil, to match the label in the form
3
+ - Support :select_multiple in search_ui, and :draggable in form_ui and search_ui, as shorthands
4
+ - Support assigning options next to the UI type in form_ui, list_ui, show_ui, search_ui, so they are used instead of common options
5
+ - Support :refresh_link option in :select form_ui for non-association columns
6
+ - Support using a hash in :refresh_link option instead of true, with html
7
+ - Support select with multiple attribute for plural associations using :select form_ui, instead of checkboxes, using {html_options: {multiple: true}}, or :select_multiple
8
+ - Support attributes= in column, to set multiple settings with a hash
9
+ - Fix update_columns in type column of polymorphic association, when foreign key has value, it will look for old id with new type and may fail
10
+ - Support changing between subform and form_ui with update_columns
11
+ - Deprecate automatic :select form_ui for associations in subforms, set :select in the controller config to remove deprecation warning, or enable new behaviour of nested subforms with ActiveScaffold.nested_subforms = true
12
+ - Some fixes for human conditions with some search UI
13
+ - Add more string comparators in field search
14
+ - Support date and datetime searches with operators using html5 inputs, as was supported when using date picker. The different bridges, date_picker and calendar_date_select, will just replace the input fields.
15
+ - Support disabling default usage of jquery UI date picker, in case of sortable is wanted, so jquery-ui-rails is loaded, but wants to use HTML5 date input.
16
+ - Support multiple id in constraints for polymorphic association, and don't register constrained field if value is an array.
17
+ - Support subqueries in field_search, with new syntax for search_sql, so search in polymorphic associations is possible.
18
+ - Better support for active model attributes
19
+ - Load files on boot using initializer blocks and use hooks to patch rails classes, run hook :active_scaffold_routing when routing is loaded so other plugins can extend routes
20
+
21
+ = 3.7.0
22
+ - Drop support for rails < 5.2 and ruby < 2.5
23
+ - Support adding settings for chosen and tinyMCE in initializer (ActiveScaffold.js_config) or JavaScript code (ActiveScaffold.config, needed for callbacks)
24
+ - Support ruby 3.0 and 3.1
25
+ - Check action link security method in process_action_link_action with no id
26
+ - Add thumbnail_variant setting to ActiveStorage bridge
27
+ - Support Postgres citext column type
28
+ - Fix date picker bridge for ruby >= 2.7
29
+ - Fix keeping_errors for rails >= 6.1
30
+ - Fix usage of field_error_proc on record_select bridge for rails 7
31
+ - Support TinyMCE 6
32
+ - Add hide_form_column_if to columns
33
+ - Re-enable form which is sent to iframe when response is received, e.g. if form is downloading a file
34
+ - Use hash order for bitfields value instead of bit order, so options can be re-ordered as `2**1 => opt1, 2**0 => opt0, 2**2 => opt2`
35
+ - Remove delayed_setup, as it didn't work since rails 5.2
36
+ - Support Turbo
37
+ - Fix detecting when form submit to iframe has ended, for downloads too (using cookie)
38
+ - Fix list deleted records on nested listings using JSON column or serializer in PaperTrail versions table
39
+ - Support procs in description of columns, passing record, column, and scope to the proc
40
+ - Fix displaying errors in forms in rails 7.1
41
+ - Support for mongoid 7
42
+ - Support update_columns in field_search, so cascading behaviour is available to field search as in create or update forms
43
+ - Support floating footer in field_search, create and update, so footer may float to keep it visible when form is too long to fit
44
+ - Support hide/show link in form columns with option :collapsible
45
+ - Improve support for three-state boolean (nullable boolean columns), allowing to change the label for NULL
46
+ - Improve support for nullable boolean columns in field search, allowing to search for NULL
47
+
1
48
  = 3.6.20
2
49
  - Fix numeric search on field search for rails >= 5.0
3
50
 
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
 
2
2
  Overview
3
3
  ========
4
- [![Build status](https://travis-ci.com/activescaffold/active_scaffold.svg?branch=master)](https://travis-ci.com/activescaffold/active_scaffold)
4
+ [![Build status](https://api.travis-ci.com/activescaffold/active_scaffold.svg?branch=master)](https://app.travis-ci.com/activescaffold/active_scaffold)
5
5
  [![Code Climate](https://codeclimate.com/github/activescaffold/active_scaffold/badges/gpa.svg)](https://codeclimate.com/github/activescaffold/active_scaffold)
6
6
  [![Test Coverage](https://codeclimate.com/github/activescaffold/active_scaffold/badges/coverage.svg)](https://codeclimate.com/github/activescaffold/active_scaffold)
7
7
  [![Dependency Status](https://gemnasium.com/activescaffold/active_scaffold.svg)](https://gemnasium.com/activescaffold/active_scaffold)
@@ -9,10 +9,14 @@ Overview
9
9
  [![Inline docs](https://inch-ci.org/github/activescaffold/active_scaffold.svg?branch=master)](https://inch-ci.org/github/activescaffold/active_scaffold)
10
10
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
11
11
 
12
- 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 >= 4.2.0 and Rails <= 6.1 is supported, ruby >= 2.3 required.
12
+ 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 >= 5.2.0 is supported, ruby >= 2.5 required.
13
13
 
14
14
  Branch Details
15
15
  --------------
16
+ 3-7-stable supports rails >= 5.2.x and <= 7.1.x, and ruby >= 2.5.0
17
+
18
+ These versions are not supported anymore:
19
+ 3-6-stable supports rails >= 4.2.x and <= 6.1.x, and ruby >= 2.3.0
16
20
  3-5-stable supports rails >= 4.0.x and <= 5.1.x, and ruby >= 2.0.0
17
21
  3-4-stable supports rails >= 3.2.x and <= 4.2.x, and ruby >= 1.9.3
18
22
  3-3-stable supports rails 3.2.x and ruby >= 1.8
@@ -24,33 +28,42 @@ To get started with a new Rails project
24
28
 
25
29
  Added to Gemfile
26
30
 
27
- gem 'active_scaffold'
31
+ ```ruby
32
+ gem 'active_scaffold'
33
+ ```
28
34
 
29
35
  For rails >= 5.1, add jquery-rails to Gemfile, and install generator will jquery to application.js before rails-ujs. Also it's possible to load jquery in your layout before application.js using CDN (e.g. jquery-rails-cdn). You can replace rails-ujs with jquery_ujs, although rails-ujs should work (never load both).
30
36
 
31
- gem 'jquery-rails'
37
+ ```ruby
38
+ gem 'jquery-rails'
39
+ ```
32
40
 
33
41
  For rails >= 6.0, installer generator will create app/assets/javascripts/application.js, add it to assets.precompile array and add javascript_include_tag in layout, as ActiveScaffold doesn't work with webpack yet. Jquery may be loaded by packs or assets pipeline.
34
42
 
35
43
  Run the following commands, for rails 4.2
36
44
 
37
- bundle install
38
- rails g active_scaffold:install
39
- bundle exec rake db:create
40
- rails g active_scaffold:resource Model [attrs]
41
- bundle exec rake db:migrate
42
-
45
+ ```console
46
+ bundle install
47
+ rails g active_scaffold:install
48
+ bundle exec rake db:create
49
+ rails g active_scaffold:resource Model [attrs]
50
+ bundle exec rake db:migrate
51
+ ```
52
+
43
53
  Or run the following commands, for rails >= 5
44
54
 
45
- bundle install
46
- rails g active_scaffold:install
47
- rails db:create
48
- rails g active_scaffold:resource Model [attrs]
49
- rails db:migrate
50
-
55
+ ```console
56
+ bundle install
57
+ rails g active_scaffold:install
58
+ rails db:create
59
+ rails g active_scaffold:resource Model [attrs]
60
+ rails db:migrate
61
+ ```
51
62
 
52
63
  Run the app and visit localhost:3000/<plural_model>
53
64
 
65
+ It's recommended to call `clear_helpers` in ApplicationController, as some helpers defined by ActiveScaffold, such as active_scaffold_enum_options, options_for_association_conditions, association_klass_scoped, are usually overrided for different controllers, and it may cause issues when all helper modules are available to every controller, specially when models have associations or columns with the same name but need different code for those overrided helper methods.
66
+
54
67
  Threadsafe
55
68
  ----------
56
69
 
@@ -1,34 +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;
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
+ }
27
28
  }
28
29
  }
29
- }
30
- });
31
- */
30
+ });
31
+ */
32
32
  if (/1\.[2-7]\..*/.test(jQuery().jquery)) {
33
33
  var error = 'ActiveScaffold requires jquery 1.8.0 or greater, please use jquery-rails 2.1.x gem or greater';
34
34
  if (typeof console != 'undefined') console.error(error);
@@ -72,9 +72,26 @@ jQuery(document).ready(function($) {
72
72
  }
73
73
  });
74
74
  jQuery(document).on('submit', 'form.as_form:not([data-remote])', function(event) {
75
- var as_form = jQuery(this).closest("form");
75
+ var as_form = jQuery(this).closest("form"), form_id = as_form.attr('id'), iframe, interval, doc, cookie;
76
76
  if (as_form.data('loading') == true) {
77
- setTimeout("ActiveScaffold.disable_form('" + as_form.attr('id') + "')", 10);
77
+ setTimeout(function() { ActiveScaffold.disable_form(form_id); }, 10);
78
+ if (as_form.attr('target')) {
79
+ cookie = 'as_dl_' + new Date().getTime();
80
+ as_form.append($('<input>', {type: 'hidden', name: '_dl_cookie', value: cookie}));
81
+ iframe = jQuery('iframe[name="' + jQuery(this).attr('target') + '"]')[0];
82
+ interval = setInterval(function() {
83
+ doc = iframe.contentDocument || (iframe.contentWindow && iframe.contentWindow.document);
84
+ if (doc && doc.readyState !== 'loading' && (doc.location.href !== 'about:blank' || document.cookie.split(cookie+'=').length == 2)) {
85
+ ActiveScaffold.enable_form(form_id);
86
+ clearInterval(interval);
87
+ doc.location.replace('about:blank');
88
+ document.cookie = cookie + '=; path=/; expires=' + new Date().toUTCString();
89
+ } else if (!doc) {
90
+ clearInterval(interval);
91
+ document.cookie = cookie + '=; path=/; expires=' + new Date().toUTCString();
92
+ }
93
+ }, 1000);
94
+ }
78
95
  }
79
96
  return true;
80
97
  });
@@ -181,7 +198,7 @@ jQuery(document).ready(function($) {
181
198
  var td = jQuery(this), span = td.find('span.in_place_editor_field');
182
199
  if (event.type == 'mouseenter') {
183
200
  if (td.hasClass('empty') || typeof(span.data('editInPlace')) === 'undefined') td.find('span').addClass("hover");
184
- }
201
+ }
185
202
  if (event.type == 'mouseleave') {
186
203
  if (td.hasClass('empty') || typeof(span.data('editInPlace')) === 'undefined') td.find('span').removeClass("hover");
187
204
  }
@@ -249,6 +266,7 @@ jQuery(document).ready(function($) {
249
266
  var element = jQuery(this);
250
267
  var form_element = element.prev();
251
268
  var value;
269
+ if (form_element.is(".field_with_errors")) form_element = form_element.children().last();
252
270
  if (form_element.is(".checkbox-list")) {
253
271
  value = form_element.find(':checked').map(function(item){return $(this).val();}).toArray();
254
272
  form_element = form_element.parent().find("input:checkbox"); // parent is needed for draggable-list, checked list may be empty
@@ -358,7 +376,7 @@ jQuery(document).ready(function($) {
358
376
  jQuery(this).parent().find('[type=submit]').click();
359
377
  }));
360
378
 
361
- jQuery(document).on('turbolinks:before-visit', function() {
379
+ jQuery(document).on('turbolinks:before-visit turbo:before-visit', function() {
362
380
  if (history.state.active_scaffold) {
363
381
  history.replaceState({turbolinks: true, url: document.location.href}, '', document.location.href);
364
382
  }
@@ -377,13 +395,16 @@ jQuery(document).ready(function($) {
377
395
  });
378
396
 
379
397
  // call setup on document.ready if Turbolinks not enabled
380
- if (typeof(Turbolinks) == 'undefined' || !Turbolinks.supported) {
398
+ if ((typeof(Turbolinks) == 'undefined' || !Turbolinks.supported) && typeof(Turbo) == 'undefined') {
381
399
  ActiveScaffold.setup_history_state();
382
400
  ActiveScaffold.setup(document);
383
401
  }
384
402
  if (ActiveScaffold.config.warn_changes) ActiveScaffold.setup_warn_changes();
385
403
  jQuery(document).on('as:element_updated as:element_created', function(e, action_link) {
386
- ActiveScaffold.setup(e.target);
404
+ ActiveScaffold.setup(e.target);
405
+ });
406
+ jQuery(document).on('as:element_removed', function(e, action_link) {
407
+ setTimeout(ActiveScaffold.update_floating_form_footer); // delay so form is already removed
387
408
  });
388
409
  jQuery(document).on('as:action_success', 'a.as_action', function(e, action_link) {
389
410
  ActiveScaffold.setup(action_link.adapter);
@@ -395,7 +416,7 @@ jQuery(document).ready(function($) {
395
416
  });
396
417
  });
397
418
 
398
- jQuery(document).on('turbolinks:load', function($) {
419
+ jQuery(document).on('turbolinks:load turbo:load', function($) {
399
420
  ActiveScaffold.setup(document);
400
421
  });
401
422
 
@@ -423,7 +444,7 @@ jQuery(document).on('turbolinks:load', function($) {
423
444
  for (var name in prop) {
424
445
  // Check if we're overwriting an existing function
425
446
  prototype[name] = typeof prop[name] == "function" &&
426
- typeof _super[name] == "function" && fnTest.test(prop[name]) ?
447
+ typeof _super[name] == "function" && fnTest.test(prop[name]) ?
427
448
  (function(name, fn){
428
449
  return function() {
429
450
  var tmp = this._super;
@@ -477,6 +498,7 @@ var ActiveScaffold = {
477
498
  ActiveScaffold.draggable_lists('.draggable-lists', container);
478
499
  ActiveScaffold.sliders(container);
479
500
  ActiveScaffold.disable_optional_subforms(container);
501
+ ActiveScaffold.update_floating_form_footer(); // check other forms too, state may change
480
502
  },
481
503
  setup_history_state: function() {
482
504
  if (!jQuery('.active-scaffold').length) return;
@@ -909,25 +931,30 @@ var ActiveScaffold = {
909
931
  render_form_field: function(source, content, options) {
910
932
  if (typeof(source) == 'string') source = '#' + source;
911
933
  var source = jQuery(source);
912
- var element = source.closest('.sub-form-record'), selector = '';
913
- if (element.length == 0) {
914
- element = source.closest('form > ol.form');
934
+ var element, container = source.closest('.sub-form-record'), selector = '';
935
+ if (container.length == 0) {
936
+ container = source.closest('form > ol.form');
915
937
  selector = 'li';
916
938
  }
917
939
  // find without entering new subforms
918
- selector = options.is_subform ? '' : selector + ':not(.sub-form) ';
919
- element = element.find(selector + '.' + options.field_class).first();
940
+ element = container.find(selector + ':not(.sub-form) .' + options.field_class).first();
941
+ if (element.length)
942
+ element = element.closest('dl');
943
+ else if (options.subform_class)
944
+ element = container.find(selector + '.' + options.subform_class).first();
920
945
 
921
946
  if (element.length) {
922
- if (options.is_subform == false) {
923
- if (typeof(options.hidden) != 'undefined') {
924
- var li = element.closest('li');
925
- li[options.hidden ? 'addClass' : 'removeClass'].call(li, 'hidden')
926
- }
927
- this.replace(element.closest('dl'), content);
928
- } else {
947
+ var parent = element.is('li, td') ? element : element.parent('li, td');
948
+ if (element.is('li'))
929
949
  this.replace_html(element, content);
950
+ else
951
+ this.replace(element, content);
952
+ if (parent.is('li')) {
953
+ for (var attr in options.attrs)
954
+ parent.attr(attr, options.attrs[attr]);
930
955
  }
956
+ if (typeof(options.hidden) != 'undefined')
957
+ parent[options.hidden ? 'addClass' : 'removeClass'].call(parent, 'hidden')
931
958
  }
932
959
  },
933
960
 
@@ -960,23 +987,23 @@ var ActiveScaffold = {
960
987
  // test editor is open
961
988
  if (typeof(span.data('editInPlace')) === 'undefined') {
962
989
  var options = {show_buttons: true,
963
- hover_class: 'hover',
964
- element_id: 'editor_id',
965
- ajax_data_type: "script",
966
- delegate: {
967
- willCloseEditInPlace: function(span, options) {
968
- if (span.data('addEmptyOnCancel')) span.closest('td').addClass('empty');
969
- span.closest('tr').find('td.actions .loading-indicator').css('visibility','visible');
970
- },
971
- didCloseEditInPlace: function(span, options) {
972
- span.closest('tr').find('td.actions .loading-indicator').css('visibility','hidden');
973
- }
974
- },
975
- update_value: 'value'},
976
- csrf_param = jQuery('meta[name=csrf-param]').first(),
977
- csrf_token = jQuery('meta[name=csrf-token]').first(),
978
- my_parent = span.parent(),
979
- column_heading = null;
990
+ hover_class: 'hover',
991
+ element_id: 'editor_id',
992
+ ajax_data_type: "script",
993
+ delegate: {
994
+ willCloseEditInPlace: function(span, options) {
995
+ if (span.data('addEmptyOnCancel')) span.closest('td').addClass('empty');
996
+ span.closest('tr').find('td.actions .loading-indicator').css('visibility','visible');
997
+ },
998
+ didCloseEditInPlace: function(span, options) {
999
+ span.closest('tr').find('td.actions .loading-indicator').css('visibility','hidden');
1000
+ }
1001
+ },
1002
+ update_value: 'value'},
1003
+ csrf_param = jQuery('meta[name=csrf-param]').first(),
1004
+ csrf_token = jQuery('meta[name=csrf-token]').first(),
1005
+ my_parent = span.parent(),
1006
+ column_heading = null;
980
1007
 
981
1008
  if(!(my_parent.is('td') || my_parent.is('th'))){
982
1009
  my_parent = span.parents('td').eq(0);
@@ -990,8 +1017,8 @@ var ActiveScaffold = {
990
1017
  }
991
1018
 
992
1019
  var render_url = column_heading.data('ie-render-url'),
993
- mode = column_heading.data('ie-mode'),
994
- record_id = span.data('ie-id') || '';
1020
+ mode = column_heading.data('ie-mode'),
1021
+ record_id = span.data('ie-id') || '';
995
1022
 
996
1023
  ActiveScaffold.read_inplace_edit_heading_attributes(column_heading, options);
997
1024
 
@@ -1134,15 +1161,26 @@ var ActiveScaffold = {
1134
1161
  window.onbeforeunload = function() {
1135
1162
  if (jQuery('form.need-confirm').length) return unload_message;
1136
1163
  };
1137
- jQuery(document).on('turbolinks:before-visit', function(e) {
1164
+ jQuery(document).on('turbolinks:before-visit turbolinks:before-visit', function(e) {
1138
1165
  if (jQuery('form.need-confirm').length) {
1139
1166
  if (!window.confirm(unload_message)) e.preventDefault();
1140
1167
  }
1141
1168
  });
1169
+ },
1170
+
1171
+ update_floating_form_footer: function() {
1172
+ jQuery('.active-scaffold form.floating-footer .form-footer').each(function () {
1173
+ var $footer = jQuery(this), $form = $footer.closest('form.floating-footer');
1174
+ $footer.removeClass('floating');
1175
+ if ($form.visible(true) && !$footer.visible(true)) $footer.addClass('floating');
1176
+ });
1142
1177
  }
1178
+
1143
1179
  }
1144
1180
 
1145
1181
 
1182
+ jQuery(window).on('scroll resize', ActiveScaffold.update_floating_form_footer);
1183
+
1146
1184
  /*
1147
1185
  * URL modification support. Incomplete functionality.
1148
1186
  */
@@ -1,14 +1,15 @@
1
1
  jQuery(document).ready(function() {
2
+ var chosen_options = ActiveScaffold.config.chosen_options || {};
2
3
  jQuery(document).on('as:element_updated as:element_created', function(event) {
3
- jQuery('select.chosen', event.target).chosen();
4
+ jQuery('select.chosen', event.target).chosen(chosen_options);
4
5
  });
5
6
  jQuery(document).on('as:action_success', 'a.as_action', function(event, action_link) {
6
7
  if (action_link.adapter) {
7
- jQuery('select.chosen', action_link.adapter).chosen();
8
+ jQuery('select.chosen', action_link.adapter).chosen(chosen_options);
8
9
  }
9
10
  });
10
- jQuery('select.chosen').chosen();
11
- jQuery(document).on('turbolinks:load', function($) {
12
- jQuery('select.chosen').chosen();
11
+ jQuery('select.chosen').chosen(chosen_options);
12
+ jQuery(document).on('turbolinks:load turbo:load', function($) {
13
+ jQuery('select.chosen').chosen(chosen_options);
13
14
  });
14
15
  });
@@ -8,9 +8,23 @@
8
8
  };
9
9
 
10
10
  function loadTinyMCE() {
11
- var settings = jQuery(this).data('tinymce');
12
- if (settings) tinyMCE.settings = settings;
13
- tinyMCE.execCommand('mceAddEditor', false, jQuery(this).attr('id'));
11
+ var global_settings = ActiveScaffold.config.tiny_mce_settings || {};
12
+ var local_settings = jQuery(this).data('tinymce');
13
+ var settings = {};
14
+ for (key in global_settings) {
15
+ settings[key] = global_settings[key];
16
+ }
17
+ for (key in local_settings) {
18
+ settings[key] = local_settings[key];
19
+ }
20
+ var id = jQuery(this).attr('id');
21
+ if (tinymce && tinymce.majorVersion >= 6) {
22
+ settings.selector = '#' + id;
23
+ tinymce.init(settings);
24
+ } else { // tinyMCE.majorVersion < 6
25
+ tinyMCE.settings = settings;
26
+ tinyMCE.execCommand('mceAddEditor', false, id);
27
+ }
14
28
  }
15
29
 
16
30
  jQuery(document).on('submit', 'form.as_form', function() {
@@ -28,4 +42,4 @@
28
42
  jQuery(action_link.adapter).find('textarea.mceEditor').each(loadTinyMCE);
29
43
  }
30
44
  });
31
- })();
45
+ })();
@@ -672,6 +672,17 @@ clear: both;
672
672
  .active-scaffold p.form-footer {
673
673
  clear: both;
674
674
  }
675
+ .active-scaffold .form-footer.floating {
676
+ position: fixed;
677
+ bottom: 10px;
678
+ z-index: 10;
679
+ top: auto;
680
+ left: auto;
681
+ border: none;
682
+ padding: 10px;
683
+ background: white;
684
+ }
685
+
675
686
 
676
687
  .active-scaffold a.as_cancel,
677
688
  .active-scaffold p.form-footer a {
@@ -694,7 +705,7 @@ letter-spacing: 0;
694
705
  clear: both;
695
706
  }
696
707
 
697
- .active-scaffold label {
708
+ .active-scaffold label, .active-scaffold label + a.visibility-toggle {
698
709
  font-weight: normal;
699
710
  font-size: 11px;
700
711
  }
@@ -844,7 +855,7 @@ padding-left: 5px;
844
855
  .active-scaffold .form-element .sub-form.optional {
845
856
  float: none;
846
857
  }
847
- .active-scaffold .form-element .show-new-subform {
858
+ .active-scaffold .form-element a.show-new-subform {
848
859
  margin-left: 5px;
849
860
  }
850
861
 
@@ -7,11 +7,15 @@
7
7
  multipart ||= action_config.multipart? unless local_assigns.has_key? :multipart
8
8
  columns ||= action_config.columns unless local_assigns.has_key? :columns
9
9
  persistent ||= action_config.persistent unless local_assigns.has_key? :persistent
10
+ unless local_assigns.has_key? :floating_footer
11
+ floating_footer ||= action_config.floating_footer if action_config.respond_to? :floating_footer
12
+ end
10
13
  else
11
14
  multipart ||= false
12
15
  columns ||= nil
13
16
  persistent ||= false
14
17
  end
18
+ floating_footer ||= false
15
19
  method ||= :post
16
20
  cancel_link = true if cancel_link.nil?
17
21
  submit_text ||= form_action
@@ -26,7 +30,7 @@ options = {:id => form_id,
26
30
  :method => method,
27
31
  'data-loading' => defined?(loading) ? loading : true}
28
32
  cancel_options = {:class => 'as_cancel'}
29
-
33
+ options[:class] << ' floating-footer' if floating_footer
30
34
  cancel_options[:remote] = true if xhr #cancel link does nt have to care about multipart forms
31
35
  if xhr && multipart # file_uploads
32
36
  form_remote_upload_tag url_options.merge({:iframe => true}), options
@@ -9,6 +9,7 @@
9
9
  data: {loading: true},
10
10
  method: :get
11
11
  }
12
+ options[:class] << ' floating-footer' if active_scaffold_config.field_search.floating_footer
12
13
 
13
14
  hidden_params = url_options.except(:controller, :action, :id, :search).to_query.split(Rack::Utils::DEFAULT_SEP)
14
15
  -%>
@@ -52,7 +52,8 @@
52
52
  next unless in_subform?(column, parent_record, record_column)
53
53
  columns_length += 1
54
54
  show_actions = true
55
- if column.association && column.form_ui.nil?
55
+ if !ActiveScaffold.nested_subforms && !readonly && column.association && column.form_ui.nil?
56
+ ActiveSupport::Deprecation.warn "Nested subforms are allowed now, set form_ui = :select for #{column.name} in controller for #{config.model.name}"
56
57
  column = column.dup unless ActiveScaffold.threadsafe
57
58
  column.form_ui = :select
58
59
  end
@@ -8,23 +8,34 @@
8
8
  @rendered ||= Set.new
9
9
  return if @rendered.include? column.name
10
10
  @rendered << column.name
11
- renders_as = column_renders_as(column)
12
- if renders_as == :subform
13
- options = {:is_subform => true, :field_class => "#{column.name}-sub-form"}
11
+ if @form_action == :field_search
12
+ form_ui = column.search_ui
14
13
  else
15
- options = {:is_subform => false, :field_class => "#{column.name}-input", :hidden => column.form_ui == :hidden}
16
- end
17
- html = if scope
18
- readonly = @record.readonly? || !@record.authorized_for?(:crud_type => :update)
19
- crud_type = @record.new_record? ? :create : (readonly ? :read : :update)
20
- # subform.columns.to_a.include? so it doesn't check inside subgroups
21
- active_scaffold_render_subform_column(column, scope, crud_type, readonly, !active_scaffold_config.subform.columns.to_a.include?(column.name), @record)
22
- else
23
- render_column(column, @record, renders_as, scope)
14
+ renders_as = column_renders_as(column)
15
+ form_ui = column.form_ui
24
16
  end
17
+ options = {field_class: "#{column.name}-input", hidden: form_ui == :hidden}
18
+ options[:subform_class] = "#{column.name}-sub-form" if column.association
19
+ options[:attrs] =
20
+ if renders_as == :subform
21
+ active_scaffold_subform_attributes(column, (column.css_class unless column.css_class.is_a?(Proc)))
22
+ else
23
+ {class: 'form-element', id: ''}
24
+ end
25
+ html =
26
+ if scope
27
+ readonly = @record.readonly? || !@record.authorized_for?(:crud_type => :update)
28
+ crud_type = @record.new_record? ? :create : (readonly ? :read : :update)
29
+ # subform.columns.to_a.include? so it doesn't check inside subgroups
30
+ active_scaffold_render_subform_column(column, scope, crud_type, readonly, !active_scaffold_config.subform.columns.to_a.include?(column.name), @record)
31
+ elsif @form_action == :field_search
32
+ search_attribute(column, @record)
33
+ else
34
+ render_column(column, @record, renders_as, scope)
35
+ end
25
36
  -%>
26
37
 
27
38
  ActiveScaffold.render_form_field('<%= source_id %>','<%= escape_javascript(html) %>', <%= options.to_json.html_safe %>);
28
39
  <%if column.update_columns && !column.update_columns.empty?%>
29
- <%= render(:partial => "render_field", :collection => column.update_columns, :locals => {:source_id => source_id, :scope => scope})%>
40
+ <%= render(partial: "render_field", collection: column.update_columns, locals: {source_id: source_id, scope: scope})%>
30
41
  <%end%>
@@ -47,6 +47,9 @@ de:
47
47
  deleted_model: "%{model} gelöscht"
48
48
  deleted_records: Gelöschte Records auflisten
49
49
  delimiter: Trennzeichen
50
+ doesnt_begin_with:
51
+ doesnt_contain:
52
+ doesnt_end_with:
50
53
  download: Herunterladen
51
54
  edit: Bearbeiten
52
55
  ends_with: Endet
@@ -138,10 +141,10 @@ de:
138
141
  yesterday: Gestern
139
142
  date:
140
143
  formats:
141
- month:
144
+ month: "%B"
142
145
  quarter: Quartal %{num}
143
- week:
144
- year_month:
146
+ week:
147
+ year_month: "%b %Y"
145
148
  year_quarter: Quartal %{quarter} %{year}
146
149
  time:
147
150
  formats:
@@ -47,6 +47,9 @@ en:
47
47
  deleted_model: Deleted %{model}
48
48
  deleted_records: List Deleted Records
49
49
  delimiter: Delimiter
50
+ doesnt_begin_with: Doesn't begin with
51
+ doesnt_contain: Doesn't contain
52
+ doesnt_end_with: Doesn't end with
50
53
  download: Download
51
54
  edit: Edit
52
55
  ends_with: Ends with