24

How can I use angular material 2 FAB buttons to open a browse input dialog? This can be done in HTML by this way.

<button type="button">
    <label for="file-input">click</label>
</button>
<input type="file" id="file-input" style="display:none">

I tried following the same approach with material 2, but it doesn't work.

<button md-mini-fab type="button">
    <label for="fileToUpload">
        <md-icon>add</md-icon>
    </label>
</button>
<input id="fileToUpload" type="file" style="display:none;">

Are there any other ways that will work? Thank you.

Saif
  • 1,745
  • 5
  • 23
  • 46
  • You can use a button and an input / a label and an input. https://stackoverflow.com/a/56763240/5042169 – Jun Jun 26 '19 at 01:12

6 Answers6

70

Here is a simple solution:

<button (click)="fileInput.click()">
  <md-icon>library_add</md-icon>
  <span>Select</span>
  <input #fileInput type="file" (change)="onFileInput($event)" style="display:none;" />
</button>
KyleMit
  • 30,350
  • 66
  • 462
  • 664
rhyttr
  • 728
  • 1
  • 5
  • 7
16

You need to simply trigger the click for your file input.

<button md-mini-fab type="button" onclick="document.getElementById('fileToUpload').click()">
  <label for="fileToUpload"><md-icon>add</md-icon></label>
</button>
<input id="fileToUpload" type="file" style="display:none;">
anoop
  • 3,812
  • 2
  • 16
  • 28
  • this will even strip down the need for label tag, but this solution uses JS. I actually wanted to use as minimum JS as possible. Specifically I don't want to use any thing like document.getElementById and similar things. Well it may save me if nothing else works. – Saif May 23 '17 at 15:43
  • 1
    @saifullah: you may go for a directive then and can achieve it by ` `element.bind("click",.`, but it will be like making it more complex. :), – anoop May 31 '17 at 15:37
  • can you please help me to solve this https://stackoverflow.com/questions/52143052/how-to-manually-set-focus-on-mat-form-field-in-angular-6 @anoop – Zhu Sep 03 '18 at 04:19
16

Try this:

<input #file type="file" [hidden]="true" accept="image/*" (change)="upload(file.files)">
<button mat-button #upload (click)="file.click()">Upload file</button>

<mat-button> is from https://material.angular.io

We are hiding the basic input button and linking the material button to the file upload.

Ashwin R
  • 744
  • 7
  • 14
8

I'm not sure about your cases, but in my Angular5 application I used this HTML structure for uploading files on server:

<label for="uploadPicture" class="upload-file">
   <mat-icon>add_a_photo</mat-icon>
</label>
<input type="file"
       id="uploadPicture"
       class="hidden-input"
       accept="image/jpeg, .jpeg, image/png, .png, image/pjpeg, .jpg"
       (change)="selectFile($event.target.files[0])">

In my case this solution working great. No need to trigger click event, because when you click on <label> that related to input it's same as click on input.

Thom
  • 14,013
  • 25
  • 105
  • 185
alexJS
  • 626
  • 6
  • 11
  • wow, thats so awesome, I was looking for the same. But how did you displayed the selected filename??? – Talk is Cheap Show me Code Apr 26 '18 at 08:06
  • @Jaydeep Simple solution - (change)="selectFile($event.target.files)" will pass filedata in function argument. In you .ts file You will have: public selectFile(file): void { this.someVariableForFileName = file.name } and show this variable in HTML view:
    {{someVariableForFileName}}
    Hope, it help You. :)
    – alexJS Apr 27 '18 at 10:26
0

It can be a combination of md-button, md-dialog, and md-input. The mini fab button must have a click event to trigger the md-dialog component.

<button md-mini-fab type="button" (click)="openDialog()">
    <label for="fileToUpload">
      <md-icon>add</md-icon>
    </label>
</button>

Within the md-dialog component, the md-input field can be added.

<h1 md-dialog-title>Dialog</h1>
<div md-dialog-actions>
  <md-input-container>
    <input mdInput id="fileToUpload" type="file">
  </md-input-container>
  <p>
    <button md-button (click)="dialogRef.close('Option 1')">Option 1</button>
    <button md-button (click)="dialogRef.close('Option 2')">Option 2</button>
  </p>
</div>

Please see this Plunker example to get all/specific details.

Nehal
  • 13,130
  • 4
  • 43
  • 59
  • that's actually two clicks for just one input type file functionality, which isn't what I asked for. I want to just give material 2 design to input having type file. Which isn't any option provided by material by now. There are only workarounds available for that. – Saif May 23 '17 at 15:38
0

You can use a button and an input. Make sure that button doesn't enclose input.

<button (click)="fileInput.click()">Upload</button>
<input #fileInput type="file" (change)="onFileInput($event)" multiple style="display:none;" />

You can also use a label enclosing an input.

<label>
    <mat-icon>add</mat-icon>
    <input type="file" (change)="onFileInput($event)" multiple />
</label>
Jun
  • 2,942
  • 5
  • 28
  • 50