中安拓也のブログ

プログラミングについて書くブログ

【Angular】小文字を大文字に変換するDirective

はじめに

小文字で入力したアルファベットを大文字に変換するDirectiveを作成します。

環境

TypeScriptベースのフレームワークであるAngularを使用しています。

ng versionの実行結果

Angular CLI: 9.1.4
Node: 12.9.1
OS: darwin x64

Angular: 0.0.0
... core, platform-browser, platform-browser-dynamic
Ivy Workspace: Yes

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.901.4
@angular-devkit/build-angular     0.901.4
@angular-devkit/build-optimizer   0.901.4
@angular-devkit/build-webpack     0.901.4
@angular-devkit/core              9.1.4
@angular-devkit/schematics        9.1.4
@angular/animations               9.1.4
@angular/cdk                      9.2.2
@angular/cli                      9.1.4
@angular/common                   9.1.4
@angular/compiler                 9.1.4
@angular/compiler-cli             9.1.4
@angular/fire                     6.0.0
@angular/flex-layout              9.0.0-beta.29
@angular/forms                    9.1.4
@angular/language-service         9.1.4
@angular/router                   9.1.4
@ngtools/webpack                  9.1.4
@schematics/angular               9.1.4
@schematics/update                0.901.4
rxjs                              6.5.5
typescript                        3.7.5
webpack                           4.42.0

大文字に変換するディレクティブ

下記のディレクティブで入力した文字を大文字に変換することができるようになります。

uppercase-change.directive.ts

import { Directive, ElementRef, HostListener } from '@angular/core';

/**
 * アルファベットの小文字を大文字に変換するディレクティブ
 *
 * @export
 * @directive UppercaseChangeDirective
 */
@Directive({
  selector: '[appUppercaseChange]'
})
export class UppercaseChangeDirective {
  private lastValue: string;

  constructor(private ref: ElementRef) {}

  /**
   * 文字を入力したタイミングで呼び出され、大文字に変換する
   *
   * @param {*} event
   * @memberof UppercaseChangeDirective
   */
  @HostListener('input', ['$event'])
  public onInput(event: any): void {
    const start = event.target.selectionStart;
    const end = event.target.selectionEnd;
    event.target.value = event.target.value.toUpperCase();
    event.target.setSelectionRange(start, end);
    event.preventDefault();
    if (
      !this.lastValue ||
      (this.lastValue &&
        event.target.value.length > 0 &&
        this.lastValue !== event.target.value)
    ) {
      this.lastValue = this.ref.nativeElement.value = event.target.value;
      const evt = document.createEvent('HTMLEvents');
      evt.initEvent('input', false, true);
      event.target.dispatchEvent(evt);
    }
  }
}

大文字への変換は下記のコードで実施しており、そのほかのコードは、文字列の途中に文字を挿入したときに、ディレクティブで文字列を変換すると、カーソル(キャレット)が文字列の途中ではなく文末に移動してしまう問題に対応するために書いています。

event.target.value = event.target.value.toUpperCase();

本記事ディレクティブのデモ画面をStackBlitzで公開しているので、実際に触ることができます。

https://ng-uppercase-directive.stackblitz.io

f:id:l08084:20201211200835p:plain
StackBlitzによる本ディレクティブのデモ画面

参考サイト

angular - Directive to upper case input fields - Stack Overflow