effective_addresses 1.2.4 → 1.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.
- checksums.yaml +4 -4
- data/README.md +61 -3
- data/app/assets/javascripts/effective_addresses/address_fields.js.coffee +7 -1
- data/app/helpers/effective_addresses_helper.rb +17 -6
- data/app/models/effective/address.rb +1 -17
- data/app/views/effective/addresses/_address_fields_formtastic.html.haml +38 -25
- data/app/views/effective/addresses/_address_fields_simple_form.html.haml +22 -11
- data/lib/effective_addresses.rb +0 -1
- data/lib/effective_addresses/version.rb +1 -1
- data/lib/generators/templates/effective_addresses.rb +6 -4
- data/spec/dummy/app/models/user.rb +22 -22
- metadata +2 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1e67a2c4ca21e0c16b9d61346e05f3533ba09b31
|
4
|
+
data.tar.gz: 659e413366e47d7c3c8b2469c8c0887f7cbade9a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 23c02018590042e590c457e702a9178cbbdd34b9f90bfb92bf610e9519cb9067f9212af07d77e4c0aec1ef8f1b9f91010b45c709e1fa890b1b6b4e066ced7025
|
7
|
+
data.tar.gz: ba069457c8055a65af00fc91fdd77a3a5a55cd54737d211262e38bbaad0551147fe012665bc78122c29799b6eb70ed90a46106a2d7c00335aadd37a1d9960924
|
data/README.md
CHANGED
@@ -165,7 +165,13 @@ The actual permitted parameters are:
|
|
165
165
|
|
166
166
|
### Form Helpers
|
167
167
|
|
168
|
-
Use the helper in a Formtastic or SimpleForm form to quickly create the address fields.
|
168
|
+
Use the helper in a Formtastic or SimpleForm form to quickly create the address fields. Currently only supports Formtastic and SimpleForm.
|
169
|
+
|
170
|
+
When you select a country from the select input an AJAX GET request will be made to `effective_addresses.address_subregions_path` (`/addresses/subregions/:country_code`)
|
171
|
+
which populates the province/state dropdown with the selected country's states or provinces.
|
172
|
+
|
173
|
+
|
174
|
+
#### Formtastic
|
169
175
|
|
170
176
|
```ruby
|
171
177
|
= semantic_form_for @user do |f|
|
@@ -173,7 +179,11 @@ Use the helper in a Formtastic or SimpleForm form to quickly create the address
|
|
173
179
|
= effective_address_fields(f, :billing_address)
|
174
180
|
|
175
181
|
= f.action :submit
|
182
|
+
```
|
176
183
|
|
184
|
+
#### SimpleForm
|
185
|
+
|
186
|
+
```ruby
|
177
187
|
= simple_form_for @user do |f|
|
178
188
|
%h3 Billing Address
|
179
189
|
= effective_address_fields(f, :billing_address)
|
@@ -181,9 +191,57 @@ Use the helper in a Formtastic or SimpleForm form to quickly create the address
|
|
181
191
|
= f.submit 'Save'
|
182
192
|
```
|
183
193
|
|
184
|
-
|
194
|
+
#### Field Ordering
|
195
|
+
You may choose to order fields different than the default, such as putting the country first. You can do so with the `:field_order` option, for example:
|
196
|
+
```ruby
|
197
|
+
= simple_form_for @user do |f|
|
198
|
+
%h3 Billing Address
|
199
|
+
= effective_address_fields(f, :billing_address, :field_order => [:country_code, :full_name, :address1, :address2, :city, :state_code, :postal_code])
|
200
|
+
|
201
|
+
= f.submit 'Save'
|
202
|
+
```
|
185
203
|
|
186
|
-
|
204
|
+
## Geocoder option
|
205
|
+
|
206
|
+
Effective addresses has an optional integration with [Geocoder](https://github.com/alexreisner/geocoder). At it's simplest, this provides preselection and prefill of `country`, `state`, `city`, and `postal_code` based on the user's IP address. See [Geocoder](https://github.com/alexreisner/geocoder) for
|
207
|
+
a complete list of possibilities.
|
208
|
+
|
209
|
+
### Installation and Setup
|
210
|
+
|
211
|
+
```ruby
|
212
|
+
gem 'geocoder'
|
213
|
+
```
|
214
|
+
|
215
|
+
Add `config/initializer/geocoder.rb`, below is a sample:
|
216
|
+
|
217
|
+
```ruby
|
218
|
+
Geocoder.configure(
|
219
|
+
# geocoding options
|
220
|
+
|
221
|
+
# IP address geocoding service (see below for supported options):
|
222
|
+
# https://github.com/alexreisner/geocoder#ip-address-services
|
223
|
+
ip_lookup: :telize,
|
224
|
+
cache: Rails.cache,
|
225
|
+
cache_prefix: 'geocoder:'
|
226
|
+
)
|
227
|
+
|
228
|
+
# Provide a hardcoded ip of 1.2.3.4 when in developmnt/test and the ip address resolves as localhost
|
229
|
+
if %w(development test).include? Rails.env
|
230
|
+
module Geocoder
|
231
|
+
module Request
|
232
|
+
def geocoder_spoofable_ip_with_localhost_override
|
233
|
+
ip_candidate = geocoder_spoofable_ip_without_localhost_override
|
234
|
+
if ip_candidate == '127.0.0.1'
|
235
|
+
'1.2.3.4'
|
236
|
+
else
|
237
|
+
ip_candidate
|
238
|
+
end
|
239
|
+
end
|
240
|
+
alias_method_chain :geocoder_spoofable_ip, :localhost_override
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
```
|
187
245
|
|
188
246
|
|
189
247
|
## License
|
@@ -1,9 +1,15 @@
|
|
1
1
|
$(document).on 'change', "select[data-effective-address-country]", (event) ->
|
2
2
|
country_code = $(this).val()
|
3
3
|
uuid = $(this).data('effective-address-country')
|
4
|
+
form = $(this).closest('form')
|
4
5
|
|
6
|
+
# clear postal_code and city values on country change
|
7
|
+
form.find("input[data-effective-address-postal-code='#{uuid}']").val('')
|
8
|
+
form.find("input[data-effective-address-city='#{uuid}']").val('')
|
9
|
+
|
10
|
+
# load state options
|
5
11
|
url = "/addresses/subregions/#{country_code}"
|
6
|
-
state_select =
|
12
|
+
state_select = form.find("select[data-effective-address-state='#{uuid}']").first()
|
7
13
|
|
8
14
|
if country_code.length == 0
|
9
15
|
state_select.prop('disabled', true).addClass('disabled').parent('.form-group').addClass('disabled')
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'carmen-rails'
|
2
2
|
|
3
3
|
module EffectiveAddressesHelper
|
4
|
+
@@use_geocoder = defined?(Geocoder)
|
5
|
+
|
4
6
|
def effective_address_fields(form, method = 'billing', options = {})
|
5
7
|
method = (method.to_s.include?('_address') ? method.to_s : "#{method}_address")
|
6
8
|
|
@@ -8,13 +10,9 @@ module EffectiveAddressesHelper
|
|
8
10
|
use_full_name = form.object._validators[method.to_sym].any? { |v| v.kind_of?(EffectiveAddressFullNamePresenceValidator) }
|
9
11
|
|
10
12
|
address = form.object.send(method) || form.object.addresses.build(:category => method.to_s.gsub('_address', ''))
|
13
|
+
effective_address_pre_select(address) if address.new_record?
|
11
14
|
|
12
|
-
|
13
|
-
address.country = EffectiveAddresses.pre_selected_country
|
14
|
-
address.state = EffectiveAddresses.pre_selected_state if (address.country.present? && EffectiveAddresses.pre_selected_state.present?)
|
15
|
-
end
|
16
|
-
|
17
|
-
opts = {:required => required, :use_full_name => use_full_name}.merge(options).merge({:f => form, :address => address, :method => method})
|
15
|
+
opts = {:required => required, :use_full_name => use_full_name, :field_order => [:full_name, :address1, :address2, :city, :country_code, :state_code, :postal_code]}.merge(options).merge({:f => form, :address => address, :method => method})
|
18
16
|
|
19
17
|
if form.class.name == 'SimpleForm::FormBuilder'
|
20
18
|
render :partial => 'effective/addresses/address_fields_simple_form', :locals => opts
|
@@ -25,6 +23,19 @@ module EffectiveAddressesHelper
|
|
25
23
|
end
|
26
24
|
end
|
27
25
|
|
26
|
+
def effective_address_pre_select(address)
|
27
|
+
if EffectiveAddresses.pre_selected_country.present?
|
28
|
+
address.country = EffectiveAddresses.pre_selected_country
|
29
|
+
address.state = EffectiveAddresses.pre_selected_state if (result[0].present? && EffectiveAddresses.pre_selected_state.present?)
|
30
|
+
elsif @@use_geocoder && request.location.present?
|
31
|
+
data = request.location.data
|
32
|
+
address.country = data['country_code']
|
33
|
+
address.state = data['region_code']
|
34
|
+
address.postal_code = data['postal_code']
|
35
|
+
address.city = data['city']
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
28
39
|
def region_options_for_simple_form_select(regions = nil)
|
29
40
|
if regions.present?
|
30
41
|
countries = regions
|
@@ -9,23 +9,7 @@ module Effective
|
|
9
9
|
|
10
10
|
belongs_to :addressable, :polymorphic => true, :touch => true
|
11
11
|
|
12
|
-
|
13
|
-
category :string, :validates => [:presence]
|
14
|
-
|
15
|
-
full_name :string
|
16
|
-
|
17
|
-
address1 :string, :validates => [:presence]
|
18
|
-
address2 :string
|
19
|
-
|
20
|
-
city :string, :validates => [:presence]
|
21
|
-
|
22
|
-
state_code :string
|
23
|
-
country_code :string, :validates => [:presence]
|
24
|
-
|
25
|
-
postal_code :string, :validates => [:presence]
|
26
|
-
|
27
|
-
timestamps
|
28
|
-
end
|
12
|
+
validates_presence_of :category, :address1, :city, :country_code, :postal_code
|
29
13
|
|
30
14
|
validates_presence_of :state_code, :if => Proc.new { |address| address.country_code.blank? || Carmen::Country.coded(address.country_code).try(:subregions).present? }
|
31
15
|
|
@@ -5,28 +5,41 @@
|
|
5
5
|
- if ((f.object.errors.include?(method) && !f.object.errors.include?(:addresses)) rescue false)
|
6
6
|
- fa.object.errors.add(:address1, f.object.errors[method].first)
|
7
7
|
|
8
|
-
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
8
|
+
- field_order.each do |field|
|
9
|
+
|
10
|
+
- case field
|
11
|
+
- when :full_name
|
12
|
+
- if use_full_name || fa.object.errors.include?(:full_name)
|
13
|
+
= fa.input :full_name, :required => true, :label => 'Full name', :placeholder => 'Full name'
|
14
|
+
|
15
|
+
- when :address1
|
16
|
+
= fa.input :address1, :placeholder => 'Address', :label => "Address 1"
|
17
|
+
|
18
|
+
- when :address2
|
19
|
+
= fa.input :address2, :label => 'Address 2'
|
20
|
+
|
21
|
+
- when :city
|
22
|
+
= fa.input :city, :placeholder => 'City'
|
23
|
+
|
24
|
+
- when :country_code
|
25
|
+
= fa.input :country_code,
|
26
|
+
:as => :select,
|
27
|
+
:label => 'Country',
|
28
|
+
:prompt => 'Country...',
|
29
|
+
:collection => region_options_for_select(EffectiveAddresses.country_codes == :all ? Carmen::Country.all : Carmen::Country.all.select{ |c| EffectiveAddresses.country_codes.include?(c.code) rescue true}, fa.object.country_code, :priority => EffectiveAddresses.country_codes_priority),
|
30
|
+
:input_html => { 'data-effective-address-country' => uuid }
|
31
|
+
|
32
|
+
- when :state_code
|
33
|
+
- if fa.object.country_code.present?
|
34
|
+
= fa.input :state_code, :as => :select, :label => 'Province / State',
|
35
|
+
:collection => region_options_for_select(Carmen::Country.coded(fa.object.country_code).subregions, fa.object.state_code),
|
36
|
+
:prompt => 'please select a country',
|
37
|
+
:input_html => { 'data-effective-address-state' => uuid }
|
38
|
+
- else
|
39
|
+
= fa.input :state_code, :as => :select, :label => 'Province / State',
|
40
|
+
:collection => [],
|
41
|
+
:prompt => 'please select a country',
|
42
|
+
:input_html => {:disabled => 'disabled', 'data-effective-address-state' => uuid}
|
43
|
+
|
44
|
+
- when :postal_code
|
45
|
+
= fa.input :postal_code, :label => 'Postal / Zip code', :placeholder => 'Postal / Zip code'
|
@@ -5,19 +5,30 @@
|
|
5
5
|
- if ((f.object.errors.include?(method) && !f.object.errors.include?(:addresses)) rescue false)
|
6
6
|
- fa.object.errors.add(:address1, f.object.errors[method].first)
|
7
7
|
|
8
|
-
-
|
9
|
-
= fa.input :full_name, :required => required
|
8
|
+
- field_order.each do |field|
|
10
9
|
|
10
|
+
- case field
|
11
|
+
- when :full_name
|
12
|
+
- if use_full_name || fa.object.errors.include?(:full_name)
|
13
|
+
= fa.input :full_name, :required => required
|
11
14
|
|
12
|
-
|
13
|
-
|
14
|
-
= fa.input :city, :required => required
|
15
|
+
- when :address1
|
16
|
+
= fa.input :address1, :required => required
|
15
17
|
|
16
|
-
|
18
|
+
- when :address2
|
19
|
+
= fa.input :address2
|
17
20
|
|
18
|
-
|
19
|
-
|
20
|
-
- else
|
21
|
-
= fa.input :state_code, :as => :select, :disabled => true, :collection => [], :input_html => { 'data-effective-address-state' => uuid }, :required => required
|
21
|
+
- when :city
|
22
|
+
= fa.input :city, :input_html => { 'data-effective-address-city' => uuid }, :required => required
|
22
23
|
|
23
|
-
|
24
|
+
- when :country_code
|
25
|
+
= fa.input :country_code, :as => :select, :collection => region_options_for_simple_form_select(), :input_html => {'data-effective-address-country' => uuid}, :required => required
|
26
|
+
|
27
|
+
- when :state_code
|
28
|
+
- if fa.object.try(:country_code).present?
|
29
|
+
= fa.input :state_code, :as => :select, :collection => region_options_for_simple_form_select(Carmen::Country.coded(fa.object.country_code).subregions), :input_html => {'data-effective-address-state' => uuid}, :required => required
|
30
|
+
- else
|
31
|
+
= fa.input :state_code, :as => :select, :disabled => true, :collection => [], :input_html => { 'data-effective-address-state' => uuid }, :required => required
|
32
|
+
|
33
|
+
- when :postal_code
|
34
|
+
= fa.input :postal_code, :input_html => { 'data-effective-address-postal-code' => uuid }, :required => required
|
data/lib/effective_addresses.rb
CHANGED
@@ -13,13 +13,15 @@ EffectiveAddresses.setup do |config|
|
|
13
13
|
# Select these countries ontop of the others
|
14
14
|
config.country_codes_priority = ['US', 'CA'] # nil for no priority countries
|
15
15
|
|
16
|
-
#
|
17
|
-
# Valid values are: country code, country name, or nil
|
16
|
+
# Force this country to be preselected on any new address forms.
|
17
|
+
# Valid values are: country code, country name, or nil.
|
18
|
+
# Leave nil if using Geocoder for IP based discovery.
|
18
19
|
config.pre_selected_country = nil
|
19
20
|
|
20
|
-
#
|
21
|
+
# Force this state to be preselected on any new address forms.
|
21
22
|
# Must also define pre_selected_country for this to take affect
|
22
|
-
# Valid values are: state code, state name, or nil
|
23
|
+
# Valid values are: state code, state name, or nil.
|
24
|
+
# Leave nil if using Geocoder for IP based discovery.
|
23
25
|
config.pre_selected_state = nil
|
24
26
|
|
25
27
|
# Validate that the postal/zip code format is correct for these countries
|
@@ -1,24 +1,24 @@
|
|
1
1
|
class User < ActiveRecord::Base
|
2
|
-
structure do
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
end
|
2
|
+
# structure do
|
3
|
+
# # Devise attributes
|
4
|
+
# encrypted_password :string
|
5
|
+
# reset_password_token :string
|
6
|
+
# reset_password_sent_at :datetime
|
7
|
+
# remember_created_at :datetime
|
8
|
+
# confirmation_sent_at :datetime
|
9
|
+
# confirmed_at :datetime
|
10
|
+
# confirmation_token :string
|
11
|
+
# unconfirmed_email :string
|
12
|
+
# sign_in_count :integer, :default => 0
|
13
|
+
# current_sign_in_at :datetime
|
14
|
+
# last_sign_in_at :datetime
|
15
|
+
# current_sign_in_ip :string
|
16
|
+
# last_sign_in_ip :string
|
17
|
+
#
|
18
|
+
# email :string
|
19
|
+
# first_name :string
|
20
|
+
# last_name :string
|
21
|
+
#
|
22
|
+
# timestamps
|
23
|
+
# end
|
24
24
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: effective_addresses
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Code and Effect
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-09-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -80,20 +80,6 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: migrant
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - ">="
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '0'
|
90
|
-
type: :runtime
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - ">="
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '0'
|
97
83
|
- !ruby/object:Gem::Dependency
|
98
84
|
name: rspec-rails
|
99
85
|
requirement: !ruby/object:Gem::Requirement
|