Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making intlTelInput and Jquery mask plugins to work together

I am trying to add the "mask" feature (from jquery mask plugin) to the intlTelInput plugin. This way, the user input will be "forced" to have the number phone pattern according to the country he selected.

Here is my code for now (which you should be able to run easily as I added online ressources):

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Hello</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
  <link href="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/11.0.14/css/intlTelInput.css" rel="stylesheet" />
  <script src="https://code.jquery.com/jquery-1.11.1.js"></script>


    <script src="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/11.0.14/js/utils.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/11.0.14/js/intlTelInput.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.mask/1.14.11/jquery.mask.js"></script>

</head>


<body>

      <form action="" method="POST" onsubmit="return submitForm(this);">

            <input type="tel"name ="phone1" id="phone1" value="<?php echo $phone1;?>">

            <input type="tel" class="hide" id="hiden">

            <button type="submit">Validate</button>

      </form>


</body>



<script>

/* INITIALIZE BOTH INPUTS WITH THE intlTelInput FEATURE*/

$("#phone1").intlTelInput({
  initialCountry: "us",
  separateDialCode: true,
  preferredCountries: ["fr", "us", "gb"],
  geoIpLookup: function(callback) {
    $.get('https://ipinfo.io', function() {}, "jsonp").always(function(resp) {
      var countryCode = (resp && resp.country) ? resp.country : "";
      callback(countryCode);
    });
  },
  utilsScript: "https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/11.0.14/js/utils.js"
});


$("#hiden").intlTelInput({
  initialCountry: "us",
  dropdownContainer: 'body',
  utilsScript: "https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/11.0.14/js/utils.js"
});



/* ADD A MASK IN PHONE1 INPUT (when document ready and when changing flag) FOR A BETTER USER EXPERIENCE */

var mask1 = $("#phone1").attr('placeholder').replace(/[0-9]/g, 0);

$(document).ready(function(){
  $('#phone1').mask(mask1)});

$("#phone1").on("countrychange", function(e, countryData) {
  $("#phone1").val('');
  var mask1 = $("#phone1").attr('placeholder').replace(/[0-9]/g, 0);
  $('#phone1').mask(mask1);
});


/*ON SUBMIT...*/

function submitForm(oFormElement)
  {


  document.getElementById("hiden").value = $("#phone1").val().replace(/\s+/g, ''); // REMOVE ALL THE SPACES OF PHONE1 VALUE
                                                                                   // PUT THE RESULT IN HIDEN INPUT 
                                                                                   // AND TEST THIS LATTER TO SEE IF IT FITS WITH
                                                                                   // the intlTelInput NUMBER FORMAT

  //alert($("#hiden").val());


   // AND IT WILL DISPLAY OK
  if($("#hiden").intlTelInput("isValidNumber")==true){  
    alert("OK");
    return true;
  }
  else{
    alert("NOT OK");
    return false;
  }

}


</script>

The problem here, is that I can't remove the flags dropdown of the hidden field, as you can see:

enter image description here

I tried to add an option called dropdownContainer to the initialization of the hidden field. It says in the intltelinput doc that this option with the value 'body' should place the flag dropdown next to the container (in this case: 'body') and if this container has overflow: hidden then the flag would be actually hidden.

But as you can see, it does not work.

Thank you for your attention.

p.s:

  1. If you change the flag of the "phone1" input, you will have to change the "initialCountry" value manually for the "hiden" input. (I will fix this later).
  2. I already looked for a plugin with both features (from jquery mask and intlTellInput), and I did not find, but if you know one, please tell me.
like image 598
ThisIsMe Avatar asked Jun 14 '17 10:06

ThisIsMe


3 Answers

It is not professional to add a hidden input manually to apply this feature, especially when using plugins like this one which includes a lot of APIs and methods.

After studying the documentation of the intl-tel-input (https://github.com/jackocnr/intl-tel-input) and utils.js (https://github.com/jackocnr/intl-tel-input/wiki/utils.js), the solution can be like this:

Hook a callback function to the countrychange event to apply the mask based on the selected country.

Make sure to place this JS snippet in the footer or at least after the HTML input we're targeting.

// Make sure to place this snippet in the footer or at least after
// the HTML input we're targeting.

$(document).ready(function() {
  var phoneInputID = "#phone";
  var input = document.querySelector(phoneInputID);
  var iti = window.intlTelInput(input, {
    // allowDropdown: false,
    // autoHideDialCode: false,
    // autoPlaceholder: "off",
    // dropdownContainer: document.body,
    // excludeCountries: ["us"],
    formatOnDisplay: true,
    // geoIpLookup: function(callback) {
    //   $.get("http://ipinfo.io", function() {}, "jsonp").always(function(resp) {
    //     var countryCode = (resp && resp.country) ? resp.country : "";
    //     callback(countryCode);
    //   });
    // },
    hiddenInput: "full_number",
    // initialCountry: "auto",
    // localizedCountries: { 'de': 'Deutschland' },
    // nationalMode: false,
    // onlyCountries: ['us', 'gb', 'ch', 'ca', 'do'],
    // placeholderNumberType: "MOBILE",
    preferredCountries: ['es'],
    // separateDialCode: true,
    utilsScript: "https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/11.0.14/js/utils.js"
  });


  $(phoneInputID).on("countrychange", function(event) {

    // Get the selected country data to know which country is selected.
    var selectedCountryData = iti.getSelectedCountryData();

    // Get an example number for the selected country to use as placeholder.
    newPlaceholder = intlTelInputUtils.getExampleNumber(selectedCountryData.iso2, true, intlTelInputUtils.numberFormat.INTERNATIONAL),

      // Reset the phone number input.
      iti.setNumber("");

    // Convert placeholder as exploitable mask by replacing all 1-9 numbers with 0s
    mask = newPlaceholder.replace(/[1-9]/g, "0");

    // Apply the new mask for the input
    $(this).mask(mask);
  });


  // When the plugin loads for the first time, we have to trigger the "countrychange" event manually, 
  // but after making sure that the plugin is fully loaded by associating handler to the promise of the 
  // plugin instance.

  iti.promise.then(function() {
    $(phoneInputID).trigger("countrychange");
  });

});
<html>

<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.12/js/intlTelInput.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.mask/1.14.11/jquery.mask.js"></script>
  <link href="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.12/css/intlTelInput.css" rel="stylesheet" />
</head>

<body>
  <input type="tel" id="phone" name="phone" />
</body>

</html>
like image 124
Ahmed El-Atab Avatar answered Nov 19 '22 00:11

Ahmed El-Atab


You could select the input element with jquery, and hide its parent. Works in my example:

Code required: $('input.hide').parent().hide();

Please note you will probably need a better class then hide because using my exact method will cause side-effects if you hide other input fields. Try a class like hide-parent instead. I've just used this because it works in your example.

Example:

/* INITIALIZE BOTH INPUTS WITH THE intlTelInput FEATURE*/

$("#phone1").intlTelInput({
    initialCountry: "us",
    separateDialCode: true,
    preferredCountries: ["fr", "us", "gb"],
    geoIpLookup: function (callback) {
        $.get('https://ipinfo.io', function () {
        }, "jsonp").always(function (resp) {
            var countryCode = (resp && resp.country) ? resp.country : "";
            callback(countryCode);
        });
    },
    utilsScript: "https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/11.0.14/js/utils.js"
});


$("#hiden").intlTelInput({
    initialCountry: "us",
    dropdownContainer: 'body',
    utilsScript: "https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/11.0.14/js/utils.js"
});


/* ADD A MASK IN PHONE1 INPUT (when document ready and when changing flag) FOR A BETTER USER EXPERIENCE */

var mask1 = $("#phone1").attr('placeholder').replace(/[0-9]/g, 0);

$(document).ready(function () {
    $('#phone1').mask(mask1)
});

$("#phone1").on("countrychange", function (e, countryData) {
    $("#phone1").val('');
    var mask1 = $("#phone1").attr('placeholder').replace(/[0-9]/g, 0);
    $('#phone1').mask(mask1);
});


/*ON SUBMIT...*/

function submitForm(oFormElement) {


    document.getElementById("hiden").value = $("#phone1").val().replace(/\s+/g, ''); // REMOVE ALL THE SPACES OF PHONE1 VALUE
                                                                                     // PUT THE RESULT IN HIDEN INPUT 
                                                                                     // AND TEST THIS LATTER TO SEE IF IT FITS WITH
                                                                                     // the intlTelInput NUMBER FORMAT

    //alert($("#hiden").val());


    // AND IT WILL DISPLAY OK
    if ($("#hiden").intlTelInput("isValidNumber") == true) {
        alert("OK");
        return true;
    }
    else {
        alert("NOT OK");
        return false;
    }

}

$('input.hide').parent().hide();
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link href="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/11.0.14/css/intlTelInput.css" rel="stylesheet" />
<script src="https://code.jquery.com/jquery-1.11.1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/11.0.14/js/utils.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/11.0.14/js/intlTelInput.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.mask/1.14.11/jquery.mask.js"></script>


<form action="" method="POST" onsubmit="return submitForm(this);">

    <input type="tel"name ="phone1" id="phone1" value="<?php echo $phone1;?>">

    <input type="tel" class="hide" id="hiden">

    <button type="submit">Validate</button>

</form>
like image 40
Randy Avatar answered Nov 19 '22 00:11

Randy


Here's my (lighter) jQuery take at it:

<label for="telephone">Téléphone</label>
<input id="telephone" name="telephone" type="tel">
$('#telephone').on('focus', function(){
    var $this = $(this),
        // Get active country's phone number format from input placeholder attribute
        activePlaceholder = $this.attr('placeholder'),
        // Convert placeholder as exploitable mask by replacing all 1-9 numbers with 0s
        newMask = activePlaceholder.replace(/[1-9]/g, "0");
        // console.log(activePlaceholder + ' => ' + newMask);

    // Init new mask for focused input
    $this.mask(newMask);
});

No need to double-input. Works everytime you select a new country.

like image 1
frontenddeveloper.0fees.net Avatar answered Nov 19 '22 00:11

frontenddeveloper.0fees.net