Input Mask

Masking input fields

by Leandro Barbosa

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.3/moment.min.js"></script>
<div class="margin">
  <label for="ssn">SSN</label>
  <div class="form-group">
    <input type="ssn" id="ssn" placeholder="this is ssn" class="js-mask" maxlength="9">
  </div>
</div>
<div class="margin">
  <label for="dob">DOB</label>
  <div class="form-group">
    <input type="dob" id="dob" placeholder="this is dob" class="js-mask" maxlength="8">
  </div>
</div>
<div class="margin">
  <label for="phone">PHONE</label>
  <div class="form-group">
    <input type="phone" id="phone" placeholder="this is phone" class="js-mask" maxlength="10">
  </div>
</div>
<div class="margin">
  <label for="any">ANY</label>
  <div class="form-group">
    <input type="any" id="any" placeholder="this is any" class="js-mask">
  </div>
</div>
<div class="margin">
  <label for="email">EMAIL</label>
  <div class="form-group">
    <input type="email" id="email" placeholder="this is email" class="js-mask">
  </div>
</div>

CSS

* {
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
}

html,
body,
div,
object,
iframe,
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote,
ol,
ul,
li,
form,
legend,
label,
table,
header,
footer,
nav,
section,
figure {
  margin: 0;
  padding: 0;
}

header,
footer,
nav,
section,
article,
hgroup,
figure {
  display: block;
}

.margin {
  margin: 20px;
}

.form-group {
  position: relative;
}

.masked-input-group {
  table-layout: fixed;
  width: 100%;
}

input.masked-input {
  min-height: 40px;
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  opacity: 0;
  border: 0;
  text-align: left !important;
  text-indent: -9999px;
  caret-color: rgba(0, 0, 0, 0);
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
  -webkit-text-fill-color: rgba(0, 0, 0, 0);
  z-index: 1;
  text-shadow: 0 0 0 rgba(0, 0, 0, 0);
  color: rgba(0, 0, 0, 0);
  font-size: 1px;
}

@supports (-webkit-overflow-scrolling: touch) {
  /* media query for iOS */
}

input.masked-input:focus {
  outline: 0;
}

input.masked-input.masked-input-toggle.form-control:first-child {
  border-right: 1px solid #ddd;
}

input.masked-input.masked-input-toggle.form-control:first-child:focus {
  border-color: #3e7cab;
}

input.masked-input.masked-input-toggle.active {
  position: static;
  opacity: 1;
  color: #4f4f4f;
  text-indent: 0;
  -webkit-text-fill-color: #4f4f4f;
}


/* IE bug fix */

@media all and (-ms-high-contrast: none),
(-ms-high-contrast: active) {
  input.masked-input.masked-input-toggle.active {
    text-indent: 0;
  }
}

input.masked-input.masked-input-toggle + .masked-output {
  display: table-cell;
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
  border-top-left-radius: 4px;
  border-bottom-left-radius: 4px;
}

input.masked-input.masked-input-toggle + .masked-output + .input-group-addon {
  width: 39px;
  cursor: pointer;
  position: relative;
  z-index: 3;
}

input.masked-input.masked-input-toggle:focus +...

JavaScript

/**
 * Custom masks
 * Usage:
 * <input type="ssn|dob|phone|email" class="js-custom-mask">
 * $('input.js-custom-mask').maskIt();
 *
 * Dependencies:
 *      jQuery - jquery.com
 *      Moment.js - momentjs.com
 */
(function($) {
  //Select all on input field focus
  $.fn.selectRange = function(s, e) {
    if (!s || !e) {
      s = 0;
      e = 9999;
    }
    $(this).each(function() {
      var el = $(this)[0];
      if (el) {
        el.focus();
        setTimeout(function() {
          if (el.setSelectionRange) {
            el.setSelectionRange(s, e);
          } else if (el.createTextRange) {
            var range = el.createTextRange();
            range.collapse(true);
            range.moveEnd('character', e);
            range.moveStart('character', s);
            range.select();
          } else if (el.selectionStart) {
            el.selectionStart = s;
            el.selectionEnd = e;
          } else {
            el.select();
          }
        }, 1);
      }
    });
  };

  $.fn.maskIt = function() {
    return this.each(function(idx, el) {
      var $input = $(el);

      //don't initialize what's already initialized
      if ($input.data('has-custom-mask') === true) {
        return false;
      }

      //no HTML5 validation on this form
      if ($input.closest('form').attr('novalidate') !== 'true') { //if there's no attribute...
        $input
          .closest('form')
          .attr({
            'novalidate': true
          })
          .find('[type="submit"]')
          .attr('formnovalidate', true);
      }

      //set vars
      var t = null; //used for the "any" field type.
      var val = $input.val();
      var len = val.length;
      var type = $input.attr('type');
      var placeholder = $input.attr('placeholder') || '';
      var mask = '<span style="display:inline-block;width:0;">&nbsp;</span>';
      var icon = '<i class="masked-icon">*</i>';

      //set a flag
      $input.data('has-custom-mask', true);

      //set the...