Skip to content

Commit

Permalink
Use custom ErrorStateMatcher on file upload input
Browse files Browse the repository at this point in the history
  • Loading branch information
jmccollum-woolpert committed Feb 5, 2024
1 parent fa4f56b commit a5f73e4
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,11 @@ <h4 class="strong d-flex mb-2">
[readonly]="true"
[formControl]="fileName"
(click)="selectFile()"
[errorStateMatcher]="fileUploadErrorStateMatcher"
required />
<mat-error
*ngIf="
fileName.errors?.required && (fileName.touched || fileName.dirty) && !validatingUpload
fileName.errors?.required && fileName.touched && fileName.dirty && !validatingUpload
">
{{ (messages$ | async)?.formFileRequired || 'File is required' }}
</mat-error>
Expand All @@ -62,6 +63,7 @@ <h4 class="strong d-flex mb-2">
<mat-error *ngIf="fileName.errors?.requestFormat && (fileName.touched || fileName.dirty)">
{{ (messages$ | async)?.formInvalidRequestFormat || 'Invalid request format' }}
</mat-error>
<mat-hint>.json or .zip</mat-hint>
</mat-form-field>
<button
type="button"
Expand Down Expand Up @@ -110,6 +112,7 @@ <h4 class="strong d-flex mb-2">
#fileInput
type="file"
accept=".json,.zip"
(cancel)="onCancelSelectFile()"
(click)="fileUploadClicked($event)"
(change)="fileSelected($event)" />
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

import { ChangeDetectionStrategy, Component, ElementRef, ViewChild } from '@angular/core';
import {
FormGroupDirective,
NgForm,
UntypedFormBuilder,
UntypedFormControl,
UntypedFormGroup,
Expand All @@ -29,6 +31,23 @@ import { toDispatcherLatLng } from 'src/app/util';
import { ScenarioSolutionHelpDialogComponent } from 'src/app/core/containers/scenario-solution-help-dialog/scenario-solution-help-dialog.component';
import { UploadActions } from '../../actions';
import { CsvHelpDialogComponent } from '../csv-help-dialog/csv-help-dialog.component';
import { ErrorStateMatcher } from '@angular/material/core';

class FileUploadErrorStateMatcher implements ErrorStateMatcher {
isErrorState(
control: UntypedFormControl | null,
ngForm: FormGroupDirective | NgForm | null
): boolean {
const invalid =
ngForm?.errors?.required ||
ngForm.errors?.zipContents ||
ngForm.errors?.fileFormat ||
ngForm.errors?.requestFormat ||
control?.invalid;
const show = ngForm?.touched && ngForm?.dirty;
return !!(invalid && show);
}
}

@Component({
selector: 'app-upload-dialog',
Expand All @@ -39,6 +58,7 @@ import { CsvHelpDialogComponent } from '../csv-help-dialog/csv-help-dialog.compo
export class UploadDialogComponent {
@ViewChild('fileInput', { static: true }) fileInput: ElementRef<HTMLInputElement>;

readonly fileUploadErrorStateMatcher = new FileUploadErrorStateMatcher();
readonly form: UntypedFormGroup;
readonly fileName: UntypedFormControl;
fileInvalid: boolean;
Expand Down Expand Up @@ -111,7 +131,6 @@ export class UploadDialogComponent {
if (!this.fileInput) {
return;
}

this.fileInput.nativeElement.click();
this.fileName.markAsTouched();
}
Expand All @@ -120,7 +139,12 @@ export class UploadDialogComponent {
(e.target as HTMLInputElement).value = null;
}

onCancelSelectFile(): void {
this.fileName.markAsDirty();
}

async fileSelected(e: Event): Promise<void> {
this.fileName.markAsDirty();
const target = e.target as HTMLInputElement;
const file = target && target.files && target.files[0];
if (!file) {
Expand Down

0 comments on commit a5f73e4

Please sign in to comment.