├── .gitignore
├── .travis.yml
├── Appraisals
├── CHANGELOG.md
├── Gemfile
├── MIT-LICENSE
├── README.md
├── Rakefile
├── carmen-rails.gemspec
├── gemfiles
├── rails_3.gemfile
├── rails_3.gemfile.lock
├── rails_4.gemfile
└── rails_4.gemfile.lock
├── lib
├── carmen-rails.rb
├── carmen
│ └── rails
│ │ ├── action_view
│ │ └── form_helper.rb
│ │ └── version.rb
└── tasks
│ └── carmen-rails_tasks.rake
└── test
├── carmen
└── action_view
│ └── helpers
│ └── form_helper_test.rb
└── test_helper.rb
/.gitignore:
--------------------------------------------------------------------------------
1 | .bundle/
2 | log/*.log
3 | pkg/
4 | Gemfile.lock
5 | .DS_Store
6 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | rvm:
2 | - 1.9.2
3 | - 1.9.3
4 | - 2.0.0
5 | env:
6 | - "RAILS_VERSION=3.1.0"
7 | - "RAILS_VERSION=3.2.0"
8 | - "RAILS_VERSION=4.0.0"
9 | matrix:
10 | exclude:
11 | - rvm: 1.9.2
12 | env: "RAILS_VERSION=4.0.0"
13 | branches:
14 | only:
15 | - master
16 |
--------------------------------------------------------------------------------
/Appraisals:
--------------------------------------------------------------------------------
1 | appraise "rails-3" do
2 | gem "rails", "~> 3.2"
3 | end
4 |
5 | appraise "rails-4" do
6 | gem "rails", "~> 4.0"
7 | end
8 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ### 1.0.1
2 |
3 | * Rails 4 compatibility.
4 |
5 | ### 1.0.0
6 |
7 | Updates
8 |
9 | * Push from beta to 1.0.0 final.
10 |
11 | ### 1.0.0.beta 3
12 |
13 | Bug Fixes
14 |
15 | * Removed some 1.9 syntax taht prevented the gem from running on Ruby 1.8
16 |
17 | Enhancements
18 |
19 | * Region select options are now sorted (lukast-akra)
20 |
21 | API Changes
22 |
23 | * region_options_for_select now takes priority region codes in an options hash
24 | under the key 'priority'.
25 | * The API for region_options_for_select now expects a collection of Carmen::Regions
26 | as its second argument instead of a parent region. This makes it simple to provide
27 | a custom collection of regions to build a select from.
28 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source "http://rubygems.org"
2 |
3 | gemspec
4 |
5 | gem 'appraisal', "1.0.0.beta3"
6 | gem "debugger"
7 |
--------------------------------------------------------------------------------
/MIT-LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2012 Jim Benton and contributors
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # NOT ACTIVELY MAINTAINED
2 |
3 | I haven't time in over a year to properly support this project.
4 |
5 | # carmen-rails
6 |
7 | carmen-rails is a Rails 3 plugin that supplies two new form helper methods:
8 | `country_select` and `subregion_select`. It uses
9 | [carmen](http://github.com/jim/carmen) as its source of geographic data.
10 |
11 | ## Requirements
12 |
13 | carmen-rails requires Ruby 1.9.2 or greater.
14 |
15 | ## Installation
16 |
17 | Just add carmen-rails to your Gemfile:
18 |
19 | ```ruby
20 | gem 'carmen-rails', '~> 1.0.0'
21 | ```
22 | ## Usage
23 |
24 | ```erb
25 | <%= form_for(@order) do |f| %>
26 |
27 | <%= f.label :country_code %>
28 | <%= f.country_select :country_code, {priority: %w(US CA), prompt: 'Please select a country'} %>
29 |
30 | <% end %>
31 | ```
32 |
33 | #### SimpleForm
34 | Pass the object to the country_select helper. This ensures the persisted country is selected when the form is rendered.
35 |
36 | ```erb
37 | <%= simple_form_for @user do |f| %>
38 | <%= f.input :country_code do %>
39 | <%= f.country_select :country_code, {object: f.object, prompt: 'Country'} %>
40 | <% end %>
41 | <% end %>
42 | ```
43 |
44 | Passing the object is necessary when using nested form fields with Formtastic.
45 |
46 | ## How do I only display a subset of countries/regions?
47 |
48 | Carmen had a concept of excluded countries in the old days, where you could
49 | specify certain countries or regions to not include in a select.
50 |
51 | The new (and much more flexible) way to handle this is to write a helper method
52 | that returns the subset of regions you want to provide:
53 |
54 | ``` ruby
55 | def only_us_and_canada
56 | Carmen::Country.all.select{|c| %w{US CA}.include?(c.code)}
57 | end
58 | ```
59 |
60 | And then in your form something like this:
61 |
62 | ``` erb
63 | <%= f.select :country, region_options_for_select(only_us_and_canada) %>
64 | ```
65 |
66 | More docs coming soon. In the meantime, all of the public methods in
67 | carmen-rails [have been thoroughly TomDoc'ed](https://github.com/jim/carmen-rails/blob/master/lib/carmen/rails/action_view/form_helper.rb).
68 |
69 | ### Demo app
70 |
71 | There is a [live demo app](http://carmen-rails-demo.herokuapp.com) that shows
72 | carmen-rails in action, and includes a [step-by-step setup guide](https://github.com/jim/carmen-demo-app#readme).
73 |
74 | ## Configuration
75 |
76 | Using this library will automatically set Carmen to use [Rails' built-in I18n functionality](http://guides.rubyonrails.org/i18n.html). This means that changing
77 | some configuration should be done through Rails and not Carmen. For example, adding paths for additional locale files
78 | should be done inside `config/application.rb`:
79 |
80 | ``` ruby
81 | config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
82 | ```
83 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | require "rubygems"
2 | require 'bundler/setup'
3 |
4 | require 'rake'
5 | require 'rake/testtask'
6 | require 'rdoc/task'
7 |
8 | Bundler::GemHelper.install_tasks
9 |
10 | Rake::TestTask.new(:test) do |t|
11 | t.libs << 'lib'
12 | t.libs << 'test'
13 | t.pattern = 'test/**/*_test.rb'
14 | t.verbose = true
15 | end
16 |
17 | desc 'Default: run unit tests.'
18 | task :default => :test
19 |
--------------------------------------------------------------------------------
/carmen-rails.gemspec:
--------------------------------------------------------------------------------
1 | $:.push File.expand_path("../lib", __FILE__)
2 |
3 | require "carmen/rails/version"
4 |
5 | Gem::Specification.new do |s|
6 | s.name = "carmen-rails"
7 | s.version = Carmen::Rails::VERSION
8 | s.authors = ["Jim Benton"]
9 | s.email = ["jim@autonomousmachine.com"]
10 | s.homepage = "http://github.com/jim/carmen-rails"
11 | s.summary = "Rails adapter for Carmen"
12 | s.description = "Provides country_select and subregion_select form helpers."
13 |
14 | s.files = Dir["{lib}/**/*"] + ["MIT-LICENSE", "Rakefile", "README.md"]
15 | s.test_files = Dir["spec/**/*"]
16 |
17 | s.add_dependency "rails"
18 | s.add_dependency "carmen", "~> 1.0.0"
19 |
20 | s.add_development_dependency "minitest"
21 | end
22 |
--------------------------------------------------------------------------------
/gemfiles/rails_3.gemfile:
--------------------------------------------------------------------------------
1 | # This file was generated by Appraisal
2 |
3 | source "http://rubygems.org"
4 |
5 | gem "appraisal", "1.0.0.beta3"
6 | gem "debugger"
7 | gem "rails", "~> 3.2"
8 |
9 | gemspec :path=>".././"
10 |
--------------------------------------------------------------------------------
/gemfiles/rails_3.gemfile.lock:
--------------------------------------------------------------------------------
1 | PATH
2 | remote: .././
3 | specs:
4 | carmen-rails (1.0.0)
5 | carmen (~> 1.0.0)
6 | rails
7 |
8 | GEM
9 | remote: http://rubygems.org/
10 | specs:
11 | actionmailer (3.2.17)
12 | actionpack (= 3.2.17)
13 | mail (~> 2.5.4)
14 | actionpack (3.2.17)
15 | activemodel (= 3.2.17)
16 | activesupport (= 3.2.17)
17 | builder (~> 3.0.0)
18 | erubis (~> 2.7.0)
19 | journey (~> 1.0.4)
20 | rack (~> 1.4.5)
21 | rack-cache (~> 1.2)
22 | rack-test (~> 0.6.1)
23 | sprockets (~> 2.2.1)
24 | activemodel (3.2.17)
25 | activesupport (= 3.2.17)
26 | builder (~> 3.0.0)
27 | activerecord (3.2.17)
28 | activemodel (= 3.2.17)
29 | activesupport (= 3.2.17)
30 | arel (~> 3.0.2)
31 | tzinfo (~> 0.3.29)
32 | activeresource (3.2.17)
33 | activemodel (= 3.2.17)
34 | activesupport (= 3.2.17)
35 | activesupport (3.2.17)
36 | i18n (~> 0.6, >= 0.6.4)
37 | multi_json (~> 1.0)
38 | appraisal (1.0.0.beta3)
39 | bundler
40 | rake
41 | thor (>= 0.14.0)
42 | arel (3.0.3)
43 | builder (3.0.4)
44 | carmen (1.0.1)
45 | unicode_utils (~> 1.4.0)
46 | columnize (0.3.6)
47 | debugger (1.6.6)
48 | columnize (>= 0.3.1)
49 | debugger-linecache (~> 1.2.0)
50 | debugger-ruby_core_source (~> 1.3.2)
51 | debugger-linecache (1.2.0)
52 | debugger-ruby_core_source (1.3.2)
53 | erubis (2.7.0)
54 | hike (1.2.3)
55 | i18n (0.6.9)
56 | journey (1.0.4)
57 | json (1.8.1)
58 | mail (2.5.4)
59 | mime-types (~> 1.16)
60 | treetop (~> 1.4.8)
61 | mime-types (1.25.1)
62 | minitest (5.3.0)
63 | multi_json (1.9.0)
64 | polyglot (0.3.4)
65 | rack (1.4.5)
66 | rack-cache (1.2)
67 | rack (>= 0.4)
68 | rack-ssl (1.3.3)
69 | rack
70 | rack-test (0.6.2)
71 | rack (>= 1.0)
72 | rails (3.2.17)
73 | actionmailer (= 3.2.17)
74 | actionpack (= 3.2.17)
75 | activerecord (= 3.2.17)
76 | activeresource (= 3.2.17)
77 | activesupport (= 3.2.17)
78 | bundler (~> 1.0)
79 | railties (= 3.2.17)
80 | railties (3.2.17)
81 | actionpack (= 3.2.17)
82 | activesupport (= 3.2.17)
83 | rack-ssl (~> 1.3.2)
84 | rake (>= 0.8.7)
85 | rdoc (~> 3.4)
86 | thor (>= 0.14.6, < 2.0)
87 | rake (10.1.1)
88 | rdoc (3.12.2)
89 | json (~> 1.4)
90 | sprockets (2.2.2)
91 | hike (~> 1.2)
92 | multi_json (~> 1.0)
93 | rack (~> 1.0)
94 | tilt (~> 1.1, != 1.3.0)
95 | thor (0.18.1)
96 | tilt (1.4.1)
97 | treetop (1.4.15)
98 | polyglot
99 | polyglot (>= 0.3.1)
100 | tzinfo (0.3.38)
101 | unicode_utils (1.4.0)
102 |
103 | PLATFORMS
104 | ruby
105 |
106 | DEPENDENCIES
107 | appraisal (= 1.0.0.beta3)
108 | carmen-rails!
109 | debugger
110 | minitest
111 | rails (~> 3.2)
112 |
--------------------------------------------------------------------------------
/gemfiles/rails_4.gemfile:
--------------------------------------------------------------------------------
1 | # This file was generated by Appraisal
2 |
3 | source "http://rubygems.org"
4 |
5 | gem "appraisal", "1.0.0.beta3"
6 | gem "debugger"
7 | gem "rails", "~> 4.0"
8 |
9 | gemspec :path=>".././"
10 |
--------------------------------------------------------------------------------
/gemfiles/rails_4.gemfile.lock:
--------------------------------------------------------------------------------
1 | PATH
2 | remote: .././
3 | specs:
4 | carmen-rails (1.0.0)
5 | carmen (~> 1.0.0)
6 | rails
7 |
8 | GEM
9 | remote: http://rubygems.org/
10 | specs:
11 | actionmailer (4.0.3)
12 | actionpack (= 4.0.3)
13 | mail (~> 2.5.4)
14 | actionpack (4.0.3)
15 | activesupport (= 4.0.3)
16 | builder (~> 3.1.0)
17 | erubis (~> 2.7.0)
18 | rack (~> 1.5.2)
19 | rack-test (~> 0.6.2)
20 | activemodel (4.0.3)
21 | activesupport (= 4.0.3)
22 | builder (~> 3.1.0)
23 | activerecord (4.0.3)
24 | activemodel (= 4.0.3)
25 | activerecord-deprecated_finders (~> 1.0.2)
26 | activesupport (= 4.0.3)
27 | arel (~> 4.0.0)
28 | activerecord-deprecated_finders (1.0.3)
29 | activesupport (4.0.3)
30 | i18n (~> 0.6, >= 0.6.4)
31 | minitest (~> 4.2)
32 | multi_json (~> 1.3)
33 | thread_safe (~> 0.1)
34 | tzinfo (~> 0.3.37)
35 | appraisal (1.0.0.beta3)
36 | bundler
37 | rake
38 | thor (>= 0.14.0)
39 | arel (4.0.2)
40 | atomic (1.1.15)
41 | builder (3.1.4)
42 | carmen (1.0.1)
43 | unicode_utils (~> 1.4.0)
44 | columnize (0.3.6)
45 | debugger (1.6.6)
46 | columnize (>= 0.3.1)
47 | debugger-linecache (~> 1.2.0)
48 | debugger-ruby_core_source (~> 1.3.2)
49 | debugger-linecache (1.2.0)
50 | debugger-ruby_core_source (1.3.2)
51 | erubis (2.7.0)
52 | hike (1.2.3)
53 | i18n (0.6.9)
54 | mail (2.5.4)
55 | mime-types (~> 1.16)
56 | treetop (~> 1.4.8)
57 | mime-types (1.25.1)
58 | minitest (4.7.5)
59 | multi_json (1.9.0)
60 | polyglot (0.3.4)
61 | rack (1.5.2)
62 | rack-test (0.6.2)
63 | rack (>= 1.0)
64 | rails (4.0.3)
65 | actionmailer (= 4.0.3)
66 | actionpack (= 4.0.3)
67 | activerecord (= 4.0.3)
68 | activesupport (= 4.0.3)
69 | bundler (>= 1.3.0, < 2.0)
70 | railties (= 4.0.3)
71 | sprockets-rails (~> 2.0.0)
72 | railties (4.0.3)
73 | actionpack (= 4.0.3)
74 | activesupport (= 4.0.3)
75 | rake (>= 0.8.7)
76 | thor (>= 0.18.1, < 2.0)
77 | rake (10.1.1)
78 | sprockets (2.11.0)
79 | hike (~> 1.2)
80 | multi_json (~> 1.0)
81 | rack (~> 1.0)
82 | tilt (~> 1.1, != 1.3.0)
83 | sprockets-rails (2.0.1)
84 | actionpack (>= 3.0)
85 | activesupport (>= 3.0)
86 | sprockets (~> 2.8)
87 | thor (0.18.1)
88 | thread_safe (0.2.0)
89 | atomic (>= 1.1.7, < 2)
90 | tilt (1.4.1)
91 | treetop (1.4.15)
92 | polyglot
93 | polyglot (>= 0.3.1)
94 | tzinfo (0.3.38)
95 | unicode_utils (1.4.0)
96 |
97 | PLATFORMS
98 | ruby
99 |
100 | DEPENDENCIES
101 | appraisal (= 1.0.0.beta3)
102 | carmen-rails!
103 | debugger
104 | minitest
105 | rails (~> 4.0)
106 |
--------------------------------------------------------------------------------
/lib/carmen-rails.rb:
--------------------------------------------------------------------------------
1 | require 'carmen'
2 | require 'carmen/rails/action_view/form_helper'
3 | require 'carmen/rails/version'
4 |
5 | module Carmen
6 | module Rails
7 | class Railtie < ::Rails::Railtie
8 | # Add Carmen's locale paths to the Rails backend
9 | paths = Carmen.i18n_backend.locale_paths.map { |path|
10 | Dir[path + '**/*.yml']
11 | }.flatten.compact
12 | Carmen.i18n_backend = ::I18n
13 | config.i18n.load_path += paths
14 |
15 | # Enable fallbacks so that missing translations use the default locale
16 | config.i18n.fallbacks = true
17 | end
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/lib/carmen/rails/action_view/form_helper.rb:
--------------------------------------------------------------------------------
1 | module ActionView
2 | module Helpers
3 | module FormOptionsHelper
4 |
5 | # Generate select and subregion option tags for the given object and method. A
6 | # common use of this would be to allow users to select a state subregion within
7 | # a given country.
8 | #
9 | # object - The model object to generate the select for
10 | # method - The attribute on the object
11 | # parent_region_or_code - An instance of Carmen::Region or a 2-character
12 | # country code.
13 | # options - Other options pertaining to option tag generation. See
14 | # `region_options_for_select`.
15 | # html_options - Options to use when generating the select tag- class,
16 | # id, etc.
17 | #
18 | # Uses region_options_for_select to generate the list of option tags.
19 | #
20 | # Example:
21 | #
22 | # subregion_select(@object, :region, {priority: ['US', 'CA']}, class: 'region')
23 | #
24 | # Returns an `html_safe` string containing the HTML for a select element.
25 | def subregion_select(object, method, parent_region_or_code, options={}, html_options={})
26 | parent_region = determine_parent(parent_region_or_code)
27 | tag = instance_tag(object, method, self, options)
28 | tag.to_region_select_tag(parent_region, options, html_options)
29 | end
30 |
31 | # Generate select and country option tags for the given object and method. A
32 | # common use of this would be to allow users to select a state subregion within
33 | # a given country.
34 | #
35 | # object - The model object to generate the select for
36 | # method - The attribute on the object
37 | # options - Other options pertaining to option tag generation. See
38 | # `region_options_for_select`.
39 | # html_options - Options to use when generating the select tag- class,
40 | # id, etc.
41 | #
42 | # Uses region_options_or_select to generate the list of option tags.
43 | #
44 | # Example:
45 | #
46 | # country_select(@object, :region, {priority: ['US', 'CA']}, class: 'region')
47 | #
48 | # Note that in order to preserve compatibility with various existing
49 | # libraries, an alternative API is supported but not recommended:
50 | #
51 | # country_select(@object, :region, ['US', 'CA'], class: region)
52 | #
53 | # Returns an `html_safe` string containing the HTML for a select element.
54 | def country_select(object, method, priorities_or_options = {}, options_or_html_options = {}, html_options = {})
55 | if priorities_or_options.is_a? Array
56 | options = options_or_html_options
57 | options[:priority] = priorities_or_options
58 | else
59 | options = priorities_or_options
60 | html_options = options_or_html_options
61 | end
62 |
63 | tag = instance_tag(object, method, self, options)
64 | tag.to_region_select_tag(Carmen::World.instance, options, html_options)
65 | end
66 |
67 | # Generate option tags for a collection of regions.
68 | #
69 | # regions - An array or Carmen::RegionCollection containing Carmen::Regions
70 | # selected - the code of the region that should be selected
71 | # options - The hash of options used to customize the output (default: {}):
72 | #
73 | # To use priority regions (which are included in a special section at the
74 | # top of the list), provide an array of region codes at the :priority
75 | # option:
76 | #
77 | # region_options_for_select(@region.subregions, 'US', priority: ['US', 'CA'])
78 | #
79 | # Returns an `html_safe` string containing option tags.
80 | def region_options_for_select(regions, selected=nil, options={})
81 | options.stringify_keys!
82 | priority_region_codes = options['priority'] || []
83 | region_options = ""
84 |
85 | unless priority_region_codes.empty?
86 | unless regions.respond_to?(:coded)
87 | regions = Carmen::RegionCollection.new(regions)
88 | end
89 |
90 | priority_regions = priority_region_codes.map do |code|
91 | region = regions.coded(code)
92 | [region.name, region.code] if region
93 | end.compact
94 | unless priority_regions.empty?
95 | region_options += options_for_select(priority_regions, selected)
96 | region_options += "------------- "
97 |
98 | # If a priority region is selected, don't select it again in the main list.
99 | # This prevents some browsers from selecting the second occurance of this region,
100 | # which makes it difficult to select an alternative priority region.
101 | selected = nil if priority_region_codes.include?(selected)
102 | end
103 | end
104 |
105 | main_options = regions.map { |r| [r.name, r.code] }
106 | main_options.sort!{|a, b| a.first.to_s <=> b.first.to_s}
107 | main_options.unshift [options['prompt'], ''] if options['prompt']
108 |
109 | region_options += options_for_select(main_options, selected)
110 | region_options.html_safe
111 | end
112 |
113 | # Generate select and country option tags with the provided name. A
114 | # common use of this would be to allow users to select a country name
115 | # inside a web form.
116 | #
117 | # name - The name attribute for the select element.
118 | # options - Other options pertaining to option tag generation. See
119 | # `region_options_for_select`.
120 | # html_options - Options to use when generating the select tag- class,
121 | # id, etc.
122 | #
123 | # Uses region_options_or_select to generate the list of option tags.
124 | #
125 | # Example:
126 | #
127 | # country_select_tag('country_code', {priority: ['US', 'CA']}, class: 'region')
128 | #
129 | # Returns an `html_safe` string containing the HTML for a select element.
130 | def country_select_tag(name, value, options={})
131 | subregion_select_tag(name, value, Carmen::World.instance, options)
132 | end
133 |
134 | # Generate select and subregion option tags for the given object and method. A
135 | # common use of this would be to allow users to select a state subregion within
136 | # a given country.
137 | #
138 | # name - The name attribute for the select element.
139 | # parent_region_or_code - An instance of Carmen::Region or a 2-character
140 | # country code.
141 | # options - Other options pertaining to option tag generation. See
142 | # `region_options_for_select`.
143 | # html_options - Options to use when generating the select tag- class,
144 | # id, etc.
145 | #
146 | # Uses region_options_or_select to generate the list of option tags.
147 | #
148 | # Example:
149 | #
150 | # subregion_select_tag('state_code', 'US', {priority: ['US', 'CA']}, class: 'region')
151 | #
152 | # Returns an `html_safe` string containing the HTML for a select element.
153 | def subregion_select_tag(name, value, parent_region_or_code, options = {}, html_options = {})
154 | options.stringify_keys!
155 | parent_region = determine_parent(parent_region_or_code)
156 | opts = region_options_for_select(parent_region.subregions, value, options)
157 | html_options = {"name" => name,
158 | "id" => sanitize_to_id(name)}.update(html_options.stringify_keys)
159 | content_tag(:select, opts, html_options)
160 | end
161 |
162 | private
163 |
164 | def instance_tag(object_name, method_name, template_object, options = {})
165 | if Rails::VERSION::MAJOR == 3
166 | InstanceTag.new(object_name, method_name, template_object, options.delete(:object))
167 | else
168 | ActionView::Helpers::Tags::Base.new(object_name, method_name, template_object, options || {})
169 | end
170 | end
171 |
172 |
173 | def determine_parent(parent_region_or_code)
174 | case parent_region_or_code
175 | when String
176 | Carmen::Country.coded(parent_region_or_code)
177 | when Array
178 | parent_region_or_code.inject(Carmen::World.instance) { |parent, next_code|
179 | parent.subregions.coded(next_code)
180 | }
181 | else
182 | parent_region_or_code
183 | end
184 | end
185 | end
186 |
187 | if Rails::VERSION::MAJOR == 3
188 | class InstanceTag
189 | def to_region_select_tag(parent_region, options = {}, html_options = {})
190 | html_options = html_options.stringify_keys
191 | add_default_name_and_id(html_options)
192 | priority_regions = options[:priority] || []
193 | value = options[:selected] ? options[:selected] : value(object)
194 | opts = add_options(region_options_for_select(parent_region.subregions, value, :priority => priority_regions), options, value)
195 | content_tag("select", opts, html_options)
196 | end
197 | end
198 | end
199 |
200 | if Rails::VERSION::MAJOR == 4
201 | module Tags
202 | class Base
203 | def to_region_select_tag(parent_region, options = {}, html_options = {})
204 | html_options = html_options.stringify_keys
205 | add_default_name_and_id(html_options)
206 | options[:include_blank] ||= true unless options[:prompt] || select_not_required?(html_options)
207 |
208 | value = options[:selected] ? options[:selected] : value(object)
209 | priority_regions = options[:priority] || []
210 | opts = add_options(region_options_for_select(parent_region.subregions, value,
211 | :priority => priority_regions),
212 | options, value)
213 | select = content_tag("select", opts, html_options)
214 | if html_options["multiple"] && options.fetch(:include_hidden, true)
215 | tag("input", :disabled => html_options["disabled"], :name => html_options["name"],
216 | :type => "hidden", :value => "") + select
217 | else
218 | select
219 | end
220 | end
221 | end
222 | end
223 | end
224 |
225 | class FormBuilder
226 | # Generate select and country option tags with the provided name. A
227 | # common use of this would be to allow users to select a country name inside a
228 | # web form.
229 | #
230 | # See `FormOptionsHelper::country_select` for more information.
231 | def country_select(method, priorities_or_options = {}, options_or_html_options = {}, html_options = {})
232 | if priorities_or_options.is_a? Array
233 | options = options_or_html_options
234 | options[:priority] = priorities_or_options
235 | else
236 | options = priorities_or_options
237 | html_options = options_or_html_options
238 | end
239 |
240 | @template.country_select(@object_name, method, objectify_options(options), @default_options.merge(html_options))
241 | end
242 |
243 | # Generate select and subregion option tags with the provided name. A
244 | # common use of this would be to allow users to select a state subregion within
245 | # a given country.
246 | #
247 | # See `FormOptionsHelper::subregion_select` for more information.
248 | def subregion_select(method, parent_region_or_code, options = {}, html_options = {})
249 | @template.subregion_select(@object_name, method, parent_region_or_code, objectify_options(options), @default_options.merge(html_options))
250 | end
251 | end
252 |
253 | end
254 | end
255 |
--------------------------------------------------------------------------------
/lib/carmen/rails/version.rb:
--------------------------------------------------------------------------------
1 | module Carmen
2 | module Rails
3 | VERSION = "1.0.1"
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/lib/tasks/carmen-rails_tasks.rake:
--------------------------------------------------------------------------------
1 | # desc "Explaining what the task does"
2 | # task :carmen-rails do
3 | # # Task goes here
4 | # end
5 |
--------------------------------------------------------------------------------
/test/carmen/action_view/helpers/form_helper_test.rb:
--------------------------------------------------------------------------------
1 | require 'test_helper'
2 |
3 | class CarmenViewHelperTest < MiniTest::Unit::TestCase
4 | include ActionView::Helpers::FormOptionsHelper
5 | include ActionView::Helpers::FormTagHelper
6 | include ActionDispatch::Assertions::SelectorAssertions
7 |
8 | def setup
9 | @object = OpenStruct.new
10 | def @object.to_s; 'object'; end
11 | end
12 |
13 | def response_from_page
14 | HTML::Document.new(@html).root
15 | end
16 |
17 | def test_basic_country_select
18 | html = country_select(:object, :country_code)
19 | expected = <<-HTML
20 |
21 | Eastasia
22 | Eurasia
23 | Oceania
24 |
25 | HTML
26 |
27 | assert_equal_markup(expected, html)
28 | end
29 |
30 | def test_country_selected_value
31 | @html = country_select(:object, :country_code, :selected => 'OC')
32 | assert_select('option[selected="selected"][value="OC"]')
33 | end
34 |
35 | def test_country_selected_object_option
36 | @object.country_code = 'OC'
37 | override_object = OpenStruct.new(:country_code => 'ES')
38 | @html = country_select(@object, :country_code, {:object => override_object})
39 |
40 | assert_select('option[selected="selected"][value="ES"]')
41 | end
42 |
43 | def test_basic_country_select_tag
44 | html = country_select_tag('attribute_name', nil)
45 | expected = <<-HTML
46 |
47 | Eastasia
48 | Eurasia
49 | Oceania
50 |
51 | HTML
52 |
53 | assert_equal_markup(expected, html)
54 | end
55 |
56 | def test_country_select_tag_with_prompt
57 | html = country_select_tag('attribute_name', nil, :prompt => 'Please Select')
58 | expected = <<-HTML
59 |
60 | Please Select
61 | Eastasia
62 | Eurasia
63 | Oceania
64 |
65 | HTML
66 |
67 | assert_equal_markup(expected, html)
68 | end
69 | def test_country_tag_selected_value
70 | @html = country_select_tag(:country_code, 'OC')
71 | assert_select('option[selected="selected"][value="OC"]')
72 | end
73 |
74 | def test_priority_country_select
75 | html = country_select(:object, :country_code, :priority => ['ES'])
76 | expected = <<-HTML
77 |
78 | Eastasia
79 | -------------
80 | Eastasia
81 | Eurasia
82 | Oceania
83 |
84 | HTML
85 |
86 | assert_equal_markup(expected, html)
87 | end
88 |
89 | def test_priority_country_select_deprecated_api
90 | html = country_select(:object, :country_code, ['ES'], {})
91 | expected = <<-HTML
92 |
93 | Eastasia
94 | -------------
95 | Eastasia
96 | Eurasia
97 | Oceania
98 |
99 | HTML
100 |
101 | assert_equal_markup(expected, html)
102 | end
103 |
104 | def test_country_select_selected_priority_region_not_selected_twice
105 | @object.country_code = 'ES'
106 |
107 | html = country_select(@object, :country_code, :priority => ['ES'])
108 | expected = <<-HTML
109 |
110 | Eastasia
111 | -------------
112 | Eastasia
113 | Eurasia
114 | Oceania
115 |
116 | HTML
117 |
118 | assert_equal_markup(expected, html)
119 | end
120 |
121 | def test_basic_subregion_select
122 | oceania = Carmen::Country.coded('OC')
123 | expected = <<-HTML
124 |
125 | Airstrip One
126 |
127 | HTML
128 |
129 | html = subregion_select(:object, :subregion_code, oceania)
130 |
131 | assert_equal_markup(expected, html)
132 | end
133 |
134 | def test_subregion_select_using_parent_code
135 | expected = <<-HTML
136 |
137 | Airstrip One
138 |
139 | HTML
140 |
141 | html = subregion_select(:object, :subregion_code, 'OC')
142 |
143 | assert_equal_markup(expected, html)
144 | end
145 |
146 | def test_subregion_select_using_parent_code_array
147 | expected = <<-HTML
148 |
149 | London
150 |
151 | HTML
152 |
153 | html = subregion_select(:object, :subregion_code, ['OC', 'AO'])
154 |
155 | assert_equal_markup(expected, html)
156 | end
157 |
158 | def test_subregion_selected_value
159 | oceania = Carmen::Country.coded('OC')
160 |
161 | @html = subregion_select(:object, :subregion_code, oceania, :selected => 'AO')
162 | assert_select('option[selected="selected"][value="AO"]')
163 | end
164 |
165 | def test_subregion_selected_value_with_priority_and_selected_options
166 | oceania = Carmen::Country.coded('OC')
167 | @html = subregion_select(:object, :subregion_code, oceania, { priority: ['AO'], selected: 'AO' })
168 |
169 | assert_select('option[selected="selected"][value="AO"]')
170 | end
171 |
172 | def test_html_options_for_selected_value_with_priority_and_selected_options
173 | oceania = Carmen::Country.coded('OC')
174 | @html = subregion_select(:object, :subregion_code, oceania, { priority: ['AO'], selected: 'AO' }, { class: :test_html_options})
175 |
176 | assert_select('.test_html_options')
177 | end
178 |
179 | def test_basic_subregion_select_tag
180 | oceania = Carmen::Country.coded('OC')
181 | expected = <<-HTML
182 |
183 | Airstrip One
184 |
185 | HTML
186 |
187 | html = subregion_select_tag(:subregion_code, nil, oceania)
188 |
189 | assert_equal_markup(expected, html)
190 | end
191 |
192 | def test_subregion_select_tag_with_priority
193 | oceania = Carmen::Country.coded('OC')
194 | expected = <<-HTML
195 |
196 | Airstrip One
197 | -------------
198 | Airstrip One
199 |
200 | HTML
201 |
202 | html = subregion_select_tag(:subregion_code, nil, oceania, :priority => ['AO'])
203 |
204 | assert_equal_markup(expected, html)
205 | end
206 |
207 | def test_subregion_select_tag_with_prompt
208 | oceania = Carmen::Country.coded('OC')
209 | expected = <<-HTML
210 |
211 | Please select
212 | Airstrip One
213 |
214 | HTML
215 |
216 | html = subregion_select_tag(:subregion_code, nil, oceania, :prompt => 'Please select')
217 |
218 | assert_equal_markup(expected, html)
219 | end
220 |
221 | def test_region_options_for_select
222 | regions = Carmen::Country.all
223 | if Rails::VERSION::MAJOR == 3
224 | expected = <<-HTML
225 | Eastasia
226 | Eurasia
227 | Oceania
228 | HTML
229 | else
230 | expected = <<-HTML
231 | Eastasia
232 | Eurasia
233 | Oceania
234 | HTML
235 | end
236 | html = region_options_for_select(regions, 'OC')
237 |
238 | assert_equal_markup(expected, html)
239 | end
240 |
241 | def test_region_options_for_select_with_array_of_regions_and_priority
242 | regions = [Carmen::Country.coded('ES'), Carmen::Country.coded('EU')]
243 | expected = <<-HTML
244 | Eastasia
245 | -------------
246 | Eastasia
247 | Eurasia
248 | HTML
249 | html = region_options_for_select(regions, nil, :priority => ['ES'])
250 |
251 | assert_equal_markup(expected, html)
252 | end
253 |
254 | def test_form_builder_country_select
255 | form = ActionView::Helpers::FormBuilder.new(:object, @object, self, {}, lambda{})
256 |
257 | html = form.country_select('attribute_name')
258 | expected = <<-HTML
259 |
260 | Eastasia
261 | Eurasia
262 | Oceania
263 |
264 | HTML
265 |
266 | assert_equal_markup(expected, html)
267 | end
268 |
269 | def test_form_builder_selected_country
270 | @object.country_code = 'OC'
271 | form = ActionView::Helpers::FormBuilder.new(:object, @object, self, {}, lambda{})
272 | @html = form.country_select('country_code')
273 |
274 | assert_select('option[selected="selected"][value="OC"]')
275 | end
276 |
277 | def test_form_builder_country_select_deprecated_api
278 | form = ActionView::Helpers::FormBuilder.new(:object, @object, self, {}, lambda{})
279 |
280 | html = form.country_select('attribute_name', ['ES'])
281 | expected = <<-HTML
282 |
283 | Eastasia
284 | -------------
285 | Eastasia
286 | Eurasia
287 | Oceania
288 |
289 | HTML
290 |
291 | assert_equal_markup(expected, html)
292 | end
293 |
294 | def test_form_builder_subregion_select
295 | form = ActionView::Helpers::FormBuilder.new(:object, @object, self, {}, lambda{})
296 | html = form.subregion_select(:subregion_code, 'OC')
297 | expected = <<-HTML
298 |
299 | Airstrip One
300 |
301 | HTML
302 |
303 | assert_equal_markup(expected, html)
304 | end
305 |
306 | def test_form_builder_selected_subregion
307 | @object.subregion_code = 'AO'
308 | form = ActionView::Helpers::FormBuilder.new(:object, @object, self, {}, lambda{})
309 | @html = form.subregion_select(:subregion_code, 'OC')
310 |
311 | assert_select('option[selected="selected"][value="AO"]')
312 | end
313 | end
314 |
--------------------------------------------------------------------------------
/test/test_helper.rb:
--------------------------------------------------------------------------------
1 | lib_path = File.expand_path('../../lib', __FILE__)
2 | $LOAD_PATH.unshift(lib_path)
3 |
4 | require 'minitest/autorun'
5 | require 'minitest/spec'
6 |
7 | require 'action_view/test_case'
8 |
9 | require 'rails'
10 | require 'carmen-rails'
11 | require 'ostruct'
12 | require 'debugger'
13 |
14 | MiniTest::Spec.register_spec_type(/.*/, ActionView::TestCase)
15 |
16 | Carmen.clear_data_paths
17 |
18 | carmen_path = File.expand_path('../../../carmen', __FILE__)
19 |
20 | Carmen.append_data_path(carmen_path + '/spec_data/data')
21 |
22 | locale_path = carmen_path + '/spec_data/locale'
23 | Carmen.i18n_backend = Carmen::I18n::Simple.new(locale_path)
24 |
25 | class MiniTest::Unit::TestCase
26 | def assert_equal_markup(expected, actual, message=nil)
27 | assert_equal(clean_markup(expected), clean_markup(actual), message)
28 | end
29 |
30 | private
31 |
32 | def clean_markup(markup)
33 | clean_whitespace(markup).gsub(/( [a-zA-Z_]*="[^"]*")+/) do |match|
34 | ' ' + match.strip!.split(' ').sort.join(' ')
35 | end
36 | end
37 |
38 | def clean_whitespace(markup)
39 | markup.
40 | gsub(/\s+/, ' '). # cleanup whitespace
41 | gsub(/>\s/, '>'). # kill space after tags
42 | gsub(/\s, '<'). # space before tags
43 | gsub(/\s\/>/, '/>'). # space inside self-closing tags
44 | strip
45 | end
46 | end
47 |
--------------------------------------------------------------------------------