How to use input type file in angular material

How to use input type file in angular material

Hi, I am using angular material for designing. when i go on angular material site there no input type file element. anyone know about this.


Here is a workaround if all you want is a nicely displayed file input button.

Html

<button type="button" mat-raised-button (click)="fileInput.click()">Choose File</button>
<input hidden (change)="onFileSelected()" #fileInput type="file" id="file">

Component

onFileSelected() {
  const inputNode: any = document.querySelector('#file');

  if (typeof (FileReader) !== 'undefined') {
    const reader = new FileReader();

    reader.onload = (e: any) => {
      this.srcResult = e.target.result;
    };

    reader.readAsArrayBuffer(inputNode.files[0]);
  }
}

Inspired by this Angular Material Github Issue comment https://github.com/angular/material2/issues/3262#issuecomment-309000588


Angular Material does not support yet a workaround for file upload. There are alternative to archieve this. e.g using external libraries.

angular-material-fileupload: link to npm package

Supported features:

  • Drag and drop
  • common uploads
  • progress bar
  • file size and more...

ngx-material-file-input: Link to repository

Supported features:

  • ngx-mat-file-input component, to use inside Angular Material mat-form-field
  • a FileValidator with maxContentSize, to limit the file size
  • a ByteFormatPipe to format the file size in a human-readable format
  • and more small minor features...

Update

See the answer here if you just need a workaround without external library https://stackoverflow.com/a/53546417/6432698


I would suggest you to checkout @angular-material-components/file-input.

It is very Angular Material Compliant.

enter image description here


Made more sense to just style the default input element of type file using the ::file-selector-button to look like the angular material button. Also, this way accounts for UX which lets the user know that the file to upload has been added to the form by displaying the file name.

P.S. Style was copied from the declarations after inspecting the angular mat-raised-button

input[type="file"]::file-selector-button {
  box-shadow: 0px 3px 1px -2px rgb(0 0 0 / 20%), 0px 2px 2px 0px rgb(0 0 0 / 14%), 0px 1px 5px 0px rgb(0 0 0 / 12%);
  background: #ffd740;
  box-sizing: border-box;
  position: relative;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  cursor: pointer;
  outline: none;
  border: none;
  -webkit-tap-highlight-color: transparent;
  display: inline-block;
  white-space: nowrap;
  text-decoration: none;
  vertical-align: baseline;
  text-align: center;
  margin: 0;
  min-width: 64px;
  line-height: 36px;
  padding: 0 16px;
  border-radius: 4px;
  overflow: visible;
  transform: translate3d(0, 0, 0);
  transition: background 400ms cubic-bezier(0.25, 0.8, 0.25, 1), box-shadow 280ms cubic-bezier(0.4, 0, 0.2, 1);
  margin: 1rem;
}


/*  fallback for older browsers supporting the -webkit prefix */

input[type="file"]::-webkit-file-upload-button {
  box-shadow: 0px 3px 1px -2px rgb(0 0 0 / 20%), 0px 2px 2px 0px rgb(0 0 0 / 14%), 0px 1px 5px 0px rgb(0 0 0 / 12%);
  background: #ffd740;
  box-sizing: border-box;
  position: relative;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  cursor: pointer;
  outline: none;
  border: none;
  -webkit-tap-highlight-color: transparent;
  display: inline-block;
  white-space: nowrap;
  text-decoration: none;
  vertical-align: baseline;
  text-align: center;
  margin: 0;
  min-width: 64px;
  line-height: 36px;
  padding: 0 16px;
  border-radius: 4px;
  overflow: visible;
  transform: translate3d(0, 0, 0);
  transition: background 400ms cubic-bezier(0.25, 0.8, 0.25, 1), box-shadow 280ms cubic-bezier(0.4, 0, 0.2, 1);
  margin: 1rem;
  font-weight: 500;
}
<form>
  <label for="fileUpload">Add file</label>
  <input type="file" id="fileUpload">
</form>