From 0eff6956a55882817f67c8d471d32ed3e4b109ee Mon Sep 17 00:00:00 2001 From: Pietro Moro <33845712+pietro-moro@users.noreply.github.com> Date: Fri, 26 Jul 2019 20:54:57 +0200 Subject: Added a phone_to helper method, on the style of mail_to and sms_to. (#36775) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Added a phone_to helper method, on the style of mail_to and sms_to. It creates an anchor tag with the href set to tel: *here your number* which, when clicked on a mobile phone, or on a desktop with a supported application, lets the phone app kick in, and it prepopulates it with the phone number specified. [Pietro Moro + Rafael Mendonça França] --- actionview/CHANGELOG.md | 4 ++ actionview/lib/action_view/helpers/url_helper.rb | 47 +++++++++++++++++ actionview/test/template/url_helper_test.rb | 64 ++++++++++++++++++++++++ 3 files changed, 115 insertions(+) (limited to 'actionview') diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md index 504b1d3e98..ca3ce1476a 100644 --- a/actionview/CHANGELOG.md +++ b/actionview/CHANGELOG.md @@ -1,3 +1,7 @@ +* Added `phone_to` helper method to create a link from mobile numbers + + *Pietro Moro* + * annotated_source_code returns an empty array so TemplateErrors without a template in the backtrace are surfaced properly by DebugExceptions. diff --git a/actionview/lib/action_view/helpers/url_helper.rb b/actionview/lib/action_view/helpers/url_helper.rb index 85fd549177..9b4116834e 100644 --- a/actionview/lib/action_view/helpers/url_helper.rb +++ b/actionview/lib/action_view/helpers/url_helper.rb @@ -619,6 +619,53 @@ module ActionView content_tag("a", name || phone_number, html_options, &block) end + # Creates a TEL anchor link tag to the specified +phone_number+, which is + # also used as the name of the link unless +name+ is specified. Additional + # HTML attributes for the link can be passed in +html_options+. + # + # When clicked, the default app to make calls is opened, and it + # is prepopulated with the passed phone number and optional + # +country_code+ value. + # + # +phone_to+ has a optional +country_code+ option which automatically adds the country + # code as well as the + sign in the phone numer that gets prepopulated, + # for example if +country_code: "01"+ +\+01+ will be prepended to the + # phone numer, by passing special keys to +html_options+. + # + # ==== Options + # * :country_code - Prepends the country code to the number + # + # ==== Examples + # phone_to "1234567890" + # # => 1234567890 + # + # phone_to "1234567890", "Phone me" + # # => Phone me + # + # phone_to "1234567890", "Phone me", country_code: "01" + # # => Phone me + # + # You can use a block as well if your link target is hard to fit into the name parameter. \ERB example: + # + # <%= phone_to "1234567890" do %> + # Phone me: + # <% end %> + # # => + # Phone me: + # + def phone_to(phone_number, name = nil, html_options = {}, &block) + html_options, name = name, nil if block_given? + html_options = (html_options || {}).stringify_keys + + country_code = html_options.delete("country_code").presence + country_code = country_code.nil? ? "" : "+#{ERB::Util.url_encode(country_code)}" + + encoded_phone_number = ERB::Util.url_encode(phone_number) + html_options["href"] = "tel:#{country_code}#{encoded_phone_number}" + + content_tag("a", name || phone_number, html_options, &block) + end + private def convert_options_to_data_attributes(options, html_options) if html_options diff --git a/actionview/test/template/url_helper_test.rb b/actionview/test/template/url_helper_test.rb index bce6e7f370..d1570553dd 100644 --- a/actionview/test/template/url_helper_test.rb +++ b/actionview/test/template/url_helper_test.rb @@ -770,6 +770,70 @@ class UrlHelperTest < ActiveSupport::TestCase assert_equal({ class: "special" }, options) end + def test_phone_to + assert_dom_equal %{1234567890}, + phone_to("1234567890") + assert_dom_equal %{Bob}, + phone_to("1234567890", "Bob") + assert_dom_equal( + %{Bob}, + phone_to("1234567890", "Bob", "class" => "phoner") + ) + assert_equal phone_to("1234567890", "Bob", "class" => "admin"), + phone_to("1234567890", "Bob", class: "admin") + end + + def test_phone_to_with_options + assert_dom_equal( + %{Phone}, + phone_to("1234567890", "Phone", class: "example-class", country_code: "01") + ) + + assert_dom_equal( + %{Phone}, + phone_to("1234567890", "Phone", country_code: "01") + ) + end + + def test_phone_with_img + assert_dom_equal %{}, + phone_to("1234567890", raw('')) + end + + def test_phone_with_html_safe_string + assert_dom_equal( + %{1+234567890}, + phone_to(raw("1+234567890")) + ) + end + + def test_phone_with_nil + assert_dom_equal( + %{}, + phone_to(nil) + ) + end + + def test_phone_returns_html_safe_string + assert_predicate phone_to("1234567890"), :html_safe? + end + + def test_phone_with_block + assert_dom_equal %{Phone}, + phone_to("1234567890") { content_tag(:span, "Phone") } + end + + def test_phone_with_block_and_options + assert_dom_equal %{Phone}, + phone_to("1234567890", country_code: "01", class: "special") { content_tag(:span, "Phone") } + end + + def test_phone_does_not_modify_html_options_hash + options = { class: "special" } + phone_to "1234567890", "ME!", options + assert_equal({ class: "special" }, options) + end + def protect_against_forgery? request_forgery end -- cgit v1.2.3