<main>
  <p>Type a phone number and it formats as you type.</p>

  <input data-phone_number /><br /><br />
  <div data-phone_number class="info"></div>

  <br /><br />
  <button id="get_data">show data in console</button>
</main>
@import url('https://fonts.googleapis.com/css?family=Open+Sans:700&display=swap');

html,
body {
  height: 100vh;
  margin: 0;
  padding: 0;
}
body {
  display: grid;
  place-items: center;
}

main {
  display: flex;
  flex-direction: column;
  height: 200px;
  width: 400px;
}

main p {
  font-family: 'Open Sans', sans-serif;
  font-size: 16px;
}

main input {
  border: 2px solid rebeccapurple;
  font-family: 'Open Sans', sans-serif;
  font-size: 16px;
  margin-bottom: 8px;
  padding: 8px 16px;
}

main button {
  background-color: white;
  border: 3px solid rebeccapurple;
  border-radius: 7px;
  color: rebeccapurple;
  cursor: pointer;
  font-family: 'Open Sans', sans-serif;
  font-size: 16px;
  font-weight: 700;
  padding: 8px 16px;
}
main button:hover {
  background-color: lavender;
}
main button:active {
  background-color: rebeccapurple;
  color: white;
}
main button:focus-visible {
  box-shadow: 0 0 0 2px white, 0 0 0 5px rebeccapurple;
  outline: none;
}

main .info {
  display: flex;
  font-family: 'Open Sans', sans-serif;
  font-size: 24px;
  height: 24px;
  line-height: 24px;
  margin: 8px 0 16px;
}
const phone = new Proxy(
  {
    _clean: '',
    number: '',
    get clean() {
      return this._clean;
    }
  },
  {
    get: function (target, prop) {
      if (!prop.startsWith('_')) {
        return target[prop];
      } else {
        return 'entry not found!'
      }
    },
    set: function (target, prop, value) {
      if (!prop.startsWith('_')) {        
        target._clean = value.replace(/\D/g, '').substring(0, 10);

        const sections = {
          area: target._clean.substring(0, 3),
          prefix: target._clean.substring(3, 6),
          line: target._clean.substring(6, 10)
        }

        target.number = 
          target._clean.length > 6 ? `(${sections.area}) ${sections.prefix}-${sections.line}` :
          target._clean.length > 3 ? `(${sections.area}) ${sections.prefix}` :
          target._clean.length > 0 ? `(${sections.area}` : '';

        document.querySelectorAll('[data-phone_number]').forEach(item => {
          if (item.tagName === 'INPUT') {
            item.value = target.number;
          } else {
            item.innerText = target.number;
          }
        });

        return true;
      } else {
        return false;
      }
    }
  }
);

document.querySelectorAll('input[data-phone_number]').forEach(item => {
  item.addEventListener('input', (e) => {
    phone.number = e.target.value;
  });
});

document.querySelector('#get_data').addEventListener('click', (e) => {
  console.log(phone.number); // (123) 456-7890
  console.log(phone.clean); // 1234567890
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.