📜 ⬆️ ⬇️

Selection of the input mask by phone number

This jQuery plugin allows you to automatically select the appropriate input mask based on the entered beginning of the phone number. This allows you to make entering the phone number on the website page faster and more error-free. In addition, the developed plugin can be used in other areas, if the input rules can be represented in the form of several input masks.

Introduction


Web sites require input of phone number information. It so happened that each country has the right to set its own rules for dialing and the length of the number, resulting in confusion between residents of different countries: some are used to indicate the number with the leading number 8 , others with the leading number 0 , and still others with the + sign.

Review of existing solutions


In order to somehow resolve the arisen complexity and bring the numbers to a single format, there are 3 main solutions:
  1. The user is prompted to enter the number using the input mask. Advantage: the visual display of the number minimizes possible errors in the room. Disadvantage: each country has its own spelling and number length.
  2. The user is prompted to select a country separately and separately enter the rest of the number; possibly using an input mask. Advantage: the ability to use different input masks for different countries (as well as regions within the country). Disadvantages: the list of countries (and regions within each country) can be large; the phone number ceases to exist as a whole (or preprocessing is required before storing and displaying the number).
  3. Put the + sign in front of the number (outside input) and allow only the input of numbers. Advantages: ease of implementation. Disadvantage: no visual display of the number.


Proposed Solution


As a result, it was decided to modify the usual input mask so that it changed in accordance with the current value of the number. In addition, as you enter the number, it is proposed to display the name of the determined country. This approach, subjectively, should solve all the shortcomings of the above solutions.
')
Given that the number of countries in the world is relatively small, it was decided to compile a list of input masks for all countries. As a source, information published on the website of the International Telecommunication Union was used.

The collection of this information gave a lot of surprises. In the process of collecting information, it was necessary to take into account all possible variants of telephone numbers, including domestically. However, due to the large amount of manually processed information, it is possible that there were inaccuracies in the collected database. Over time, it is planned to make corrections to the initial set.

Software implementation


As the of the input mask, the jquery.inputmask implementation was used, which was repeatedly mentioned in Habrahabr. This plugin is now actively developing and, moreover, it is designed in such a way that it is enough for it to simply write extensions. However, in this task, it was almost impossible to write such an extension. I did not finish or rewrite the original plugin to fit my needs, because its author continues to actively work on expanding the functionality, as a result of which the application of my edits can be problematic. So I had to write a plugin add-on over the main core, which monitors (plus intercepts) external influences and modifies the data. In order to implement their external impact handlers before the main plug-in handlers, the jquery.bind-first plugin library was used .

Sorting allowed input masks

To correctly select the most appropriate input mask, the entire set of masks must be pre-sorted in a special way. In developing the rules for sorting, the following conventions were adopted:
  1. All the characters in the input mask are divided into 2 types: meaningful characters (in my case it is the # symbol, meaning an arbitrary digit, and numbers 0-9) and decorator symbols (all the rest).
  2. Another division of characters in the input mask is template characters (in my case it is the # character) and all the others.


The result is the following sorting rules in the order in which they are applied:
  1. When comparing 2 input masks character by character, only significant characters are taken into account (not decorators).
  2. Different wildcard characters are perceived as equal, and other significant characters are compared based on their code.
  3. Non-generic characters are always less patterned and as a result are placed higher.
  4. The shorter the length of significant characters in the input mask, the smaller the input mask is and is higher.


Search for a suitable input mask

When comparing input text with a regular mask from a sorted list, only the significant characters of each mask are taken into account. If the line is longer than the input mask, despite the fact that all previous characters have passed the test, this input mask is considered unsuitable. If several input masks satisfy the input text, the first one is returned. Then, in the found mask, all significant characters (including non-template ones) are replaced with wildcard characters, which is a combination of all the characters allowed by any of the wildcard characters.

Event Handling and Interception

In order to prevent conflicts with the event handlers of the main kernel of the input mask, the following events are intercepted:


All events are in the inputmask space. This allows you to avoid incorrect behavior when calling inputmask after the add-in is initialized (since the kernel, during initialization, removes all previously installed handlers in the inputmask space).

Usage example


The format of the list of masks

The list of masks is a JavaScript array of objects, preferably with the same set of properties. At least one property that contains an input mask must be present for all objects in the array. The name of the parameter containing the mask can be arbitrary. Below is a fragment of such an array:
 [ … { "mask": "+7(###)###-##-##", "cc": "RU", "name_en": "Russia", "desc_en": "", "name_ru": "", "desc_ru": "" }, { "mask": "+250(###)###-###", "cc": "RW", "name_en": "Rwanda", "desc_en": "", "name_ru": "", "desc_ru": "" }, { "mask": "+966-5-####-####", "cc": "SA", "name_en": "Saudi Arabia ", "desc_en": "mobile", "name_ru": "  ", "desc_ru": "" }, { "mask": "+966-#-###-####", "cc": "SA", "name_en": "Saudi Arabia", "desc_en": "", "name_ru": " ", "desc_ru": "" }, … ] 


Plugin connection options

Before connecting you need to download and sort the list of masks. This is done by performing the following function:
 $.masksSort = function(maskList, defs, match, key) 



When connected, the plug-in is passed a special object that describes its operation. This object contains the following set of parameters:


To initialize the plugin, you need to apply the inputmasks method to the input field:
 $.fn.inputmasks = function(maskOpts, mode) 



Plugin connection example

 <input type="text" id="customer_phone" value="7" size="25"><br> <input type="checkbox" id="phone_mask" checked> <label id="descr" for="phone_mask"> </label> <script> var maskList = $.masksSort($.masksLoad("phone-codes.json"), ['#'], /[0-9]|#/, "mask"); var maskOpts = { inputmask: { definitions: { '#': { validator: "[0-9]", cardinality: 1 } }, //clearIncomplete: true, showMaskOnHover: false, autoUnmask: true }, match: /[0-9]/, replace: '#', list: maskList, listKey: "mask", onMaskChange: function(maskObj, completed) { if (completed) { var hint = maskObj.name_ru; if (maskObj.desc_ru && maskObj.desc_ru != "") { hint += " (" + maskObj.desc_ru + ")"; } $("#descr").html(hint); } else { $("#descr").html(" "); } $(this).attr("placeholder", $(this).inputmask("getemptymask")); } }; $('#phone_mask').change(function() { if ($('#phone_mask').is(':checked')) { $('#customer_phone').inputmasks(maskOpts); } else { $('#customer_phone').inputmask("+[####################]", maskOpts.inputmask) .attr("placeholder", $('#customer_phone').inputmask("getemptymask")); $("#descr").html(" "); } }); $('#phone_mask').change(); </script> 


Demonstration


An example of a demonstration of the developed plugin is presented on the project page .

Source: https://habr.com/ru/post/162537/


All Articles