pico_phone-rails 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0524cbb733d2edc10a4a6f0fcb13197f2853d58f437286c7aea7bf4c30d53092
4
- data.tar.gz: b29da13e7d7308a7e4e60fda8be21fbd467a5e138e6d6509ce97a719cac77afd
3
+ metadata.gz: ad67a4a67bfcdfd2e94072a2989dd25c23896ed5d97ef6b506a08c31548fe9f1
4
+ data.tar.gz: 1414db39189fdaed84124aaf1e10e8abb5ed02414668130a9f37ceb4b682ccad
5
5
  SHA512:
6
- metadata.gz: c82086362cc5c8dcf692ba712c7a961b076c2d87becfd5d3ff9ccece17d7a1da095558d76748b83ecdee46fc6067c884671d6f681e2b037cf14fb06ffccc9e05
7
- data.tar.gz: 0cc7b9175ebdbef5c3cddbabae8fbb8b8705b5cd7a8ffbce7077b4ef46510f895401bd6699105601d8ce13730692f09c513e4503568fe3dd2e17c4850a80bd8f
6
+ metadata.gz: 6aaeb277b412aa8acea4729c56a9e1c371a3e967cf4c4162d9aa430e1409842e075cf810ff2db665b605dff47ebd18e85d3367cbff4c7652fc6ed92563371700
7
+ data.tar.gz: e31a7f628e3b16386fc79ccc3f0d9ceb67d41db69901ccbe7ff455475da9afc3e5a05fc316b5f85946071eb4e333bb7f9e0bb10a92955d3bb99bd5f721f89b7a
data/README.md CHANGED
@@ -181,6 +181,31 @@ reasoning as `containing_phone_number` above.
181
181
  every model, so identical names would collide and one would silently shadow
182
182
  the other.)
183
183
 
