From 900a8dbd2a7ed203f0aff8f1221fa68c8470d0e2 Mon Sep 17 00:00:00 2001 From: Volodymyr Pohrebniak Date: Wed, 12 Feb 2020 14:36:30 +0100 Subject: [PATCH] fix(rating): ignore clicks on disabled rating (#3574) Fixes #3465 --- src/rating/rating.spec.ts | 47 +++++++++++++++++++++++++++++++++++++++ src/rating/rating.ts | 8 +++++-- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/rating/rating.spec.ts b/src/rating/rating.spec.ts index 32bf7221b7..a731643293 100644 --- a/src/rating/rating.spec.ts +++ b/src/rating/rating.spec.ts @@ -450,6 +450,19 @@ describe('ngb-rating', () => { }); }); + it('should set tabindex to -1 when disabled', () => { + const fixture = createTestComponent(''); + let ratingEl = fixture.debugElement.query(By.directive(NgbRating)); + let ratingComp = ratingEl.componentInstance; + + fixture.detectChanges(); + expect(ratingEl.nativeElement.getAttribute('tabindex')).toEqual('0'); + + ratingComp.disabled = true; + fixture.detectChanges(); + expect(ratingEl.nativeElement.getAttribute('tabindex')).toEqual('-1'); + }); + describe('keyboard support', () => { it('should handle arrow keys', () => { @@ -582,6 +595,40 @@ describe('ngb-rating', () => { expect(element.nativeElement).toHaveCssClass('ng-untouched'); }); + it('should not update template driven form by clicking disabled control', async(() => { + const html = ` + + `; + + const fixture = createTestComponent(html); + const element = fixture.debugElement.query(By.css('.control')); + const disabledElement = fixture.debugElement.query(By.css('.control-disabled')); + + fixture.detectChanges(); + fixture.whenStable() + .then(() => { + getStar(element.nativeElement, 3).click(); + + fixture.detectChanges(); + return fixture.whenStable(); + }) + .then(() => { + expect(getState(element.nativeElement)).toEqual([true, true, true, false, false]); + expect(getState(disabledElement.nativeElement)).toEqual([false, false, false, false, false]); + expect(fixture.componentInstance.model).toEqual(3); + + getStar(disabledElement.nativeElement, 4).click(); + fixture.detectChanges(); + return fixture.whenStable(); + }) + .then(() => { + fixture.detectChanges(); + expect(getState(element.nativeElement)).toEqual([true, true, true, false, false]); + expect(getState(disabledElement.nativeElement)).toEqual([false, false, false, false, false]); + expect(fixture.componentInstance.model).toEqual(3); + }); + })); + it('should handle clicks and update form control', () => { const html = `
diff --git a/src/rating/rating.ts b/src/rating/rating.ts index c7899aceb9..43a59a5848 100644 --- a/src/rating/rating.ts +++ b/src/rating/rating.ts @@ -48,7 +48,7 @@ const NGB_RATING_VALUE_ACCESSOR = { encapsulation: ViewEncapsulation.None, host: { 'class': 'd-inline-flex', - 'tabindex': '0', + '[tabindex]': 'disabled ? -1 : 0', 'role': 'slider', 'aria-valuemin': '0', '[attr.aria-valuemax]': 'max', @@ -146,7 +146,11 @@ export class NgbRating implements ControlValueAccessor, handleBlur() { this.onTouched(); } - handleClick(value: number) { this.update(this.resettable && this.rate === value ? 0 : value); } + handleClick(value: number) { + if (!this.readonly && !this.disabled) { + this.update(this.resettable && this.rate === value ? 0 : value); + } + } handleKeyDown(event: KeyboardEvent) { // tslint:disable-next-line:deprecation