Reputation: 1593
I have a simple upload form and would like to bind the displayed filename to the value of the file input field <input type="file">
, but for some reason it always shows some virtual filepath. How can the binding be improved to not have this behavior(only filename, like selected.files[0].name
)?
Ideally the selected filename would be shown in the label for #selected
right after the OS filechooser finishes. Another approach of mine is included in the comments (*ngIf
), but it doesn't work either.
<form>
<div class="justify-content-center">
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text">Select image</span>
</div>
<div class="custom-file">
<input type="file" accept="image/*" class="custom-file-input" id="selected" #selected (click)="message=''" >
<label class="custom-file-label" for="selected">{{ selected.value }}</label>
<!--
<div *ngIf="selected.files[0].name; then showFilename else showDefaultMsg"></div>
<ng-template #showFilename>
<label class="custom-file-label" for="selected">{{ selected.files[0].name }}</label>
</ng-template>
<ng-template #showDefaultMsg>
<label class="custom-file-label" for="selected">Choose file....</label>
</ng-template>
-->
</div>
</div>
<button [disabled]="!selected.value" id="uploadBtn" class="btn btn-primary" (click)="onUpload(selected)">Upload</button>
<div class="text-center" *ngIf="message">
<div class="spinner-border" role="status">
<span class="sr-only">Loading....</span>
</div>
<div>{{ message }}</div>
</div>
</div>
</form>
Thanks
Upvotes: 4
Views: 5406
Reputation: 12900
I don't believe you can reference the value like that and pick up changes. selected
is an HTMLInputElement
, not an Observable<HTMLInputElement>
or any other thing that is going to emit the value on change.
In the below example, you'll see that the same setup with a text box shows what you would expect on page load, but doesn't actually pickup any changes to the input value.
You need to either use ngModel
, FormControl
, or just create an event for the change
event.
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular';
fileName = null;
onFileChange(evt): void {
this.fileName = evt.target.files[0].name;
}
}
Template
<hello name="{{ name }}"></hello>
<input type="text" #myInput value="Init Text" />
<div>Input Text: {{myInput.value}}</div>
<input type="file" (change)="onFileChange($event)" />
<div>name: {{fileName}}</div>
Upvotes: 4