184
+ ### Form field helper
185
+
186
+ ```ruby
187
+ <%= pico_phone_field_tag :phone, @contact.phone, region: "US" %>
188
+ <%= f.pico_phone_field :phone, region: "US" %>
189
+ ```
190
+
191
+ Renders an `<input type="tel">` showing the number in national format when
192
+ it parses validly, or exactly what the user typed otherwise -- so re-editing
193
+ an invalid or partial number never shows a blank or garbled reformat. Works
194
+ whether the attribute is a plain string or already a `PicoPhone::PhoneNumber`
195
+ (via the attribute type above), and accepts `region:` as a String, Symbol
196
+ (instance method on the form's object), or Proc, same resolution rules as
197
+ extraction and the search index:
198
+
199
+ ```ruby
200
+ f.pico_phone_field :phone, region: ->(contact) { contact.organization.region }
201
+ ```
202
+
203
+ Named `pico_phone_field`/`pico_phone_field_tag` rather than Rails' own
204
+ `phone_field`/`f.phone_field` (an existing core alias for `telephone_field`,
205
+ a plain `<input type="tel">` with no formatting) -- redefining a core Rails
206
+ helper would silently change behavior for every `phone_field` call in an
207
+ app, not just ones backed by a PicoPhone-managed attribute.
208
+
184
209
  ### ActiveJob serializer
185
210
 
186
211
  ```ruby
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PicoPhone
4
+ module Rails
5
+ # Computes what a phone field should display: the number's national
6
+ # format if it parses validly, the raw string otherwise -- so a user
7
+ # re-editing an invalid or partial number sees exactly what they typed,
8
+ # not a blank or garbled reformat. Shared by {FormHelper} and
9
+ # {FormBuilderExtension}.
10
+ #
11
+ # @param value [String, PicoPhone::PhoneNumber, nil]
12
+ # @param region [String, nil] ISO 3166-1 alpha-2 region for interpreting +value+ when it's a raw string
13
+ # @return [String, nil]
14
+ def self.phone_field_display_value(value, region)
15
+ return nil if value.nil?
16
+ return (value.valid? ? value.national : value.to_s) if value.is_a?(PicoPhone::PhoneNumber)
17
+
18
+ string = value.to_s
19
+ return string if string.empty?
20
+
21
+ phone_number = PicoPhone.parse(string, region)
22
+ phone_number.valid? ? phone_number.national : string
23
+ end
24
+
25
+ # Included into ActionView::Base by the railtie once ActionView loads.
26
+ # Adds +pico_phone_field_tag+, a +text_field_tag+-like helper that
27
+ # displays national format for a valid number while leaving the
28
+ # underlying +<input>+ free to submit whatever string the user types.
29
+ #
30
+ # Named distinctly from Rails' own +phone_field_tag+/+f.phone_field+
31
+ # (a built-in alias for +telephone_field+, plain +<input type="tel">+
32
+ # with no formatting) rather than overriding it -- redefining a core
33
+ # Rails helper would silently change behavior for every +phone_field+
34
+ # call in an app, not just ones backed by a PicoPhone-managed attribute.
35
+ #
36
+ # @example
37
+ # pico_phone_field_tag :phone, @contact.phone, region: "US"
38
+ module FormHelper
39
+ # @param name [String, Symbol]
40
+ # @param value [String, PicoPhone::PhoneNumber, nil]
41
+ # @param region [String, nil] ISO 3166-1 alpha-2 region for interpreting +value+ when it's a raw string
42
+ # @return [String] an HTML-safe +<input type="tel">+ tag
43
+ def pico_phone_field_tag(name, value = nil, region: nil, **options)
44
+ display_value = PicoPhone::Rails.phone_field_display_value(value, region)
45
+ text_field_tag(name, display_value, options.merge(type: "tel"))
46
+ end
47
+ end
48
+
49
+ # Included into ActionView::Helpers::FormBuilder by the railtie once
50
+ # ActionView loads. Adds +f.pico_phone_field+, mirroring
51
+ # {FormHelper#pico_phone_field_tag} but bound to the form's object.
52
+ #
53
+ # @example
54
+ # f.pico_phone_field :phone, region: "US"
55
+ # f.pico_phone_field :phone, region: ->(contact) { contact.organization.region }
56
+ module FormBuilderExtension
57
+ # @param method [Symbol] the attribute to render
58
+ # @param region [String, Symbol, Proc, nil] ISO 3166-1 alpha-2 region for interpreting the attribute's
59
+ # raw value when it isn't already a {PicoPhone::PhoneNumber} -- a String is used as-is, a Symbol is
60
+ # called as an instance method on the form's object, a Proc is called with the object, same resolution
61
+ # rules as {Extraction.extract_phone_numbers_from} and {PhoneSearchIndex.maintain_phone_search_index}
62
+ # @return [String] an HTML-safe +<input type="tel">+ tag
63
+ def pico_phone_field(method, region: nil, **options)
64
+ resolved_region = PicoPhone::Rails.resolve_region(region, object)
65
+ display_value = PicoPhone::Rails.phone_field_display_value(object.public_send(method), resolved_region)
66
+ text_field(method, options.merge(value: display_value, type: "tel"))
67
+ end
68
+ end
69
+ end
70
+ end
@@ -37,6 +37,14 @@ module PicoPhone
37
37
  end
38
38
  end
39
39
 
40
+ initializer "pico_phone_rails.form_helper" do
41
+ ActiveSupport.on_load(:action_view) do
42
+ require "pico_phone/rails/form_helper"
43
+ include PicoPhone::Rails::FormHelper
44
+ ::ActionView::Helpers::FormBuilder.include PicoPhone::Rails::FormBuilderExtension
45
+ end
46
+ end
47
+
40
48
  initializer "pico_phone_rails.i18n" do |app|
41
49
  app.config.i18n.load_path += Dir[File.expand_path("locale/*.yml", __dir__)]
42
50
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module PicoPhone
4
4
  module Rails
5
- VERSION = "0.3.0"
5
+ VERSION = "0.4.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pico_phone-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gabi Jack
@@ -75,6 +75,7 @@ files:
75
75
  - lib/pico_phone/rails.rb
76
76
  - lib/pico_phone/rails/extracted_phone_number.rb
77
77
  - lib/pico_phone/rails/extraction.rb
78
+ - lib/pico_phone/rails/form_helper.rb
78
79
  - lib/pico_phone/rails/locale/en.yml
79
80
  - lib/pico_phone/rails/normalizer.rb
80
81
  - lib/pico_phone/rails/phone_search_index.rb