Skip to content
This repository has been archived by the owner on Dec 8, 2022. It is now read-only.

Commit

Permalink
Added disabled input property for file attachment component (#81)
Browse files Browse the repository at this point in the history
* Added disabled input property for file attachment component

* tidy up

* removed extra line
  • Loading branch information
Blackbaud-AlexKingman committed Nov 20, 2019
1 parent fdd8e56 commit c3cf84e
Show file tree
Hide file tree
Showing 7 changed files with 187 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
tabindex="-1"
type="file"
[attr.accept]="acceptedTypes || null"
[disabled]="disabled"
[required]="required"
(change)="fileChangeEvent($event)"
#fileInput
Expand All @@ -32,6 +33,7 @@
type="button"
[attr.aria-label]="'skyux_file_attachment_file_upload_drag_or_click' | skyLibResources"
[attr.aria-labelledby]="(hasLabelComponent) ? labelElementId : null"
[disabled]="disabled"
(click)="onDropClicked()"
>
<sky-icon
Expand All @@ -55,6 +57,7 @@
type="button"
class="sky-btn sky-file-attachment-delete"
[attr.aria-label]="'skyux_file_attachment_file_item_delete' | skyLibResources"
[disabled]="disabled"
(click)="deleteFileAttachment()"
>
<sky-icon
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,18 @@ import {
FileAttachmentTestModule
} from './fixtures/file-attachment.module.fixture';

import {
TemplateDrivenFileAttachmentTestComponent
} from './fixtures/template-driven-file-attachment.component.fixture';

function getInputDebugEl(fixture: ComponentFixture<any>): DebugElement {
return fixture.debugElement.query(By.css('input'));
}

function getButtonEl(el: HTMLElement): HTMLElement {
return el.querySelector('.sky-file-attachment-btn');
}

describe('File attachment', () => {

let fixture: ComponentFixture<FileAttachmentTestComponent>;
Expand All @@ -60,14 +72,6 @@ describe('File attachment', () => {
});

//#region helpers
function getInputDebugEl(): DebugElement {
return fixture.debugElement.query(By.css('input'));
}

function getButtonEl(): HTMLElement {
return el.querySelector('.sky-file-attachment-btn');
}

function getDropEl(): HTMLElement {
return el.querySelector('.sky-file-attachment');
}
Expand Down Expand Up @@ -145,7 +149,7 @@ describe('File attachment', () => {
}

function triggerChangeEvent(expectedChangeFiles: any[]): void {
const inputEl = getInputDebugEl();
const inputEl = getInputDebugEl(fixture);

const fileChangeEvent = {
target: {
Expand Down Expand Up @@ -310,7 +314,7 @@ describe('File attachment', () => {
tick();
fixture.detectChanges();
const labelWrapper = getLabelWrapper();
const input = getInputDebugEl();
const input = getInputDebugEl(fixture);

expect(input.nativeElement.getAttribute('required')).toBeNull();
expect(labelWrapper.classList.contains('sky-control-label-required')).toBe(false);
Expand All @@ -323,7 +327,7 @@ describe('File attachment', () => {
tick();
fixture.detectChanges();
const labelWrapper = getLabelWrapper();
const input = getInputDebugEl();
const input = getInputDebugEl(fixture);

expect(input.nativeElement.getAttribute('required')).not.toBeNull();
expect(labelWrapper.classList.contains('sky-control-label-required')).toBe(true);
Expand All @@ -345,13 +349,43 @@ describe('File attachment', () => {
tick();
fixture.detectChanges();
const labelWrapper = getLabelWrapper();
const input = getInputDebugEl();
const input = getInputDebugEl(fixture);

expect(input.nativeElement.getAttribute('required')).not.toBeNull();
expect(labelWrapper.classList.contains('sky-control-label-required')).toBe(true);
expect(labelWrapper.getAttribute('aria-required')).toBe('true');
}));

it('should not have disabled attribute when not disabled', fakeAsync(() => {
fileAttachmentInstance.ngAfterViewInit();
tick();
fixture.detectChanges();
const input = getInputDebugEl(fixture);
const button = getButtonEl(el);

expect(input.nativeElement.getAttribute('disabled')).toBeNull();
expect(button.getAttribute('disabled')).toBeNull();
}));

it(`should have disabled attribute when form control's disabled method is called`, fakeAsync(() => {
fixture.componentInstance.attachment.disable();
fileAttachmentInstance.ngAfterViewInit();
tick();
fixture.detectChanges();
const input = getInputDebugEl(fixture);
const button = getButtonEl(el);

expect(input.nativeElement.getAttribute('disabled')).not.toBeNull();
expect(button.getAttribute('disabled')).not.toBeNull();

fixture.componentInstance.attachment.enable();
tick();
fixture.detectChanges();

expect(input.nativeElement.getAttribute('disabled')).toBeNull();
expect(button.getAttribute('disabled')).toBeNull();
}));

it('should handle removing the label', fakeAsync(() => {
fixture.componentInstance.required = true;
fileAttachmentInstance.ngAfterViewInit();
Expand All @@ -372,11 +406,11 @@ describe('File attachment', () => {
it('should click the file input on choose file button click', () => {
fixture.detectChanges();

const inputEl = getInputDebugEl();
const inputEl = getInputDebugEl(fixture);

spyOn(inputEl.references.fileInput, 'click');

const dropEl = getButtonEl();
const dropEl = getButtonEl(el);

expect(inputEl.references.fileInput.click).not.toHaveBeenCalled();

Expand All @@ -390,7 +424,7 @@ describe('File attachment', () => {
it('should not click the file input on remove button click', () => {
fixture.detectChanges();

const inputEl = getInputDebugEl();
const inputEl = getInputDebugEl(fixture);

spyOn(inputEl.references.fileInput, 'click');

Expand Down Expand Up @@ -1060,3 +1094,52 @@ describe('File attachment', () => {
});
}));
});

describe('File attachment (template-driven)', () => {

let fixture: ComponentFixture<TemplateDrivenFileAttachmentTestComponent>;
let fileAttachmentInstance: SkyFileAttachmentComponent;
let el: HTMLElement;

beforeEach(() => {
TestBed.configureTestingModule({
imports: [
FileAttachmentTestModule
]
});
fixture = TestBed.createComponent(TemplateDrivenFileAttachmentTestComponent);
fixture.detectChanges();
el = fixture.nativeElement;
fileAttachmentInstance = fixture.componentInstance.fileAttachmentComponent;
});

it('should not have disabled attribute when not disabled', fakeAsync(() => {
fileAttachmentInstance.ngAfterViewInit();
tick();
fixture.detectChanges();
const input = getInputDebugEl(fixture);
const button = getButtonEl(el);

expect(input.nativeElement.getAttribute('disabled')).toBeNull();
expect(button.getAttribute('disabled')).toBeNull();
}));

it(`should have disabled attribute when disabled input is set to true`, fakeAsync(() => {
fixture.componentInstance.disabled = true;
fileAttachmentInstance.ngAfterViewInit();
tick();
fixture.detectChanges();
const input = getInputDebugEl(fixture);
const button = getButtonEl(el);

expect(input.nativeElement.getAttribute('disabled')).not.toBeNull();
expect(button.getAttribute('disabled')).not.toBeNull();

fixture.componentInstance.disabled = false;
tick();
fixture.detectChanges();

expect(input.nativeElement.getAttribute('disabled')).toBeNull();
expect(button.getAttribute('disabled')).toBeNull();
}));
});
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,21 @@ export class SkyFileAttachmentComponent implements AfterViewInit, AfterContentIn
@Input()
public acceptedTypes: string;

/**
* Indicates whether to disable the input. This property accepts `boolean` values.
*/
@Input()
public set disabled(value: boolean) {
const newDisabledState = SkyFormsUtility.coerceBooleanProperty(value);
if (this._disabled !== newDisabledState) {
this._disabled = newDisabledState;
}
}

public get disabled(): boolean {
return this._disabled;
}

@Input()
public maxFileSize: number = 500000;

Expand Down Expand Up @@ -130,6 +145,8 @@ export class SkyFileAttachmentComponent implements AfterViewInit, AfterContentIn

private ngUnsubscribe = new Subject<void>();

private _disabled: boolean = false;

private _value: any;

constructor(
Expand Down Expand Up @@ -284,6 +301,16 @@ export class SkyFileAttachmentComponent implements AfterViewInit, AfterContentIn
this.changeDetector.markForCheck();
}

/**
* @internal
* Sets the disabled state of the control. Implemented as a part of ControlValueAccessor.
* @param isDisabled Whether the control should be disabled.
*/
public setDisabledState(isDisabled: boolean) {
this.disabled = isDisabled;
this.changeDetector.markForCheck();
}

public emitClick(): void {
this.fileClick.emit({
file: this.value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,14 @@ import {
SkyFileAttachmentsModule
} from '../file-attachments.module';

import {
TemplateDrivenFileAttachmentTestComponent
} from './template-driven-file-attachment.component.fixture';

@NgModule({
declarations: [
FileAttachmentTestComponent
FileAttachmentTestComponent,
TemplateDrivenFileAttachmentTestComponent
],
imports: [
SkyFileAttachmentsModule,
Expand All @@ -30,7 +35,8 @@ import {
ReactiveFormsModule
],
exports: [
FileAttachmentTestComponent
FileAttachmentTestComponent,
TemplateDrivenFileAttachmentTestComponent
]
})
export class FileAttachmentTestModule { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import {
Component,
ViewChild
} from '@angular/core';

import {
SkyFileAttachmentComponent
} from '../file-attachment.component';

@Component({
selector: 'file-attachment-test',
template: `
<sky-file-attachment
[disabled]="disabled"
>
<sky-file-attachment-label>
Field Label
</sky-file-attachment-label>
</sky-file-attachment>
`
})
export class TemplateDrivenFileAttachmentTestComponent {

public disabled: boolean = false;

@ViewChild(SkyFileAttachmentComponent)
public fileAttachmentComponent: SkyFileAttachmentComponent;
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@
>
Toggle required
</button>
<button
type="button"
class="sky-btn sky-btn-primary sky-test-label"
(click)="onToggleDisabledClick()"
>
Toggle disabled
</button>
</div>

<h1>
Expand Down Expand Up @@ -74,6 +81,7 @@ <h1>

<div>
<sky-file-attachment
[disabled]="disabled"
[required]="required"
[validateFn]="validateFile"
[(ngModel)]="fileValue"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,13 @@ import {
templateUrl: './single-file-attachment-visual.component.html'
})
export class SingleFileAttachmentVisualComponent implements OnInit {

public acceptedTypes: Array<String>;

public attachment: FormControl;

public disabled: boolean = false;

public fileForm: FormGroup;

public filesToUpload: Array<SkyFileItem>;
Expand Down Expand Up @@ -63,6 +66,18 @@ export class SingleFileAttachmentVisualComponent implements OnInit {
this.removeFromArray(this.filesToUpload, file);
}

/**
* Toggle both the template-driven and reactive form.
*/
public onToggleDisabledClick(): void {
this.disabled = !this.disabled;
if (this.disabled) {
this.attachment.disable();
} else {
this.attachment.enable();
}
}

private removeFromArray(items: Array<any>, obj: SkyFileItem | SkyFileLink): void {
if (items) {
const index = items.indexOf(obj);
Expand Down

0 comments on commit c3cf84e

Please sign in to comment.