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
@@ -1,7 +0,0 @@
1
- class Array
2
- # returns the value after the given value. wraps around. defaults to first element in array.
3
- def after(value)
4
- return nil unless include? value
5
- self[(index(value).to_i + 1) % length]
6
- end
7
- end
@@ -1,16 +0,0 @@
1
- module ActiveRecord
2
- class Relation
3
- def target=(records)
4
- @loaded = true
5
- @records = records
6
- @records
7
- end
8
- end
9
- end
10
- module ActiveRecord
11
- module Associations
12
- class CollectionProxy
13
- delegate :target=, :to => :@association
14
- end
15
- end
16
- end
@@ -1,46 +0,0 @@
1
- module ActionView
2
- module Helpers
3
- module FormOptionsHelper
4
-
5
- # Return a full select and option tags for the given object and method, using usa_state_options_for_select to generate the list of option <tags>.
6
- def usa_state_select(object, method, priority_states = nil, options = {}, html_options = {})
7
- InstanceTag.new(object, method, self, options.delete(:object)).to_usa_state_select_tag(priority_states, options, html_options)
8
- end
9
-
10
-
11
- # Returns a string of option tags for the states in the United States. Supply a state name as +selected to
12
- # have it marked as the selected option tag. Included also is the option to set a couple of +priority_states+
13
- # in case you want to highligh a local area
14
- # NOTE: Only the option tags are returned from this method, wrap it in a <select>
15
- def usa_state_options_for_select(selected = nil, priority_states = nil)
16
- state_options = ""
17
- if priority_states
18
- state_options += options_for_select(priority_states, selected)
19
- state_options += "<option>-------------</option>\n"
20
- end
21
-
22
- if priority_states && priority_states.include?(selected)
23
- state_options += options_for_select(USASTATES - priority_states, selected)
24
- else
25
- state_options += options_for_select(USASTATES, selected)
26
- end
27
-
28
- return state_options
29
- end
30
-
31
- USASTATES = [["Alabama", "AL"], ["Alaska", "AK"], ["Arizona", "AZ"], ["Arkansas", "AR"], ["California", "CA"], ["Colorado", "CO"], ["Connecticut", "CT"], ["Delaware", "DE"], ["District of Columbia", "DC"], ["Florida", "FL"], ["Georgia", "GA"], ["Hawaii", "HI"], ["Idaho", "ID"], ["Illinois", "IL"], ["Indiana", "IN"], ["Iowa", "IA"], ["Kansas", "KS"], ["Kentucky", "KY"], ["Louisiana", "LA"], ["Maine", "ME"], ["Maryland", "MD"], ["Massachusetts", "MA"], ["Michigan", "MI"], ["Minnesota", "MN"], ["Mississippi", "MS"], ["Missouri", "MO"], ["Montana", "MT"], ["Nebraska", "NE"], ["Nevada", "NV"], ["New Hampshire", "NH"], ["New Jersey", "NJ"], ["New Mexico", "NM"], ["New York", "NY"], ["North Carolina", "NC"], ["North Dakota", "ND"], ["Ohio", "OH"], ["Oklahoma", "OK"], ["Oregon", "OR"], ["Pennsylvania", "PA"], ["Rhode Island", "RI"], ["South Carolina", "SC"], ["South Dakota", "SD"], ["Tennessee", "TN"], ["Texas", "TX"], ["Utah", "UT"], ["Vermont", "VT"], ["Virginia", "VA"], ["Washington", "WA"], ["Wisconsin", "WI"], ["West Virginia", "WV"], ["Wyoming", "WY"]] unless const_defined?("USASTATES")
32
-
33
- end
34
-
35
- class InstanceTag #:nodoc:
36
- include FormOptionsHelper
37
-
38
- def to_usa_state_select_tag(priority_states, options, html_options)
39
- html_options = html_options.stringify_keys
40
- add_default_name_and_id(html_options)
41
- value = value(object) if method(:value).arity > 0
42
- content_tag("select", add_options(usa_state_options_for_select(value, priority_states), options, value), html_options)
43
- end
44
- end
45
- end
46
- end
@@ -1,13 +0,0 @@
1
- # TODO: clean up extensions. some could be organized for autoloading, and others could be removed entirely.
2
- Dir["#{File.dirname __FILE__}/active_scaffold/extensions/*.rb"].each { |file| require file }
3
- module ActiveScaffold
4
- autoload :Tableless, 'active_scaffold/tableless'
5
- end
6
-
7
- ActionController::Base.send(:include, ActiveScaffold)
8
- ActionController::Base.send(:include, RespondsToParent)
9
- ActionController::Base.send(:include, ActiveScaffold::Helpers::ControllerHelpers)
10
- ActionView::Base.send(:include, ActiveScaffold::Helpers::ViewHelpers)
11
-
12
- ActionController::Base.class_eval {include ActiveRecordPermissions::ModelUserAccess::Controller}
13
- ActiveRecord::Base.class_eval {include ActiveRecordPermissions::ModelUserAccess::Model}
@@ -1,12 +0,0 @@
1
- require 'test_helper'
2
-
3
- class ArrayTest < Test::Unit::TestCase
4
- def test_after
5
- @sequence = ['a', 'b', 'c']
6
-
7
- assert_equal 'b', @sequence.after('a')
8
- assert_equal 'c', @sequence.after('b')
9
- assert_equal 'a', @sequence.after('c')
10
- assert_equal nil, @sequence.after('d')
11
- end
12
- end
@@ -1,33 +0,0 @@
1
- <!--
2
- Copyright (c) 2005, Brad Neuberg, bkn3@columbia.edu
3
- http://codinginparadise.org
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining
6
- a copy of this software and associated documentation files (the "Software"),
7
- to deal in the Software without restriction, including without limitation
8
- the rights to use, copy, modify, merge, publish, distribute, sublicense,
9
- and/or sell copies of the Software, and to permit persons to whom the
10
- Software is furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be
13
- included in all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
20
- OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
21
- THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
- -->
23
-
24
- <html>
25
- <script language="JavaScript">
26
- function pageLoaded() {
27
- window.parent.dhtmlHistory.iframeLoaded(window.location);
28
- }
29
- </script>
30
- <body onload="pageLoaded()">
31
- <h1>blank.html - Needed for Internet Explorer's hidden IFrame</h1>
32
- </body>
33
- </html>
@@ -1,2 +0,0 @@
1
- Any changes made to files in sub-folders will be lost.
2
- See http://activescaffold.com/tutorials/faq#custom-css.
@@ -1,2 +0,0 @@
1
- Any changes made to files in sub-folders will be lost.
2
- See http://activescaffold.com/tutorials/faq#custom-css.
@@ -1,532 +0,0 @@
1
- if (typeof Prototype == 'undefined')
2
- {
3
- warning = "ActiveScaffold Error: Prototype could not be found. Please make sure that your application's layout includes prototype.js (e.g. <%= javascript_include_tag :defaults %>) *before* it includes active_scaffold.js (e.g. <%= active_scaffold_includes %>).";
4
- alert(warning);
5
- }
6
- if (Prototype.Version.substring(0, 3) < '1.6')
7
- {
8
- warning = "ActiveScaffold Error: Prototype version 1.6.x or higher is required. Please update prototype.js (rake rails:update:javascripts).";
9
- alert(warning);
10
- }
11
- if (!Element.Methods.highlight) Element.addMethods({highlight: Prototype.emptyFunction});
12
-
13
-
14
- /*
15
- * Simple utility methods
16
- */
17
-
18
- var ActiveScaffold = {
19
- records_for: function(tbody_id) {
20
- var rows = [];
21
- var child = $(tbody_id).down('.record');
22
- while (child) {
23
- rows.push(child);
24
- child = child.next('.record');
25
- }
26
- return rows;
27
- },
28
- stripe: function(tbody_id) {
29
- var even = false;
30
- var rows = this.records_for(tbody_id);
31
- for (var i = 0; i < rows.length; i++) {
32
- var child = rows[i];
33
- //Make sure to skip rows that are create or edit rows or messages
34
- if (child.tagName != 'SCRIPT'
35
- && !child.hasClassName("create")
36
- && !child.hasClassName("update")
37
- && !child.hasClassName("inline-adapter")
38
- && !child.hasClassName("active-scaffold-calculations")) {
39
-
40
- if (even) child.addClassName("even-record");
41
- else child.removeClassName("even-record");
42
-
43
- even = !even;
44
- }
45
- }
46
- },
47
- hide_empty_message: function(tbody, empty_message_id) {
48
- if (this.records_for(tbody).length != 0) {
49
- $(empty_message_id).hide();
50
- }
51
- },
52
- reload_if_empty: function(tbody, url) {
53
- if (this.records_for(tbody).length == 0) {
54
- new Ajax.Request(url, {
55
- method: 'get',
56
- asynchronous: true,
57
- evalScripts: true
58
- });
59
- }
60
- },
61
- removeSortClasses: function(scaffold_id) {
62
- $$('#' + scaffold_id + ' td.sorted').each(function(element) {
63
- element.removeClassName("sorted");
64
- });
65
- $$('#' + scaffold_id + ' th.sorted').each(function(element) {
66
- element.removeClassName("sorted");
67
- element.removeClassName("asc");
68
- element.removeClassName("desc");
69
- });
70
- },
71
- decrement_record_count: function(scaffold_id) {
72
- // decrement the last record count, firsts record count are in nested lists
73
- count = $$('#' + scaffold_id + ' span.active-scaffold-records').last();
74
- if (count) count.update(parseInt(count.innerHTML, 10) - 1);
75
- },
76
- increment_record_count: function(scaffold_id) {
77
- // increment the last record count, firsts record count are in nested lists
78
- count = $$('#' + scaffold_id + ' span.active-scaffold-records').last();
79
- if (count) count.update(parseInt(count.innerHTML, 10) + 1);
80
- },
81
- update_row: function(row, html) {
82
- row = $(row);
83
- Element.replace(row, html);
84
- var new_row = $(row.id);
85
- if (row.hasClassName('even-record')) new_row.addClassName('even-record');
86
- new_row.highlight();
87
- },
88
-
89
- server_error_response: '',
90
- report_500_response: function(active_scaffold_id) {
91
- messages_container = $(active_scaffold_id).down('td.messages-container');
92
- new Insertion.Top(messages_container, this.server_error_response);
93
- }
94
- }
95
-
96
- /*
97
- * DHTML history tie-in
98
- */
99
- function addActiveScaffoldPageToHistory(url, active_scaffold_id) {
100
- if (typeof dhtmlHistory == 'undefined') return; // it may not be loaded
101
-
102
- var array = url.split('?');
103
- var qs = new Querystring(array[1]);
104
- var sort = qs.get('sort')
105
- var dir = qs.get('sort_direction')
106
- var page = qs.get('page')
107
- if (sort || dir || page) dhtmlHistory.add(active_scaffold_id+":"+page+":"+sort+":"+dir, url);
108
- }
109
-
110
- /*
111
- * Add-ons/Patches to Prototype
112
- */
113
-
114
- /* patch to support replacing TR/TD/TBODY in Internet Explorer, courtesy of http://dev.rubyonrails.org/ticket/4273 */
115
- Element.replace = function(element, html) {
116
- element = $(element);
117
- if (element.outerHTML) {
118
- try {
119
- element.outerHTML = html.stripScripts();
120
- } catch (e) {
121
- var tn = element.tagName;
122
- if(tn=='TBODY' || tn=='TR' || tn=='TD')
123
- {
124
- var tempDiv = document.createElement("div");
125
- tempDiv.innerHTML = '<table id="tempTable" style="display: none">' + html.stripScripts() + '</table>';
126
- element.parentNode.replaceChild(tempDiv.getElementsByTagName(tn).item(0), element);
127
- }
128
- else throw e;
129
- }
130
- } else {
131
- var range = element.ownerDocument.createRange();
132
- /* patch to fix <form> replaces in Firefox. see http://dev.rubyonrails.org/ticket/8010 */
133
- range.selectNodeContents(element.parentNode);
134
- element.parentNode.replaceChild(range.createContextualFragment(html.stripScripts()), element);
135
- }
136
- setTimeout(function() {html.evalScripts()}, 10);
137
- return element;
138
- };
139
-
140
- /*
141
- * URL modification support. Incomplete functionality.
142
- */
143
- Object.extend(String.prototype, {
144
- append_params: function(params) {
145
- url = this;
146
- if (url.indexOf('?') == -1) url += '?';
147
- else if (url.lastIndexOf('&') != url.length) url += '&';
148
-
149
- url += $H(params).collect(function(item) {
150
- return item.key + '=' + item.value;
151
- }).join('&');
152
-
153
- return url;
154
- }
155
- });
156
-
157
- /*
158
- * Prototype's implementation was throwing an error instead of false
159
- */
160
- Element.Methods.Simulated = {
161
- hasAttribute: function(element, attribute) {
162
- var t = Element._attributeTranslations;
163
- attribute = (t.names && t.names[attribute]) || attribute;
164
- // Return false if we get an error here
165
- try {
166
- return $(element).getAttributeNode(attribute).specified;
167
- } catch (e) {
168
- return false;
169
- }
170
- }
171
- };
172
-
173
- /**
174
- * A set of links. As a set, they can be controlled such that only one is "open" at a time, etc.
175
- */
176
- ActiveScaffold.Actions = new Object();
177
- ActiveScaffold.Actions.Abstract = Class.create({
178
- initialize: function(links, target, loading_indicator, options) {
179
- this.target = $(target);
180
- this.loading_indicator = $(loading_indicator);
181
- this.options = options;
182
- this.links = links.collect(function(link) {
183
- return this.instantiate_link(link);
184
- }.bind(this));
185
- },
186
-
187
- instantiate_link: function(link) {
188
- throw 'unimplemented'
189
- }
190
- });
191
-
192
- /**
193
- * A DataStructures::ActionLink, represented in JavaScript.
194
- * Concerned with AJAX-enabling a link and adapting the result for insertion into the table.
195
- */
196
- ActiveScaffold.ActionLink = new Object();
197
- ActiveScaffold.ActionLink.Abstract = Class.create({
198
- initialize: function(a, target, loading_indicator) {
199
- this.tag = $(a);
200
- this.url = this.tag.href;
201
- this.method = 'get';
202
- if(this.url.match('_method=delete')){
203
- this.method = 'delete';
204
- } else if(this.url.match('_method=post')){
205
- this.method = 'post';
206
- } else if(this.url.match('_method=put')){
207
- this.method = 'put';
208
- }
209
- this.target = target;
210
- this.loading_indicator = loading_indicator;
211
- this.hide_target = false;
212
- this.position = this.tag.getAttribute('position');
213
- this.page_link = this.tag.getAttribute('page_link');
214
-
215
- this.onclick = this.tag.onclick;
216
- this.tag.onclick = null;
217
- this.tag.observe('click', function(event) {
218
- this.open();
219
- Event.stop(event);
220
- }.bind(this));
221
-
222
- this.tag.action_link = this;
223
- },
224
-
225
- open: function() {
226
- if (this.is_disabled()) return;
227
-
228
- if (this.tag.hasAttribute( "dhtml_confirm")) {
229
- if (this.onclick) this.onclick();
230
- return;
231
- } else {
232
- if (this.onclick && !this.onclick()) return;//e.g. confirmation messages
233
- this.open_action();
234
- }
235
- },
236
-
237
- open_action: function() {
238
- if (this.position) this.disable();
239
-
240
- if (this.page_link) {
241
- window.location = this.url;
242
- } else {
243
- if (this.loading_indicator) this.loading_indicator.style.visibility = 'visible';
244
- new Ajax.Request(this.url, {
245
- asynchronous: true,
246
- evalScripts: true,
247
- method: this.method,
248
- onSuccess: function(request) {
249
- if (this.position) {
250
- this.insert(request.responseText);
251
- if (this.hide_target) this.target.hide();
252
- } else {
253
- request.evalResponse();
254
- }
255
- }.bind(this),
256
-
257
- onFailure: function(request) {
258
- ActiveScaffold.report_500_response(this.scaffold_id());
259
- if (this.position) this.enable()
260
- }.bind(this),
261
-
262
- onComplete: function(request) {
263
- if (this.loading_indicator) this.loading_indicator.style.visibility = 'hidden';
264
- }.bind(this)
265
- });
266
- }
267
- },
268
-
269
- insert: function(content) {
270
- throw 'unimplemented'
271
- },
272
-
273
- close: function() {
274
- this.enable();
275
- this.adapter.remove();
276
- if (this.hide_target) this.target.show();
277
- },
278
-
279
- close_handler: function(event) {
280
- this.close();
281
- if (event) Event.stop(event);
282
- },
283
-
284
- register_cancel_hooks: function() {
285
- // anything in the insert with a class of cancel gets the closer method, and a reference to this object for good measure
286
- var self = this;
287
- this.adapter.select('.cancel').each(function(elem) {
288
- elem.observe('click', this.close_handler.bind(this));
289
- elem.link = self;
290
- }.bind(this))
291
- },
292
-
293
- reload: function() {
294
- this.close();
295
- this.open();
296
- },
297
-
298
- get_new_adapter_id: function() {
299
- var id = 'adapter_';
300
- var i = 0;
301
- while ($(id + i)) i++;
302
- return id + i;
303
- },
304
-
305
- enable: function() {
306
- return this.tag.removeClassName('disabled');
307
- },
308
-
309
- disable: function() {
310
- return this.tag.addClassName('disabled');
311
- },
312
-
313
- is_disabled: function() {
314
- return this.tag.hasClassName('disabled');
315
- },
316
-
317
- scaffold_id: function() {
318
- return this.tag.up('div.active-scaffold').id;
319
- }
320
- });
321
-
322
- /**
323
- * Concrete classes for record actions
324
- */
325
- ActiveScaffold.Actions.Record = Class.create(ActiveScaffold.Actions.Abstract, {
326
- instantiate_link: function(link) {
327
- var l = new ActiveScaffold.ActionLink.Record(link, this.target, this.loading_indicator);
328
- l.refresh_url = this.options.refresh_url;
329
- if (link.hasClassName('delete')) {
330
- l.url = l.url.replace(/\/delete(\?.*)?$/, '$1');
331
- l.url = l.url.replace(/\/delete\/(.*)/, '/destroy/$1');
332
- }
333
- if (l.position) l.url = l.url.append_params({adapter: '_list_inline_adapter'});
334
- l.set = this;
335
- return l;
336
- }
337
- });
338
-
339
- ActiveScaffold.ActionLink.Record = Class.create(ActiveScaffold.ActionLink.Abstract, {
340
- close_previous_adapter: function() {
341
- this.set.links.each(function(item) {
342
- if (item.url != this.url && item.is_disabled() && item.adapter) {
343
- item.enable();
344
- item.adapter.remove();
345
- }
346
- }.bind(this));
347
- },
348
-
349
- insert: function(content) {
350
- this.close_previous_adapter();
351
-
352
- if (this.position == 'replace') {
353
- this.position = 'after';
354
- this.hide_target = true;
355
- }
356
-
357
- if (this.position == 'after') {
358
- new Insertion.After(this.target, content);
359
- this.adapter = this.target.next();
360
- }
361
- else if (this.position == 'before') {
362
- new Insertion.Before(this.target, content);
363
- this.adapter = this.target.previous();
364
- }
365
- else {
366
- return false;
367
- }
368
-
369
- this.adapter.down('a.inline-adapter-close').observe('click', this.close_handler.bind(this));
370
- this.register_cancel_hooks();
371
-
372
- this.adapter.down('td').down().highlight();
373
- },
374
-
375
- close: function($super, updatedRow) {
376
- if (updatedRow) {
377
- ActiveScaffold.update_row(this.target, updatedRow);
378
- $super();
379
- } else {
380
- new Ajax.Request(this.refresh_url, {
381
- asynchronous: true,
382
- evalScripts: true,
383
- method: this.method,
384
- onSuccess: function(request) {
385
- ActiveScaffold.update_row(this.target, request.responseText);
386
- $super();
387
- }.bind(this),
388
-
389
- onFailure: function(request) {
390
- ActiveScaffold.report_500_response(this.scaffold_id());
391
- }
392
- });
393
- }
394
- },
395
-
396
- enable: function() {
397
- this.set.links.each(function(item) {
398
- if (item.url != this.url) return;
399
- item.tag.removeClassName('disabled');
400
- }.bind(this));
401
- },
402
-
403
- disable: function() {
404
- this.set.links.each(function(item) {
405
- if (item.url != this.url) return;
406
- item.tag.addClassName('disabled');
407
- }.bind(this));
408
- }
409
- });
410
-
411
- /**
412
- * Concrete classes for table actions
413
- */
414
- ActiveScaffold.Actions.Table = Class.create(ActiveScaffold.Actions.Abstract, {
415
- instantiate_link: function(link) {
416
- var l = new ActiveScaffold.ActionLink.Table(link, this.target, this.loading_indicator);
417
- if (l.position) l.url = l.url.append_params({adapter: '_list_inline_adapter'});
418
- return l;
419
- }
420
- });
421
-
422
- ActiveScaffold.ActionLink.Table = Class.create(ActiveScaffold.ActionLink.Abstract, {
423
- insert: function(content) {
424
- if (this.position == 'top') {
425
- new Insertion.Top(this.target, content);
426
- this.adapter = this.target.immediateDescendants().first();
427
- }
428
- else {
429
- throw 'Unknown position "' + this.position + '"'
430
- }
431
-
432
- this.adapter.down('a.inline-adapter-close').observe('click', this.close_handler.bind(this));
433
- this.register_cancel_hooks();
434
-
435
- this.adapter.down('td').down().highlight();
436
- }
437
- });
438
-
439
- if (Ajax.InPlaceEditor) {
440
- ActiveScaffold.InPlaceEditor = Class.create(Ajax.InPlaceEditor, {
441
- setFieldFromAjax: function(url, options) {
442
- var ipe = this;
443
- $(ipe._controls.editor).remove();
444
- new Ajax.Request(url, {
445
- method: 'get',
446
- onComplete: function(response) {
447
- ipe._form.insert({top: response.responseText});
448
- if (options.plural) {
449
- ipe._form.getElements().each(function(el) {
450
- if (el.type != "submit" && el.type != "image") {
451
- el.name = ipe.options.paramName + '[]';
452
- el.className = 'editor_field';
453
- }
454
- });
455
- } else {
456
- var fld = ipe._form.findFirstElement();
457
- fld.name = ipe.options.paramName;
458
- fld.className = 'editor_field';
459
- if (ipe.options.submitOnBlur)
460
- fld.onblur = ipe._boundSubmitHandler;
461
- ipe._controls.editor = fld;
462
- }
463
- }
464
- });
465
- },
466
-
467
- clonePatternField: function() {
468
- var patternNodes = this.getPatternNodes(this.options.inplacePatternSelector);
469
- if (patternNodes.editNode == null) {
470
- alert('did not find any matching node for ' + this.options.editFieldSelector);
471
- return;
472
- }
473
-
474
- var fld = patternNodes.editNode.cloneNode(true);
475
- if (fld.id.length > 0) fld.id += this.options.nodeIdSuffix;
476
- fld.name = this.options.paramName;
477
- fld.className = 'editor_field';
478
- this.setValue(fld, this._controls.editor.value);
479
- if (this.options.submitOnBlur)
480
- fld.onblur = this._boundSubmitHandler;
481
- $(this._controls.editor).remove();
482
- this._controls.editor = fld;
483
- this._form.appendChild(this._controls.editor);
484
-
485
- $A(patternNodes.additionalNodes).each(function(node) {
486
- var patternNode = node.cloneNode(true);
487
- if (patternNode.id.length > 0) {
488
- patternNode.id = patternNode.id + this.options.nodeIdSuffix;
489
- }
490
- this._form.appendChild(patternNode);
491
- }.bind(this));
492
- },
493
-
494
- getPatternNodes: function(inplacePatternSelector) {
495
- var nodes = {editNode: null, additionalNodes: []};
496
- var selectedNodes = $$(inplacePatternSelector);
497
- var firstNode = selectedNodes.first();
498
-
499
- if (typeof(firstNode) !== 'undefined') {
500
- // AS inplace_edit_control_container -> we have to select all child nodes
501
- // Workaround for ie which does not support css > selector
502
- if (firstNode.className.indexOf('as_inplace_pattern') !== -1) {
503
- selectedNodes = firstNode.childElements();
504
- }
505
- nodes.editNode = selectedNodes.first();
506
- selectedNodes.shift();
507
- nodes.additionalNodes = selectedNodes;
508
- }
509
- return nodes;
510
- },
511
-
512
- setValue: function(editField, textValue) {
513
- var function_name = 'setValueFor' + editField.nodeName.toLowerCase();
514
- if (typeof(this[function_name]) == 'function') {
515
- this[function_name](editField, textValue);
516
- } else {
517
- editField.value = textValue;
518
- }
519
- },
520
-
521
- setValueForselect: function(editField, textValue) {
522
- var len = editField.options.length;
523
- var i = 0;
524
- while (i < len && editField.options[i].text != textValue) {
525
- i++;
526
- }
527
- if (i < len) {
528
- editField.value = editField.options[i].value
529
- }
530
- }
531
- });
532
- }