title: SSN masking in angular js
body: <p>I am trying to mask SSN number using angular js.</p>
  
  <p>Expected:</p>
  
  <p><a href="https://i.stack.imgur.com/L9b5w.jpg" rel="nofollow noreferrer">Before mask (onFocus)</a></p>
  
  <p><a href="https://i.stack.imgur.com/RtH97.jpg" rel="nofollow noreferrer">After mask (onBlur)</a></p>
  
  <p>User can enter only numbers and SSN formatting done by filters. Below is sample code I written.</p>
  
  <p><strong>Directive:</strong></p>
  
  <pre><code>app.directive('taxId', function ($filter, $browser) {
  return {
      require: 'ngModel',
      link: function ($scope, $element, $attrs, ngModelCtrl) {
          var listener = function () {
              var value = $element.val().replace(/[^0-9]/g, '');
              if (value.length &gt; 9)
                  value = value.slice(0, 9);
              var type = $attrs.taxId;
              $element.val($filter('taxId')(value, type, false));
          };
  
          // This runs when we update the text field
          ngModelCtrl.$parsers.push(function (viewValue) {
              return viewValue.replace(/[^0-9]/g, '').slice(0, 10);
          });
  
          // This runs when the model gets updated on the scope directly and keeps our view in sync
          ngModelCtrl.$render = function () {
              $element.val($filter('taxId')(ngModelCtrl.$viewValue, $attrs.taxId, false));
          };
  
          $element.bind('change', listener);
          $element.bind('keydown', function (event) {
              var key = event.keyCode;
              // If the keys include the CTRL, SHIFT, ALT, or META keys, or the arrow keys, do nothing.
              // This lets us support copy and paste too
              if (key == 91 || (15 &lt; key &amp;&amp; key &lt; 19) || (37 &lt;= key &amp;&amp; key &lt;= 40)) {
                  return;
              }
              $browser.defer(listener); // Have to do this or changes don't get picked up properly
          });
  
          if ($attrs.taxId== "ssn") {
              $element.bind('blur', function () {
                  $scope.$apply(function () {
  
                  });
              });
  
              $element.bind('focus', function () {
                  $scope.$apply(function () {
  
                  });
              });
          }
  
          $element.bind('paste cut', function () {
              $browser.defer(listener);
          });
      }
  
  };
  </code></pre>
  
  <p>});
  <strong>Filter:</strong></p>
  
  <pre><code>app.filter('taxId', function () {
  return function (taxId, type) {
      if (!taxId) { return ''; }
  
      var value = taxId.toString().replace(/^\+/, '');
  
      if (value.match(/[^0-9]/)) {
          return taxId;
      }
  
      if (type.toLowerCase() == "fein") {
          if (value.length == 10) {
              value = value.slice(0, 2) + "-" + value.slice(2, value.length - 1);
              return value;
          } else if (value.length &gt; 2) {
              return (value.slice(0, 2) + "-" + value.slice(2, value.length));
          }
          else {
              return value.slice(0, 9);
          }
      }
      else if(type.toLowerCase() == "ssn"){
          if (value.length &gt; 5) {
              return (value.slice(0,3) + "-" + value.slice(3,5) + "-" + value.slice(5,value.length));
          }
          else if (value.length &gt; 3) {
              return (value.slice(0, 3) + "-" + value.slice(3, value.length));
          }
          else {
              return value;
          }
      }
  };
  </code></pre>
  
  <p>});</p>
  
  <p>I am able to format SSN successfully. But masking I am not able to do. I went through below link about masking but couldn't help much. I need to write special functions to mask and unmask in directive at 'blur' and 'focus'.
  In the end ng-model should contain value "999993213" but value in UI should show as "<strong>*-</strong>-3213" (both format and mask).</p>
  
  <p>Appreciate your inputs.  Thank you.</p>
  
  <p><a href="https://stackoverflow.com/questions/22581945/masking-in-angularjs">Masking in AngularJS</a></p>