effective_addresses 1.2.4 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 41c69251c76730e7fe6cf466b4d892e39cdc9569
4
- data.tar.gz: 9561541536799e5f8f4d3fab9a8f23390c9d45d5
3
+ metadata.gz: 1e67a2c4ca21e0c16b9d61346e05f3533ba09b31
4
+ data.tar.gz: 659e413366e47d7c3c8b2469c8c0887f7cbade9a
5
5
  SHA512:
6
- metadata.gz: f135e6e8b0d6512f62df507af47590ca7b7aa2ab9a1960337afac042809b94099c025731542b698c342c9fd4c0f3eacc4e3041a1b5a33fbcfabae9160a6f0a14
7
- data.tar.gz: 4e49543e8691690ac0978dc2ae5b15dd0427c6450769f2660f0b7c4c982e9addb856495918c4b5d9c4173b68a3d01145e2d22868422671a769ed893ab838eb06
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. This example is in HAML:
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
- Currently only supports Formtastic and SimpleForm.
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
- 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`) which populates the province/state dropdown with the selected country's states or provinces.
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 = $(this).closest('form').find("select[data-effective-address-state='#{uuid}']").first()
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
- if address.new_record? && EffectiveAddresses.pre_selected_country.present?
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
- structure do
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
- - if use_full_name || fa.object.errors.include?(:full_name)
9
- = fa.input :full_name, :required => true, :label => 'Full name', :placeholder => 'Full name'
10
-
11
- = fa.input :address1, :placeholder => 'Address', :label => "Address 1"
12
- = fa.input :address2, :label => 'Address 2'
13
- = fa.input :city, :placeholder => 'City'
14
- = fa.input :country_code,
15
- :as => :select,
16
- :label => 'Country',
17
- :prompt => 'Country...',
18
- :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),
19
- :input_html => { 'data-effective-address-country' => uuid }
20
-
21
- - if fa.object.country_code.present?
22
- = fa.input :state_code, :as => :select, :label => 'Province / State',
23
- :collection => region_options_for_select(Carmen::Country.coded(fa.object.country_code).subregions, fa.object.state_code),
24
- :prompt => 'please select a country',
25
- :input_html => { 'data-effective-address-state' => uuid }
26
- - else
27
- = fa.input :state_code, :as => :select, :label => 'Province / State',
28
- :collection => [],
29
- :prompt => 'please select a country',
30
- :input_html => {:disabled => 'disabled', 'data-effective-address-state' => uuid}
31
-
32
- = fa.input :postal_code, :label => 'Postal / Zip code', :placeholder => 'Postal / Zip code'
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
- - if use_full_name || fa.object.errors.include?(:full_name)
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
- = fa.input :address1, :required => required
13
- = fa.input :address2
14
- = fa.input :city, :required => required
15
+ - when :address1
16
+ = fa.input :address1, :required => required
15
17
 
16
- = fa.input :country_code, :as => :select, :collection => region_options_for_simple_form_select(), :input_html => {'data-effective-address-country' => uuid}, :required => required
18
+ - when :address2
19
+ = fa.input :address2
17
20
 
18
- - if fa.object.try(:country_code).present?
19
- = 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
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
- = fa.input :postal_code, :required => required
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
@@ -1,6 +1,5 @@
1
1
  require "effective_addresses/engine"
2
2
  require "effective_addresses/version"
3
- require 'migrant' # Required for rspec to run properly
4
3
 
5
4
  module EffectiveAddresses
6
5
 
@@ -1,3 +1,3 @@
1
1
  module EffectiveAddresses
2
- VERSION = '1.2.4'.freeze
2
+ VERSION = '1.3.0'.freeze
3
3
  end
@@ -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
- # Preselect this country on any new address forms
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
- # Preselect this state on any new address forms
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
- # 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
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.2.4
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-08-14 00:00:00.000000000 Z
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