LS&TK's SE Life Log

SE備忘録

AngularJS blur&focus時にフォーマットするDirective

JavaScriptで書くとこんなかんじの動きになるディレクティブを作成してました。ここで動作に重要になってくるのがngModelControllerなのですが、動作を理解するのに少し時間がかかってしまいました。

demo

'use strict';

function applyFormat(value) {
  return value.substring(0, 4) + "/" + value.substring(4, 6) + "/" + value.substring(6, 8);
}

function removeFormat(value) {
  return value.match(/[0-9]+\.?[0-9]*/g).join('');
}

angular.module('app').directive('dateInput', () => {
  return {
    restrict: 'A',
    require: 'ngModel',
    link: (scope, elem, attrs, ctrl) => {

      ctrl.$parsers.push(() => {
        return removeFormat(ctrl.$viewValue);
      })

      ctrl.$formatters.push(() => {
        return applyFormat(ctrl.$modelValue);
      })

      // onBlur - make 8 digits number into yyyy/mm/dd format
      elem.bind('blur', () => {
        if (!ctrl.$modelValue || !ctrl.$viewValue) return;

        ctrl.$setViewValue(applyFormat(ctrl.$modelValue));
        ctrl.$render();

      })

      // onFocus - make yyyy/mm/dd styled data to 8digits num yyyymmdd
      elem.bind('focus', () => {
        if (!ctrl.$modelValue || !ctrl.$viewValue) return;

        ctrl.$setViewValue(ctrl.$modelValue);
        ctrl.$render();

      })
    }
  }
})
  • HTML
<input type="text" ng-model="value" date-input>
  • イメージ図
DOM =$setViewValue()=> $viewValue =($parsers)=>    $modelValue
DOM   <=$render()=     $viewValue <=($formatters)= $modelValue