Posted at

Angular Materialでファイル選択ボタン

小ネタです。

Angular Materialを使ったプロジェクトで、ファイル選択input <input type="file" /> を使うときにボタンをmat-buttonにする方法を紹介します。


HTML

<input type="file" style="display: none" #fileInput accept="image/*" (change)="onChangeFileInput()" />

<button mat-raised-button color="primary" class="file-select-button" (click)="onClickFileInputButton()">
<mat-icon>attach_file</mat-icon>
ファイルを選択
</button>

<p class="file-name" *ngIf="!file; else fileName">ファイルが選択されていません</p>
<ng-template #fileName>
<p class="file-name">{{ file?.name }}</p>
</ng-template>


  • 1行目: 通常のinputコントロールに対して #fileInput という形でテンプレートリファレンスを追加。 また、このコントロールはmat-buttonに置き換える予定なので、 display: none で非表示にする

  • 2-4行目: inputの代わりになるmat-button、 クリックした際に発火するイベントハンドラを設定

  • 7行目以降: 選択したファイル名の表示


TypeScript

import { Component, ViewChild } from '@angular/core';  // ViewChildをimport

// ... 中略 ...
export class FileInputComponent {
@ViewChild('fileInput')
fileInput;

file: File | null = null;

onClickFileInputButton(): void {
this.fileInput.nativeElement.click();
}

onChangeFileInput(): void {
const files: { [key: string]: File } = this.fileInput.nativeElement.files;
this.file = files[0];
}
}


  • 1行目: テンプレートリファレンスを使って、コンポーネントのクラス側からinputにアクセスするために ViewChild をimportしておく

  • 4行目: テンプレートリファレンスを使ってinput要素を取得しておく

  • 9行目: mat-buttonが押さたイベントをinput要素に伝える処理

  • 13行目以降: inputのchangeイベントの発火を受けて、file変数にファイル内容を格納する処理


サンプル

stackblitzにサンプルを用意しました。

https://stackblitz.com/edit/angular-material-file-select