Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a custom file input in Ionic 2+ with a button styling?

Here is my template:

<label>{{label}}</label>
<input type="file" (change)="fileUpload($event)" id="file-input" style="position:absolute; top: -999999px" #fileInp>
<button ion-button (click)="onClick()">Upload</button>

and the ts file:

@ViewChild('fileInp') fileInput: ElementRef;
@Input() label: string;
@Output() data = new EventEmitter<FormData>();

fileUpload(event) {
  let fd = new FormData();
  fd.append('file', event.srcElement.files[0]);
  this.data.emit(fd);
}

onClick() {
  this.fileInput.nativeElement.click();
}

Everything works fine on Android and in the browser, but not on iOS. The same code works if I disable the button in the template.

like image 832
Anurag Kumar Avatar asked Jun 21 '17 08:06

Anurag Kumar


3 Answers

You can't trigger the click on a file input on iOS. A workaround is to use css to set the opacity of the input element to 0, and place it just on top of the button. That way, the file input won't be seen, but it will be clicked when clicking the button.

<ion-item>
  <label>{{label}}</label>
  <input type="file" (change)="fileUpload($event)" id="file-input" style="opacity: 0" #fileInp>
  <button ion-button (click)="onClick()">Upload</button>
</ion-item>

and then in the .scss file:

#file-input {
  opacity: 0;
  position: absolute;
  top: 0;
  width: 100%;
  height: 100%;
  left: 0;
  z-index: 999;
}

There're probably some other ways to fix this issue, but that's how I managed on an app I worked on in the past.

like image 148
sebaferreras Avatar answered Sep 21 '22 02:09

sebaferreras


I usually do the following.

    <ion-item>
        <ion-button color="primary" (click)="inputFile.click()">
             <ion-icon name="attach"></ion-icon> Anexar documentos
        </ion-button>
        <input #inputFile id="input-file"  style="opacity:0" type="file" (change)="uploadFiles($event)"
        multiple/>
    </ion-item>  
like image 41
Paulo Damasceno Avatar answered Sep 18 '22 02:09

Paulo Damasceno


The best way I found to do it is use a label with the for attribute and customized it using css. So when the user clicks on the label, the input is triggered. Keep in mind that the for label must be the input id.

<label class="myFakeUploadButton" for="myFileInput">Upload</label>
<input type="file" id="myFileInput">
#myFileInput{
  position: absolute;
  opacity: 0;
}

.myFakeUploadButton{
 /* Whatever you want */
}
like image 34
Pablo Avatar answered Sep 22 '22 02:09

Pablo