active_scaffold-sequel 0.3.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.
- data/CHANGELOG +179 -0
- data/MIT-LICENSE +20 -0
- data/README +36 -0
- data/app/assets/images/active_scaffold/add.gif +0 -0
- data/app/assets/images/active_scaffold/arrow_down.gif +0 -0
- data/app/assets/images/active_scaffold/arrow_up.gif +0 -0
- data/app/assets/images/active_scaffold/close.gif +0 -0
- data/app/assets/images/active_scaffold/close_touch.png +0 -0
- data/app/assets/images/active_scaffold/config.png +0 -0
- data/app/assets/images/active_scaffold/cross.png +0 -0
- data/app/assets/images/active_scaffold/gears.png +0 -0
- data/app/assets/images/active_scaffold/indicator-small.gif +0 -0
- data/app/assets/images/active_scaffold/indicator.gif +0 -0
- data/app/assets/images/active_scaffold/magnifier.png +0 -0
- data/app/assets/javascripts/active_scaffold.js.erb +19 -0
- data/app/assets/javascripts/jquery/active_scaffold.js +1057 -0
- data/app/assets/javascripts/jquery/date_picker_bridge.js.erb +24 -0
- data/app/assets/javascripts/jquery/draggable_lists.js +27 -0
- data/app/assets/javascripts/jquery/jquery.editinplace.js +743 -0
- data/app/assets/javascripts/jquery/tiny_mce_bridge.js +7 -0
- data/app/assets/javascripts/prototype/active_scaffold.js +1052 -0
- data/app/assets/javascripts/prototype/dhtml_history.js +870 -0
- data/app/assets/javascripts/prototype/form_enhancements.js +117 -0
- data/app/assets/javascripts/prototype/rico_corner.js +370 -0
- data/app/assets/javascripts/prototype/tiny_mce_bridge.js +7 -0
- data/app/assets/stylesheets/active_scaffold-ie.css +35 -0
- data/app/assets/stylesheets/active_scaffold.css.scss +14 -0
- data/app/assets/stylesheets/active_scaffold_colors.css.scss +395 -0
- data/app/assets/stylesheets/active_scaffold_extensions.css.erb +2 -0
- data/app/assets/stylesheets/active_scaffold_images.css.scss +43 -0
- data/app/assets/stylesheets/active_scaffold_layout.css +912 -0
- data/app/assets/stylesheets/blue-theme.css +74 -0
- data/config/locales/de.yml +114 -0
- data/config/locales/en.yml +118 -0
- data/config/locales/es.yml +120 -0
- data/config/locales/fr.yml +121 -0
- data/config/locales/hu.yml +74 -0
- data/config/locales/ja.yml +73 -0
- data/config/locales/ru.yml +123 -0
- data/frontends/default/views/_action_group.html.erb +24 -0
- data/frontends/default/views/_add_existing_form.html.erb +30 -0
- data/frontends/default/views/_base_form.html.erb +51 -0
- data/frontends/default/views/_create_form.html.erb +8 -0
- data/frontends/default/views/_create_form_on_list.html.erb +6 -0
- data/frontends/default/views/_field_search.html.erb +32 -0
- data/frontends/default/views/_form.html.erb +24 -0
- data/frontends/default/views/_form_association.html.erb +15 -0
- data/frontends/default/views/_form_association_footer.html.erb +47 -0
- data/frontends/default/views/_form_attribute.html.erb +20 -0
- data/frontends/default/views/_form_hidden_attribute.html.erb +2 -0
- data/frontends/default/views/_form_messages.html.erb +5 -0
- data/frontends/default/views/_horizontal_subform.html.erb +28 -0
- data/frontends/default/views/_horizontal_subform_footer.html.erb +0 -0
- data/frontends/default/views/_horizontal_subform_header.html.erb +11 -0
- data/frontends/default/views/_horizontal_subform_record.html.erb +38 -0
- data/frontends/default/views/_human_conditions.html.erb +1 -0
- data/frontends/default/views/_list.html.erb +18 -0
- data/frontends/default/views/_list_actions.html.erb +15 -0
- data/frontends/default/views/_list_calculations.html.erb +16 -0
- data/frontends/default/views/_list_column_headings.html.erb +12 -0
- data/frontends/default/views/_list_header.html.erb +10 -0
- data/frontends/default/views/_list_inline_adapter.html.erb +10 -0
- data/frontends/default/views/_list_messages.html.erb +30 -0
- data/frontends/default/views/_list_pagination.html.erb +11 -0
- data/frontends/default/views/_list_pagination_links.html.erb +9 -0
- data/frontends/default/views/_list_record.html.erb +14 -0
- data/frontends/default/views/_list_record_columns.html.erb +8 -0
- data/frontends/default/views/_list_with_header.html.erb +36 -0
- data/frontends/default/views/_messages.html.erb +10 -0
- data/frontends/default/views/_render_field.js.erb +20 -0
- data/frontends/default/views/_row.html.erb +6 -0
- data/frontends/default/views/_search.html.erb +34 -0
- data/frontends/default/views/_search_attribute.html.erb +10 -0
- data/frontends/default/views/_show.html.erb +8 -0
- data/frontends/default/views/_show_columns.html.erb +15 -0
- data/frontends/default/views/_update_actions.html.erb +9 -0
- data/frontends/default/views/_update_form.html.erb +6 -0
- data/frontends/default/views/_vertical_subform.html.erb +12 -0
- data/frontends/default/views/_vertical_subform_record.html.erb +38 -0
- data/frontends/default/views/action_confirmation.html.erb +13 -0
- data/frontends/default/views/add_existing.js.erb +18 -0
- data/frontends/default/views/add_existing_form.html.erb +5 -0
- data/frontends/default/views/create.html.erb +5 -0
- data/frontends/default/views/delete.html.erb +13 -0
- data/frontends/default/views/destroy.js.erb +24 -0
- data/frontends/default/views/edit_associated.js.erb +12 -0
- data/frontends/default/views/field_search.html.erb +5 -0
- data/frontends/default/views/form_messages.js.erb +1 -0
- data/frontends/default/views/list.html.erb +1 -0
- data/frontends/default/views/on_action_update.js.erb +13 -0
- data/frontends/default/views/on_create.js.erb +47 -0
- data/frontends/default/views/on_mark_all.js.erb +12 -0
- data/frontends/default/views/on_update.js.erb +31 -0
- data/frontends/default/views/refresh_list.js.erb +1 -0
- data/frontends/default/views/render_field.js.erb +1 -0
- data/frontends/default/views/search.html.erb +5 -0
- data/frontends/default/views/show.html.erb +5 -0
- data/frontends/default/views/update.html.erb +8 -0
- data/frontends/default/views/update_column.js.erb +16 -0
- data/frontends/default/views/update_row.js.erb +1 -0
- data/lib/active_scaffold/actions/common_search.rb +25 -0
- data/lib/active_scaffold/actions/core.rb +197 -0
- data/lib/active_scaffold/actions/create.rb +148 -0
- data/lib/active_scaffold/actions/delete.rb +76 -0
- data/lib/active_scaffold/actions/field_search.rb +82 -0
- data/lib/active_scaffold/actions/list.rb +196 -0
- data/lib/active_scaffold/actions/mark.rb +75 -0
- data/lib/active_scaffold/actions/nested.rb +245 -0
- data/lib/active_scaffold/actions/search.rb +48 -0
- data/lib/active_scaffold/actions/show.rb +61 -0
- data/lib/active_scaffold/actions/subform.rb +23 -0
- data/lib/active_scaffold/actions/update.rb +150 -0
- data/lib/active_scaffold/active_record_permissions.rb +136 -0
- data/lib/active_scaffold/attribute_params.rb +208 -0
- data/lib/active_scaffold/bridges/ancestry/ancestry_bridge.rb +39 -0
- data/lib/active_scaffold/bridges/ancestry.rb +5 -0
- data/lib/active_scaffold/bridges/calendar_date_select/as_cds_bridge.rb +67 -0
- data/lib/active_scaffold/bridges/calendar_date_select.rb +24 -0
- data/lib/active_scaffold/bridges/cancan/cancan_bridge.rb +107 -0
- data/lib/active_scaffold/bridges/cancan.rb +15 -0
- data/lib/active_scaffold/bridges/carrierwave/carrierwave_bridge.rb +31 -0
- data/lib/active_scaffold/bridges/carrierwave/carrierwave_bridge_helpers.rb +10 -0
- data/lib/active_scaffold/bridges/carrierwave/form_ui.rb +45 -0
- data/lib/active_scaffold/bridges/carrierwave/list_ui.rb +17 -0
- data/lib/active_scaffold/bridges/carrierwave.rb +12 -0
- data/lib/active_scaffold/bridges/country_helper/country_helper_bridge.rb +358 -0
- data/lib/active_scaffold/bridges/country_helper.rb +9 -0
- data/lib/active_scaffold/bridges/date_picker/ext.rb +45 -0
- data/lib/active_scaffold/bridges/date_picker/helper.rb +180 -0
- data/lib/active_scaffold/bridges/date_picker.rb +23 -0
- data/lib/active_scaffold/bridges/dragonfly/dragonfly_bridge.rb +34 -0
- data/lib/active_scaffold/bridges/dragonfly/dragonfly_bridge_helpers.rb +10 -0
- data/lib/active_scaffold/bridges/dragonfly/form_ui.rb +27 -0
- data/lib/active_scaffold/bridges/dragonfly/list_ui.rb +16 -0
- data/lib/active_scaffold/bridges/dragonfly.rb +9 -0
- data/lib/active_scaffold/bridges/file_column/as_file_column_bridge.rb +48 -0
- data/lib/active_scaffold/bridges/file_column/file_column_helpers.rb +57 -0
- data/lib/active_scaffold/bridges/file_column/form_ui.rb +34 -0
- data/lib/active_scaffold/bridges/file_column/list_ui.rb +26 -0
- data/lib/active_scaffold/bridges/file_column/test/functional/file_column_keep_test.rb +43 -0
- data/lib/active_scaffold/bridges/file_column/test/mock_model.rb +9 -0
- data/lib/active_scaffold/bridges/file_column/test/test_helper.rb +15 -0
- data/lib/active_scaffold/bridges/file_column.rb +11 -0
- data/lib/active_scaffold/bridges/paperclip/form_ui.rb +27 -0
- data/lib/active_scaffold/bridges/paperclip/list_ui.rb +16 -0
- data/lib/active_scaffold/bridges/paperclip/paperclip_bridge.rb +36 -0
- data/lib/active_scaffold/bridges/paperclip/paperclip_bridge_helpers.rb +24 -0
- data/lib/active_scaffold/bridges/paperclip.rb +12 -0
- data/lib/active_scaffold/bridges/record_select/helpers.rb +86 -0
- data/lib/active_scaffold/bridges/record_select.rb +11 -0
- data/lib/active_scaffold/bridges/semantic_attributes/column.rb +20 -0
- data/lib/active_scaffold/bridges/semantic_attributes.rb +5 -0
- data/lib/active_scaffold/bridges/shared/date_bridge.rb +209 -0
- data/lib/active_scaffold/bridges/tiny_mce/helpers.rb +46 -0
- data/lib/active_scaffold/bridges/tiny_mce.rb +17 -0
- data/lib/active_scaffold/bridges.rb +61 -0
- data/lib/active_scaffold/config/base.rb +71 -0
- data/lib/active_scaffold/config/core.rb +219 -0
- data/lib/active_scaffold/config/create.rb +44 -0
- data/lib/active_scaffold/config/delete.rb +33 -0
- data/lib/active_scaffold/config/field_search.rb +76 -0
- data/lib/active_scaffold/config/form.rb +48 -0
- data/lib/active_scaffold/config/list.rb +196 -0
- data/lib/active_scaffold/config/mark.rb +35 -0
- data/lib/active_scaffold/config/nested.rb +42 -0
- data/lib/active_scaffold/config/search.rb +73 -0
- data/lib/active_scaffold/config/show.rb +32 -0
- data/lib/active_scaffold/config/subform.rb +35 -0
- data/lib/active_scaffold/config/update.rb +41 -0
- data/lib/active_scaffold/configurable.rb +29 -0
- data/lib/active_scaffold/constraints.rb +170 -0
- data/lib/active_scaffold/data_structures/action_columns.rb +140 -0
- data/lib/active_scaffold/data_structures/action_link.rb +179 -0
- data/lib/active_scaffold/data_structures/action_links.rb +185 -0
- data/lib/active_scaffold/data_structures/actions.rb +45 -0
- data/lib/active_scaffold/data_structures/bridge.rb +22 -0
- data/lib/active_scaffold/data_structures/column.rb +389 -0
- data/lib/active_scaffold/data_structures/columns.rb +75 -0
- data/lib/active_scaffold/data_structures/error_message.rb +24 -0
- data/lib/active_scaffold/data_structures/nested_info.rb +130 -0
- data/lib/active_scaffold/data_structures/set.rb +57 -0
- data/lib/active_scaffold/data_structures/sorting.rb +172 -0
- data/lib/active_scaffold/engine.rb +4 -0
- data/lib/active_scaffold/extensions/action_controller_rendering.rb +22 -0
- data/lib/active_scaffold/extensions/action_view_rendering.rb +115 -0
- data/lib/active_scaffold/extensions/active_record_offset.rb +12 -0
- data/lib/active_scaffold/extensions/array.rb +7 -0
- data/lib/active_scaffold/extensions/cache_association.rb +16 -0
- data/lib/active_scaffold/extensions/localize.rb +10 -0
- data/lib/active_scaffold/extensions/name_option_for_datetime.rb +12 -0
- data/lib/active_scaffold/extensions/nil_id_in_url_params.rb +7 -0
- data/lib/active_scaffold/extensions/paginator_extensions.rb +26 -0
- data/lib/active_scaffold/extensions/routing_mapper.rb +48 -0
- data/lib/active_scaffold/extensions/to_label.rb +8 -0
- data/lib/active_scaffold/extensions/unsaved_associated.rb +60 -0
- data/lib/active_scaffold/extensions/unsaved_record.rb +20 -0
- data/lib/active_scaffold/extensions/usa_state.rb +46 -0
- data/lib/active_scaffold/finder.rb +372 -0
- data/lib/active_scaffold/helpers/association_helpers.rb +48 -0
- data/lib/active_scaffold/helpers/controller_helpers.rb +88 -0
- data/lib/active_scaffold/helpers/form_column_helpers.rb +321 -0
- data/lib/active_scaffold/helpers/human_condition_helpers.rb +62 -0
- data/lib/active_scaffold/helpers/id_helpers.rb +127 -0
- data/lib/active_scaffold/helpers/list_column_helpers.rb +340 -0
- data/lib/active_scaffold/helpers/pagination_helpers.rb +55 -0
- data/lib/active_scaffold/helpers/search_column_helpers.rb +267 -0
- data/lib/active_scaffold/helpers/show_column_helpers.rb +50 -0
- data/lib/active_scaffold/helpers/view_helpers.rb +342 -0
- data/lib/active_scaffold/marked_model.rb +38 -0
- data/lib/active_scaffold/paginator.rb +136 -0
- data/lib/active_scaffold/responds_to_parent.rb +70 -0
- data/lib/active_scaffold/version.rb +9 -0
- data/lib/active_scaffold.rb +368 -0
- data/lib/active_scaffold_env.rb +11 -0
- data/lib/generators/active_scaffold/USAGE +29 -0
- data/lib/generators/active_scaffold/active_scaffold_generator.rb +20 -0
- data/lib/generators/active_scaffold_controller/USAGE +19 -0
- data/lib/generators/active_scaffold_controller/active_scaffold_controller_generator.rb +29 -0
- data/lib/generators/active_scaffold_controller/templates/controller.rb +4 -0
- data/lib/generators/active_scaffold_controller/templates/helper.rb +2 -0
- data/public/blank.html +33 -0
- data/shoulda_macros/macros.rb +136 -0
- data/test/bridges/active_scaffold_dependent_protect_test.rb +34 -0
- data/test/bridges/bridge_test.rb +90 -0
- data/test/bridges/company.rb +81 -0
- data/test/bridges/paperclip_test.rb +68 -0
- data/test/bridges/tiny_mce_test.rb +27 -0
- data/test/bridges/unobtrusive_date_picker_test.rb +49 -0
- data/test/bridges/validation_reflection_test.rb +57 -0
- data/test/config/base_test.rb +15 -0
- data/test/config/core_test.rb +58 -0
- data/test/config/create_test.rb +58 -0
- data/test/config/delete_test.rb +33 -0
- data/test/config/field_search_test.rb +47 -0
- data/test/config/list_test.rb +129 -0
- data/test/config/nested_test.rb +62 -0
- data/test/config/search_test.rb +60 -0
- data/test/config/show_test.rb +43 -0
- data/test/config/subform_test.rb +17 -0
- data/test/config/update_test.rb +40 -0
- data/test/const_mocker.rb +36 -0
- data/test/data_structures/action_columns_test.rb +113 -0
- data/test/data_structures/action_link_test.rb +78 -0
- data/test/data_structures/action_links_test.rb +78 -0
- data/test/data_structures/actions_test.rb +25 -0
- data/test/data_structures/association_column_test.rb +42 -0
- data/test/data_structures/column_test.rb +185 -0
- data/test/data_structures/columns_test.rb +69 -0
- data/test/data_structures/error_message_test.rb +28 -0
- data/test/data_structures/set_test.rb +86 -0
- data/test/data_structures/sorting_test.rb +126 -0
- data/test/data_structures/standard_column_test.rb +24 -0
- data/test/data_structures/virtual_column_test.rb +23 -0
- data/test/extensions/active_record_test.rb +45 -0
- data/test/extensions/array_test.rb +12 -0
- data/test/helpers/form_column_helpers_test.rb +31 -0
- data/test/helpers/list_column_helpers_test.rb +42 -0
- data/test/helpers/pagination_helpers_test.rb +59 -0
- data/test/misc/active_record_permissions_test.rb +154 -0
- data/test/misc/attribute_params_test.rb +146 -0
- data/test/misc/configurable_test.rb +96 -0
- data/test/misc/constraints_test.rb +193 -0
- data/test/misc/finder_test.rb +92 -0
- data/test/misc/lang_test.rb +11 -0
- data/test/mock_app/app/controllers/application_controller.rb +10 -0
- data/test/mock_app/app/helpers/application_helper.rb +3 -0
- data/test/mock_app/config/boot.rb +110 -0
- data/test/mock_app/config/database.yml +16 -0
- data/test/mock_app/config/environment.rb +43 -0
- data/test/mock_app/config/environments/development.rb +17 -0
- data/test/mock_app/config/environments/production.rb +28 -0
- data/test/mock_app/config/environments/test.rb +28 -0
- data/test/mock_app/config/initializers/backtrace_silencers.rb +7 -0
- data/test/mock_app/config/initializers/inflections.rb +10 -0
- data/test/mock_app/config/initializers/mime_types.rb +5 -0
- data/test/mock_app/config/initializers/new_rails_defaults.rb +19 -0
- data/test/mock_app/config/initializers/session_store.rb +15 -0
- data/test/mock_app/config/locales/en.yml +5 -0
- data/test/mock_app/config/routes.rb +43 -0
- data/test/mock_app/db/test.sqlite3 +1 -0
- data/test/mock_app/public/blank.html +33 -0
- data/test/mock_app/public/images/active_scaffold/DO_NOT_EDIT +2 -0
- data/test/mock_app/public/images/active_scaffold/default/add.gif +0 -0
- data/test/mock_app/public/images/active_scaffold/default/arrow_down.gif +0 -0
- data/test/mock_app/public/images/active_scaffold/default/arrow_up.gif +0 -0
- data/test/mock_app/public/images/active_scaffold/default/close.gif +0 -0
- data/test/mock_app/public/images/active_scaffold/default/cross.png +0 -0
- data/test/mock_app/public/images/active_scaffold/default/indicator-small.gif +0 -0
- data/test/mock_app/public/images/active_scaffold/default/indicator.gif +0 -0
- data/test/mock_app/public/images/active_scaffold/default/magnifier.png +0 -0
- data/test/mock_app/public/javascripts/active_scaffold/DO_NOT_EDIT +2 -0
- data/test/mock_app/public/javascripts/active_scaffold/default/active_scaffold.js +532 -0
- data/test/mock_app/public/javascripts/active_scaffold/default/dhtml_history.js +867 -0
- data/test/mock_app/public/javascripts/active_scaffold/default/form_enhancements.js +117 -0
- data/test/mock_app/public/javascripts/active_scaffold/default/rico_corner.js +370 -0
- data/test/mock_app/public/stylesheets/active_scaffold/DO_NOT_EDIT +2 -0
- data/test/mock_app/public/stylesheets/active_scaffold/default/stylesheet-ie.css +35 -0
- data/test/mock_app/public/stylesheets/active_scaffold/default/stylesheet.css +848 -0
- data/test/model_stub.rb +55 -0
- data/test/run_all.rb +8 -0
- data/test/test_helper.rb +39 -0
- data/vendor/assets/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
- data/vendor/assets/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
- data/vendor/assets/images/ui-bg_flat_10_000000_40x100.png +0 -0
- data/vendor/assets/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
- data/vendor/assets/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
- data/vendor/assets/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/vendor/assets/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
- data/vendor/assets/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
- data/vendor/assets/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
- data/vendor/assets/images/ui-icons_222222_256x240.png +0 -0
- data/vendor/assets/images/ui-icons_228ef1_256x240.png +0 -0
- data/vendor/assets/images/ui-icons_ef8c08_256x240.png +0 -0
- data/vendor/assets/images/ui-icons_ffd27a_256x240.png +0 -0
- data/vendor/assets/images/ui-icons_ffffff_256x240.png +0 -0
- data/vendor/assets/javascripts/jquery-ui-timepicker-addon.js +1276 -0
- data/vendor/assets/stylesheets/jquery-ui.css +568 -0
- metadata +502 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
module ActiveScaffold::DataStructures
|
|
2
|
+
# encapsulates the column sorting configuration for the List view
|
|
3
|
+
class Sorting
|
|
4
|
+
def initialize(columns)
|
|
5
|
+
# a ActiveScaffold::DataStructures::Columns instance
|
|
6
|
+
@columns = columns
|
|
7
|
+
|
|
8
|
+
# @clauses is an array of pairs: [[column, params], ...]
|
|
9
|
+
# where 'column' is a ActiveScaffold::DataStructures::Column instance and
|
|
10
|
+
# 'params' is a hash with :table, :column, :descending keys
|
|
11
|
+
@clauses = []
|
|
12
|
+
|
|
13
|
+
# hash: 'column name'.to_sym => 'index to @clauses array'.to_i
|
|
14
|
+
@cindex = {}
|
|
15
|
+
|
|
16
|
+
# synchronize access to @cindex and @clauses
|
|
17
|
+
@mutex = Mutex.new
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def set_default_sorting(model)
|
|
21
|
+
order_clauses = model.dataset.opts[:order]
|
|
22
|
+
|
|
23
|
+
# If an ORDER BY clause is found set default sorting according to it, else
|
|
24
|
+
# fallback to setting primary key ordering
|
|
25
|
+
if order_clauses
|
|
26
|
+
# we are going to return nil from 'self.clause', but the @clauses need to be set for determining the sorting properties for view
|
|
27
|
+
set_sorting_from_order_clause(order_clauses, model.table_name)
|
|
28
|
+
@default_sorting = true
|
|
29
|
+
else
|
|
30
|
+
set(model.primary_key) if model.primary_key
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def set_nested_sorting(table_name, order_clause)
|
|
35
|
+
clear
|
|
36
|
+
set_sorting_from_order_clause(order_clause, table_name)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# add a clause to the sorting, assuming the column is sortable
|
|
40
|
+
def add(order, params = nil)
|
|
41
|
+
params = extract_order_params(order) unless params
|
|
42
|
+
column = get_column(params[:column])
|
|
43
|
+
raise ArgumentError, "Could not find column #{params[:column]} for #{order.inspect}" if column.nil?
|
|
44
|
+
if column.sortable?
|
|
45
|
+
@mutex.synchronize do
|
|
46
|
+
@clauses << [column, params]
|
|
47
|
+
@cindex[params[:column]] = @clauses.count - 1
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
raise ArgumentError, "Can't mix :method- and :sql-based sorting" if mixed_sorting?
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def set(*args)
|
|
54
|
+
clear
|
|
55
|
+
args.each {|a| add(a)}
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# clears the sorting
|
|
59
|
+
def clear
|
|
60
|
+
@mutex.synchronize do
|
|
61
|
+
@default_sorting = false
|
|
62
|
+
@clauses = []
|
|
63
|
+
@cindex = {}
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# checks whether the given column (a Column object or a column name) is in the sorting
|
|
68
|
+
def sorts_on?(column)
|
|
69
|
+
!get_clause(column).nil?
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def direction_of(column)
|
|
73
|
+
c = @mutex.synchronize do
|
|
74
|
+
i = @cindex[(column.respond_to?(:name) ? column.name : column)]
|
|
75
|
+
@clauses[i] if i
|
|
76
|
+
end
|
|
77
|
+
if c
|
|
78
|
+
c[1][:descending] ? 'DESC' : 'ASC'
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# checks whether any column is configured to sort by method (using a proc)
|
|
83
|
+
def sorts_by_method?
|
|
84
|
+
@clauses.any? { |sorting| sorting[0].sort.is_a? Hash and sorting[0].sort.has_key? :method }
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def sorts_by_sql?
|
|
88
|
+
@clauses.any? { |sorting| sorting[0].sort.is_a? Hash and sorting[0].sort.has_key? :sql }
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# provides quick access to the first (and sometimes only) clause
|
|
92
|
+
def first
|
|
93
|
+
@clauses.first
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# builds an order-by clause
|
|
97
|
+
def clause
|
|
98
|
+
return nil if sorts_by_method? || default_sorting?
|
|
99
|
+
@clauses.collect do |column,params|
|
|
100
|
+
if column.sort[:sql]
|
|
101
|
+
order = *column.sort[:sql]
|
|
102
|
+
order = order.collect {|o| o.respond_to?(:invert) ? o.invert : o.desc} if params[:descending]
|
|
103
|
+
order
|
|
104
|
+
end
|
|
105
|
+
end.flatten.compact
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
protected
|
|
109
|
+
|
|
110
|
+
# retrieves the sorting clause for the given column
|
|
111
|
+
def get_clause(column)
|
|
112
|
+
@mutex.synchronize do
|
|
113
|
+
i = @cindex[(column.respond_to?(:name) ? column.name : column)]
|
|
114
|
+
@clauses[i] if i
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# possibly converts the given argument into a column object from @columns (if it's not already)
|
|
119
|
+
def get_column(name_or_column)
|
|
120
|
+
# it's a column
|
|
121
|
+
return name_or_column if name_or_column.is_a? ActiveScaffold::DataStructures::Column
|
|
122
|
+
# it's a name
|
|
123
|
+
return @columns[name_or_column]
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def mixed_sorting?
|
|
127
|
+
sorts_by_method? and sorts_by_sql?
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def default_sorting?
|
|
131
|
+
@default_sorting
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def set_sorting_from_order_clause(order_clauses, model_table_name = nil)
|
|
135
|
+
clear
|
|
136
|
+
order_clauses.each do |criterion|
|
|
137
|
+
params = extract_order_params(criterion)
|
|
138
|
+
add(criterion, params) unless different_table?(model_table_name, params[:table])
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def get_table_column(tcol)
|
|
143
|
+
table, column = tcol.to_s.split('__')
|
|
144
|
+
if column
|
|
145
|
+
[table.to_sym, column.to_sym]
|
|
146
|
+
else
|
|
147
|
+
[nil, table.to_sym]
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def extract_order_params(criterion)
|
|
152
|
+
if criterion.respond_to?(:expression) and criterion.respond_to?(:descending) # Sequel::SQL::OrderedExpression
|
|
153
|
+
expression = criterion.expression
|
|
154
|
+
if expression.respond_to?(:table) and expression.respond_to?(:column) # Sequel::SQL::QualifiedIdentifier
|
|
155
|
+
table = expression.table
|
|
156
|
+
column = expression.column
|
|
157
|
+
else
|
|
158
|
+
table, column = get_table_column(expression)
|
|
159
|
+
end
|
|
160
|
+
descending = criterion.descending
|
|
161
|
+
else
|
|
162
|
+
table, column = get_table_column(criterion)
|
|
163
|
+
descending = false
|
|
164
|
+
end
|
|
165
|
+
{:table => table, :column => column, :descending => descending}
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def different_table?(model_table_name, order_table_name)
|
|
169
|
+
model_table_name and order_table_name and model_table_name != order_table_name
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# wrap the action rendering for ActiveScaffold controllers
|
|
2
|
+
module ActionController #:nodoc:
|
|
3
|
+
class Base
|
|
4
|
+
def render_with_active_scaffold(*args, &block)
|
|
5
|
+
if self.class.uses_active_scaffold? and params[:adapter] and @rendering_adapter.nil?
|
|
6
|
+
@rendering_adapter = true # recursion control
|
|
7
|
+
# if we need an adapter, then we render the actual stuff to a string and insert it into the adapter template
|
|
8
|
+
opts = args.blank? ? Hash.new : args.first
|
|
9
|
+
render :partial => params[:adapter][1..-1],
|
|
10
|
+
:locals => {:payload => render_to_string(opts.merge(:layout => false), &block).html_safe},
|
|
11
|
+
:use_full_path => true, :layout => false, :content_type => :html
|
|
12
|
+
@rendering_adapter = nil # recursion control
|
|
13
|
+
else
|
|
14
|
+
render_without_active_scaffold(*args, &block)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
alias_method_chain :render, :active_scaffold
|
|
18
|
+
|
|
19
|
+
# Rails 2.x implementation is post-initialization on :active_scaffold method
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
module ActionView
|
|
2
|
+
class LookupContext
|
|
3
|
+
module ViewPaths
|
|
4
|
+
def find_all_templates(name, partial = false, locals = {})
|
|
5
|
+
prefixes.collect do |prefix|
|
|
6
|
+
view_paths.collect do |resolver|
|
|
7
|
+
if Rails.version < '3.2.0' # FIXME: remove when rails 3.1 support is dropped
|
|
8
|
+
temp_args = *args_for_lookup(name, [prefix], partial, locals)
|
|
9
|
+
else
|
|
10
|
+
temp_args = *args_for_lookup(name, [prefix], partial, locals, {})
|
|
11
|
+
end
|
|
12
|
+
temp_args[1] = temp_args[1][0]
|
|
13
|
+
resolver.find_all(*temp_args)
|
|
14
|
+
end
|
|
15
|
+
end.flatten!
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# wrap the action rendering for ActiveScaffold views
|
|
22
|
+
module ActionView::Helpers #:nodoc:
|
|
23
|
+
module RenderingHelper
|
|
24
|
+
#
|
|
25
|
+
# Adds two rendering options.
|
|
26
|
+
#
|
|
27
|
+
# ==render :super
|
|
28
|
+
#
|
|
29
|
+
# This syntax skips all template overrides and goes directly to the provided ActiveScaffold templates.
|
|
30
|
+
# Useful if you want to wrap an existing template. Just call super!
|
|
31
|
+
#
|
|
32
|
+
# ==render :active_scaffold => #{controller.to_s}, options = {}+
|
|
33
|
+
#
|
|
34
|
+
# Lets you embed an ActiveScaffold by referencing the controller where it's configured.
|
|
35
|
+
#
|
|
36
|
+
# You may specify options[:constraints] for the embedded scaffold. These constraints have three effects:
|
|
37
|
+
# * the scaffold's only displays records matching the constraint
|
|
38
|
+
# * all new records created will be assigned the constrained values
|
|
39
|
+
# * constrained columns will be hidden (they're pretty boring at this point)
|
|
40
|
+
#
|
|
41
|
+
# You may also specify options[:conditions] for the embedded scaffold. These only do 1/3 of what
|
|
42
|
+
# constraints do (they only limit search results). Any format accepted by Sequel::Model.find is valid.
|
|
43
|
+
#
|
|
44
|
+
# Defining options[:label] lets you completely customize the list title for the embedded scaffold.
|
|
45
|
+
#
|
|
46
|
+
def render_with_active_scaffold(*args, &block)
|
|
47
|
+
if args.first == :super
|
|
48
|
+
last_view = view_stack.last || {:view => instance_variable_get(:@virtual_path).split('/').last}
|
|
49
|
+
options = args[1] || {}
|
|
50
|
+
options[:locals] ||= {}
|
|
51
|
+
options[:locals].reverse_merge!(last_view[:locals] || {})
|
|
52
|
+
if last_view[:templates].nil?
|
|
53
|
+
last_view[:templates] = lookup_context.find_all_templates(last_view[:view], last_view[:partial], options[:locals].keys)
|
|
54
|
+
last_view[:templates].shift
|
|
55
|
+
end
|
|
56
|
+
options[:template] = last_view[:templates].shift
|
|
57
|
+
view_stack << last_view
|
|
58
|
+
result = render_without_active_scaffold options
|
|
59
|
+
view_stack.pop
|
|
60
|
+
result
|
|
61
|
+
elsif args.first.is_a? Hash and args.first[:active_scaffold]
|
|
62
|
+
require 'digest/md5'
|
|
63
|
+
options = args.first
|
|
64
|
+
|
|
65
|
+
remote_controller = options[:active_scaffold]
|
|
66
|
+
constraints = options[:constraints]
|
|
67
|
+
conditions = options[:conditions]
|
|
68
|
+
eid = Digest::MD5.hexdigest(params[:controller] + remote_controller.to_s + constraints.to_s + conditions.to_s)
|
|
69
|
+
session["as:#{eid}"] = {:constraints => constraints, :conditions => conditions, :list => {:label => args.first[:label]}}
|
|
70
|
+
options[:params] ||= {}
|
|
71
|
+
options[:params].merge! :eid => eid, :embedded => true
|
|
72
|
+
|
|
73
|
+
id = "as_#{eid}-embedded"
|
|
74
|
+
url_options = {:controller => remote_controller.to_s, :action => 'index'}.merge(options[:params])
|
|
75
|
+
|
|
76
|
+
if controller.respond_to?(:render_component_into_view)
|
|
77
|
+
controller.send(:render_component_into_view, url_options)
|
|
78
|
+
else
|
|
79
|
+
content_tag(:div, :id => id, :class => 'active-scaffold-component') do
|
|
80
|
+
url = url_for(url_options)
|
|
81
|
+
# parse the ActiveRecord model name from the controller path, which
|
|
82
|
+
# might be a namespaced controller (e.g., 'admin/admins')
|
|
83
|
+
model = remote_controller.to_s.sub(/.*\//, '').singularize
|
|
84
|
+
content_tag(:div, :class => 'active-scaffold-header') do
|
|
85
|
+
content_tag :h2, link_to(args.first[:label] || active_scaffold_config_for(model).list.label, url, :remote => true)
|
|
86
|
+
end <<
|
|
87
|
+
if ActiveScaffold.js_framework == :prototype
|
|
88
|
+
javascript_tag("new Ajax.Updater('#{id}', '#{url}', {method: 'get', evalScripts: true});")
|
|
89
|
+
elsif ActiveScaffold.js_framework == :jquery
|
|
90
|
+
javascript_tag("jQuery('##{id}').load('#{url}');")
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
else
|
|
96
|
+
options = args.first
|
|
97
|
+
if options.is_a?(Hash)
|
|
98
|
+
current_view = {:view => options[:partial], :partial => true} if options[:partial]
|
|
99
|
+
current_view = {:view => options[:template], :partial => false} if current_view.nil? && options[:template]
|
|
100
|
+
current_view[:locals] = options[:locals] if !current_view.nil? && options[:locals]
|
|
101
|
+
view_stack << current_view if current_view.present?
|
|
102
|
+
end
|
|
103
|
+
result = render_without_active_scaffold(*args, &block)
|
|
104
|
+
view_stack.pop if current_view.present?
|
|
105
|
+
result
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
alias_method_chain :render, :active_scaffold
|
|
109
|
+
|
|
110
|
+
def view_stack
|
|
111
|
+
@_view_stack ||= []
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
end
|
|
115
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
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
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
class Object
|
|
2
|
+
def as_(key, options = {})
|
|
3
|
+
unless key.blank?
|
|
4
|
+
text = I18n.translate "#{key}", {:scope => [:active_scaffold], :default => key.is_a?(String) ? key : key.to_s.titleize}.merge(options)
|
|
5
|
+
# text = nil if text.include?('translation missing:')
|
|
6
|
+
end
|
|
7
|
+
text ||= key
|
|
8
|
+
text
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module ActionView
|
|
2
|
+
module Helpers
|
|
3
|
+
class InstanceTag
|
|
4
|
+
private
|
|
5
|
+
def datetime_selector_with_name(options, html_options)
|
|
6
|
+
options.merge!(:prefix => options[:name].gsub(/\[[^\[]*\]$/,'')) if options[:name]
|
|
7
|
+
datetime_selector_without_name(options, html_options)
|
|
8
|
+
end
|
|
9
|
+
alias_method_chain :datetime_selector, :name
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require 'active_scaffold/paginator'
|
|
2
|
+
|
|
3
|
+
class ActiveScaffold::Paginator
|
|
4
|
+
|
|
5
|
+
# Total number of pages
|
|
6
|
+
def number_of_pages_with_infinite
|
|
7
|
+
number_of_pages_without_infinite unless infinite?
|
|
8
|
+
end
|
|
9
|
+
alias_method_chain :number_of_pages, :infinite
|
|
10
|
+
|
|
11
|
+
# Is this an "infinite" paginator
|
|
12
|
+
def infinite?
|
|
13
|
+
@count.nil?
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
class Page
|
|
17
|
+
# Checks to see if there's a page after this one
|
|
18
|
+
def next_with_infinite?
|
|
19
|
+
return true if @pager.infinite?
|
|
20
|
+
next_without_infinite?
|
|
21
|
+
end
|
|
22
|
+
alias_method_chain :next?, :infinite
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end
|
|
26
|
+
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module ActionDispatch
|
|
2
|
+
module Routing
|
|
3
|
+
ACTIVE_SCAFFOLD_CORE_ROUTING = {
|
|
4
|
+
:collection => {:show_search => :get, :render_field => :get},
|
|
5
|
+
:member => {:row => :get, :update_column => :post, :render_field => :get}
|
|
6
|
+
}
|
|
7
|
+
ACTIVE_SCAFFOLD_ASSOCIATION_ROUTING = {
|
|
8
|
+
:collection => {:edit_associated => :get, :new_existing => :get, :add_existing => :post},
|
|
9
|
+
:member => {:edit_associated => :get, :add_association => :get, :destroy_existing => :delete}
|
|
10
|
+
}
|
|
11
|
+
class Mapper
|
|
12
|
+
module Base
|
|
13
|
+
def as_routes(options = {:association => true})
|
|
14
|
+
collection do
|
|
15
|
+
ActionDispatch::Routing::ACTIVE_SCAFFOLD_CORE_ROUTING[:collection].each {|name, type| send(type, name)}
|
|
16
|
+
end
|
|
17
|
+
member do
|
|
18
|
+
ActionDispatch::Routing::ACTIVE_SCAFFOLD_CORE_ROUTING[:member].each {|name, type| send(type, name)}
|
|
19
|
+
end
|
|
20
|
+
as_association_routes if options[:association]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def as_association_routes
|
|
24
|
+
collection do
|
|
25
|
+
ActionDispatch::Routing::ACTIVE_SCAFFOLD_ASSOCIATION_ROUTING[:collection].each {|name, type| send(type, name)}
|
|
26
|
+
end
|
|
27
|
+
member do
|
|
28
|
+
ActionDispatch::Routing::ACTIVE_SCAFFOLD_ASSOCIATION_ROUTING[:member].each {|name, type| send(type, name)}
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def as_nested_resources(*resources)
|
|
33
|
+
options = resources.extract_options!
|
|
34
|
+
resources.each do |resource|
|
|
35
|
+
resources(resource, options.merge(:parent_scaffold => merge_module_scope(@scope[:module], parent_resource.plural), :association => resource)) { yield if block_given? }
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def as_scoped_routes(*scopes)
|
|
40
|
+
options = scopes.extract_options!
|
|
41
|
+
scopes.each do |scope|
|
|
42
|
+
resources(scope, options.merge(:parent_scaffold => merge_module_scope(@scope[:module], parent_resource.plural), :named_scope => scope, :controller => parent_resource.plural)) { yield if block_given? }
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# save and validation support for associations.
|
|
2
|
+
class Sequel::Model
|
|
3
|
+
def associated_valid?(path = [])
|
|
4
|
+
return true if path.include?(self) # prevent recursion (if associated and parent are new records)
|
|
5
|
+
path << self
|
|
6
|
+
# using [].all? syntax to avoid a short-circuit
|
|
7
|
+
with_unsaved_associated { |a| [a.valid?, a.associated_valid?(path)].all? {|v| v == true} }
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def save_associated
|
|
11
|
+
with_unsaved_associated { |a| a.save and a.save_associated }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def save_associated!
|
|
15
|
+
save_associated or raise(Sequel::Error)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def no_errors_in_associated?
|
|
19
|
+
with_unsaved_associated {|a| a.errors.count == 0 and a.no_errors_in_associated?}
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
protected
|
|
23
|
+
|
|
24
|
+
# Provide an override to allow the model to restrict which associations are considered
|
|
25
|
+
# by ActiveScaffolds update mechanism. This allows the model to restrict things like
|
|
26
|
+
# Acts-As-Versioned versions associations being traversed.
|
|
27
|
+
#
|
|
28
|
+
# By defining the method :scaffold_update_nofollow returning an array of associations
|
|
29
|
+
# these associations will not be traversed.
|
|
30
|
+
# By defining the method :scaffold_update_follow returning an array of associations,
|
|
31
|
+
# only those associations will be traversed.
|
|
32
|
+
#
|
|
33
|
+
# Otherwise the default behaviour of traversing all associations will be preserved.
|
|
34
|
+
def associations_for_update
|
|
35
|
+
if self.respond_to?( :scaffold_update_nofollow )
|
|
36
|
+
self.class.associations.reject {|association| self.scaffold_update_nofollow.include?(association)}
|
|
37
|
+
elsif self.respond_to?( :scaffold_update_follow )
|
|
38
|
+
self.class.associations.select {|association| self.scaffold_update_follow.include?(association)}
|
|
39
|
+
else
|
|
40
|
+
self.class.associations
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
# yields every associated object that has been instantiated and is flagged as unsaved.
|
|
47
|
+
# returns false if any yield returns false.
|
|
48
|
+
# returns true otherwise, even when none of the associations have been instantiated. build wrapper methods accordingly.
|
|
49
|
+
def with_unsaved_associated
|
|
50
|
+
associations_for_update.all? do |association|
|
|
51
|
+
records = send(association)
|
|
52
|
+
if records
|
|
53
|
+
records = [records] unless records.is_a? Array # convert singular associations into collections for ease of use
|
|
54
|
+
records.select {|r| r.unsaved?}.all? {|r| yield r} # must use select instead of find_all, which Rails overrides on association proxies for db access
|
|
55
|
+
else
|
|
56
|
+
true
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# a simple (manual) unsaved? flag and method. at least it automatically reverts after a save!
|
|
2
|
+
class Sequel::Model
|
|
3
|
+
# acts like a dirty? flag, manually thrown during update_record_from_params.
|
|
4
|
+
def unsaved=(val)
|
|
5
|
+
@unsaved = (val) ? true : false
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
# whether the unsaved? flag has been thrown
|
|
9
|
+
def unsaved?
|
|
10
|
+
@unsaved
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# automatically unsets the unsaved flag
|
|
14
|
+
def save_with_unsaved_flag(*args)
|
|
15
|
+
result = save_without_unsaved_flag(*args)
|
|
16
|
+
self.unsaved = false
|
|
17
|
+
return result
|
|
18
|
+
end
|
|
19
|
+
alias_method_chain :save, :unsaved_flag
|
|
20
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
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
|