Press "Enter" to skip to content

An International Telephone Input With Flags And Dial Codes Blazor Component

Elev8Technologies 0

Our Family Reunification Service (FRS) can digitally collect information in over 200 languages. As part of supporting multiple languages and being able to accept contact information from individuals that may be visiting from a different country, our solutions need to be able to collect international phone numbers.

For example, here’s a US-based number in standard local formatting: (415) 555-2671

Here’s the same phone number in E.164 formatting: +14155552671

In several countries, local dialing may require adding a ‘0‘ in front of the subscriber number.

For example, here’s a UK-based number in standard local formatting: 020 7183 8750

Here’s the same phone number in E.164 formatting: +442071838750

If you do a quick internet search for “international-telephone-input”, there are several JavaScript-based controls, and we even found a Blazor-specific control. The issue with all the controls that we looked at was they had a big dependency on JavaScript. We try to avoid JavaScript as much as possible due to compatibility issues across devices, form factors, operating systems, browsers, etc. The other issue we encountered was a lot of additional functionality that we didn’t want to introduce into our solution. One developer had tried to determine the country based on the IP address. Another added a lot of JavaScript code to perform validation on the input.

Our tool of choice for development is Blazor. We took some of the common ideas from several controls we tested and created a simple Blazor component that can be dropped onto any page and enhanced as needed.

One of the common ideas we implemented was using the flag of the country to pick the correct country code. This is introduced in a single image file, and using CSS to clip the image to display the correct flag. Below is a sample from the image.

And below is a sample from the CSS file

There is a dependency on Bootstrap. You can use the CDN version from jsdeliver.net

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">

  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>

 The implementation is pretty basic, albeit long, when you look at what is in the UL. Below is a sample.

<div class="input-group mb-3">
    <button class="btn dropdown-toggle intphone-country-select" type="button" data-bs-toggle="dropdown" aria-expanded="false"><div class="flag-box">
        <div class="flag @_flagClass"></div>
    </div></button>
    
    <ul class="dropdown-menu country-list">
    <li class="country" @onclick="@(e => SetCountry(1,"us"))">
            <div class="flag-box">
                <div class="flag us"></div>
            </div>
            <span class="country-name">United States</span>
            <span class="dial-code">+1</span>
        </li>
        <li class="country" @onclick="@(e => SetCountry(44, "gb"))">
            <div class="flag-box">
                <div class="flag gb"></div>
            </div>
            <span class="country-name">United Kingdom</span>
            <span class="dial-code">+44</span>
        </li>
        <li class="divider"></li>
        <li class="country" @onclick="@(e => SetCountry(93,"af"))">
            <div class="flag-box">
                <div class="flag af"></div>
            </div>
            <span class="country-name">Afghanistan</span>
            <span class="dial-code">+93</span>
        </li>
        <li class="country" @onclick="@(e => SetCountry(358,"ax"))">
            <div class="flag-box">
                <div class="flag ax"></div>
            </div>
            <span class="country-name">Aland Islands</span>
            <span class="dial-code">+358</span>
        </li>
        <li class="country" @onclick="@(e => SetCountry(355,"al"))">
            <div class="flag-box">
                <div class="flag al"></div>
            </div>
            <span class="country-name">Albania</span>
            <span class="dial-code">+355</span>
        </li>
        {... and a bunch more of this}
    </ul>
    <input id="@Id" class="@Class" value="@BindingValue" @onchange="@SetTelephoneNumber" />
    
</div>

The UL class dropdown-menu is a Bootstrap class that creates the dropdown list to be displayed on the click of the button.

Below is the code portion:

[Parameter]
    public string BindingValue
    {
        get => string.IsNullOrEmpty(_value) ? "+1 " : _value;
        set
        {
            if (_value == value) return;
            _value = value;
            BindingValueChanged.InvokeAsync(value);
            Change.InvokeAsync(value);
        }
    }

    [Parameter] public EventCallback<string> BindingValueChanged { get; set; }
    [Parameter] public EventCallback<string> Change { get; set; }
    [Parameter] public string Id { get; set; }
    [Parameter] public string Class { get; set; }

    private string _value;
    private int _dialCode = 1;
    private string _telephoneNumber = string.Empty;
    private string _flagClass = "us";

    private class CountryInfo
    {
        public string CountryAbb {get; set; }
        public int DialCode {get;set;}
    }
    
    protected void SetCountry(int dialCode,string flagClass)
    {
        _flagClass = flagClass;
        _dialCode = dialCode;
        BindingValue = $"+{_dialCode} {_telephoneNumber}";
    }
    protected void SetTelephoneNumber(ChangeEventArgs args)
    {
        _telephoneNumber = args.Value?.ToString() ?? string.Empty;
        BindingValue = _telephoneNumber;

    }

Below is an example implementation of the component using the Change event

<InternationalPhoneNumber Id="{someId}" Class="{someclass}" 
                                              Change="@((e => UpdateDynamicDataPhone(e, {somevalue})))"></InternationalPhoneNumber>

and here is an example using the bind-BindingValue

           <InternationalPhoneNumber Id="{someId}" Class="form-control" 
                                                          @bind-BindingValue="{someModel.property}"></InternationalPhoneNumber>

If you want a copy of the code and an example I will be publishing it a repo in our Github.

https://github.com/Elev8Technologies/International-telephone-input

Leave a Reply

%d bloggers like this: