<!-- Load Emoji One Support -->
<script src="https://cdn.jsdelivr.net/emojione/2.2.7/lib/js/emojione.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/emojione/2.2.7/assets/css/emojione.min.css"/>
<!-- Actual content -->
<p id="errorMessage" style="display: none;">
  THIS DEMO WORKS ONLY IN  BROWSER THAT SUPPORTS FETCH. Adjust the fetch call to use a different AJAX HTTP request to use it in other browsers.
</p>
<h1>Phone Validation Example</h1>
<form>
  <label for="phoneNumber">Phone Number</label>
  <input class="phone-input" id="phoneNumber" name="phoneNumber" type="tel" autocomplete="tel" required value="+14157012311" placeholder="Use international format">
  <span class="valid-indicator">
    <img class="emojione valid" alt="✅" title=":white_check_mark:" src="https://cdn.jsdelivr.net/emojione/assets/png/2705.png?v=2.2.7"/>
    <img class="emojione invalid" alt="❎" title=":negative_squared_cross_mark:" src="https://cdn.jsdelivr.net/emojione/assets/png/274e.png?v=2.2.7"/>
  </span>
  <span class="country-code"></span>
</form>
html, body {
  padding: 0;
  margin: 0;
  width: 100%;
  height: 100%;
  box-sizing: border-box;
}

body {
  font-family: ‘Trebuchet MS’, Helvetica, sans-serif;
  font-weight: 200;
  color: #333;
  border-top: 5px solid #F22F46;
  font-size: 25px;
  
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

h1 {
  font-weight: 100;
  color: #0D122B;
}

input {
  position: relative;
  font-size: 1em;
  padding: 10px;
  border: 2px solid #efefef;
}

/* Form specific styles */

.phone-input + .valid-indicator > .valid {
  display: initial;
}

.phone-input + .valid-indicator > .invalid {
  display: none;
}


.phone-input:invalid + .valid-indicator > .valid {
  display: none;
}

.phone-input:invalid + .valid-indicator > .invalid {
  display: initial;
}

.country-code[data-loading] > img {
  animation-name: rotatingEmoji;
  animation-duration: 1s;
  animation-iteration-count: infinite;
  animation-timing-function: linear;
}

@keyframes rotatingEmoji {
  from { transform: rotateZ(0deg) scaleX(-1); }
  to { transform: rotateZ(360deg) scaleX(-1); }
}
if (typeof fetch !== 'function') {
  document.getElementById('errorMessage').style.display = 'block';
}

var phoneNumberInput = document.getElementById('phoneNumber');
var countryFlag = document.querySelector('.country-code');
var lastTimeout = undefined;

phoneNumberInput.addEventListener('keyup', keyListener);

function keyListener() {
  if (lastTimeout) {
    clearTimeout(lastTimeout);
  }
  
  if (phoneNumberInput.value.length > 4) {
    lastTimeout = setTimeout(verifyNumber, 300);
  }
}

function verifyNumber() {
  showLoading();
  var currentNumber = phoneNumberInput.value;
  fetch('https://twilio-verify-number.now.sh/check/' + currentNumber)
    .then(function (response) {
      stopLoading();
      if (!response.ok) {
        throw new Error('Something went wrong with the HTTP call.');
      }
      return response.json();
    })
    .then(function (data) {  
      if (data.valid) {
        countryFlag.innerHTML = emojione.toImage(':flag_' + data.country.toLowerCase() + ':');
        phoneNumberInput.setCustomValidity('');
      } else {
        phoneNumberInput.setCustomValidity('Invalid phone number');
      }
    })
    .catch(function (err) {
      phoneNumberInput.setCustomValidity('Could not verify number');
      console.error(err.message);
  });
}

function showLoading() {
  countryFlag.setAttribute('data-loading', true);
  countryFlag.innerHTML = emojione.toImage(':arrows_counterclockwise:');
}

function stopLoading() {
  countryFlag.removeAttribute('data-loading');
  countryFlag.innerHTML = '';
}

keyListener();

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.