Skip to content

Commit 8319b3c

Browse files
samir-ayoubalinelariguet
authored andcommitted
fix(checkbox-group): corrige inconsistência de uso no Edge e IE
No IE e Edge havia inconsistência e scroll indevido se selecionasse uma opção no checkbox. Isso ocorria se houvessem dois componentes `checkbox-group` e isso gerava conflitos de id nos inputs de opção. Fixes DTHFUI-1571
1 parent a04f569 commit 8319b3c

File tree

9 files changed

+99
-29
lines changed

9 files changed

+99
-29
lines changed

projects/ui/src/lib/components/po-field/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export * from './po-checkbox-group/po-checkbox-group-option.interface';
1+
export * from './po-checkbox-group/interfaces/po-checkbox-group-option.interface';
22
export * from './po-checkbox-group/po-checkbox-group.component';
33
export * from './po-combo/po-combo-filter-mode.enum';
44
export * from './po-combo/interfaces/po-combo-filter.interface';
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { PoCheckboxGroupOption } from './po-checkbox-group-option.interface';
2+
3+
/**
4+
* @docsPrivate
5+
*
6+
* @usedBy PoCheckboxGroupComponent
7+
*
8+
* @description
9+
*
10+
* Interface para as ações do componente po-checkbox-group utilizada no template.
11+
*
12+
*/
13+
export interface PoCheckboxGroupOptionView extends PoCheckboxGroupOption {
14+
15+
// Identificador do item.
16+
id: string;
17+
18+
}

projects/ui/src/lib/components/po-field/po-checkbox-group/po-checkbox-group-option.interface.ts renamed to projects/ui/src/lib/components/po-field/po-checkbox-group/interfaces/po-checkbox-group-option.interface.ts

File renamed without changes.

projects/ui/src/lib/components/po-field/po-checkbox-group/po-checkbox-group-base.component.spec.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import * as ValidatorsFunctions from '../validators';
55
import { expectPropertiesValues } from './../../../util-test/util-expect.spec';
66

77
import { PoCheckboxGroupBaseComponent } from './po-checkbox-group-base.component';
8-
import { PoCheckboxGroupOption } from './po-checkbox-group-option.interface';
8+
import { PoCheckboxGroupOption } from './interfaces/po-checkbox-group-option.interface';
99

1010
describe('PoCheckboxGroupBaseComponent: ', () => {
1111
let component: PoCheckboxGroupBaseComponent;
@@ -340,6 +340,17 @@ describe('PoCheckboxGroupBaseComponent: ', () => {
340340
expect(component['getGridSystemColumns'](columns, maxColumns)).toBe(6);
341341
});
342342

343+
it('setCheckboxGroupOptionsView: should set `checkboxGroupOptionsView` with an id property in each option item', () => {
344+
spyOn(UtilsFunction, 'uuid');
345+
346+
component['setCheckboxGroupOptionsView'](options);
347+
348+
expect(UtilsFunction.uuid).toHaveBeenCalled();
349+
component.checkboxGroupOptionsView.forEach(checkboxOption => {
350+
expect(checkboxOption.hasOwnProperty('id')).toBeTruthy();
351+
});
352+
});
353+
343354
});
344355

345356
describe('Properties: ', () => {
@@ -370,7 +381,12 @@ describe('PoCheckboxGroupBaseComponent: ', () => {
370381
it('p-options: should be update with valid values.', () => {
371382
const validValues = [[], [{label: '1', value: '2'}]];
372383

384+
spyOn(component, <any> 'removeDuplicatedOptions');
385+
spyOn(component, <any> 'setCheckboxGroupOptionsView');
386+
373387
expectPropertiesValues(component, 'options', validValues, validValues);
388+
expect(component['removeDuplicatedOptions']).toHaveBeenCalled();
389+
expect(component['setCheckboxGroupOptionsView']).toHaveBeenCalledWith(component.options);
374390
});
375391

376392
it('p-columns: should update property with valid values', () => {

projects/ui/src/lib/components/po-field/po-checkbox-group/po-checkbox-group-base.component.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { AbstractControl, ControlValueAccessor, Validator } from '@angular/forms';
22
import { EventEmitter, Input, Output } from '@angular/core';
33

4-
import { convertToBoolean, convertToInt } from './../../../utils/util';
4+
import { convertToBoolean, convertToInt, uuid } from './../../../utils/util';
55
import { requiredFailed } from '../validators';
66

7-
import { PoCheckboxGroupOption } from './po-checkbox-group-option.interface';
7+
import { PoCheckboxGroupOption } from './interfaces/po-checkbox-group-option.interface';
8+
import { PoCheckboxGroupOptionView } from './interfaces/po-checkbox-group-option-view.interface';
89

910
const poCheckboxGroupColumnsDefaultLength: number = 6;
1011
const poCheckboxGroupColumnsTotalLength: number = 12;
@@ -40,6 +41,7 @@ const poCheckboxGroupColumnsTotalLength: number = 12;
4041
*/
4142
export class PoCheckboxGroupBaseComponent implements ControlValueAccessor, Validator {
4243

44+
checkboxGroupOptionsView: Array<PoCheckboxGroupOptionView>;
4345
checkedOptions: any = {};
4446
checkedOptionsList: any = [];
4547
mdColumns: number = poCheckboxGroupColumnsDefaultLength;
@@ -152,6 +154,7 @@ export class PoCheckboxGroupBaseComponent implements ControlValueAccessor, Valid
152154
@Input('p-options') set options(value: Array<PoCheckboxGroupOption>) {
153155
this._options = Array.isArray(value) ? value : [];
154156
this.removeDuplicatedOptions();
157+
this.setCheckboxGroupOptionsView(this.options);
155158
}
156159

157160
get options() {
@@ -301,4 +304,10 @@ export class PoCheckboxGroupBaseComponent implements ControlValueAccessor, Valid
301304
});
302305
}
303306

307+
private setCheckboxGroupOptionsView(optionsList: Array<PoCheckboxGroupOption>) {
308+
this.checkboxGroupOptionsView = optionsList.map(option => {
309+
return { ...option, id: uuid() };
310+
});
311+
}
312+
304313
}

projects/ui/src/lib/components/po-field/po-checkbox-group/po-checkbox-group.component.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<div class="po-field-container-content po-checkbox-group-content">
77
<div class="po-row po-pt-1 po-pb-1">
88

9-
<div *ngFor="let option of options; let i = index"
9+
<div *ngFor="let option of checkboxGroupOptionsView; trackBy: trackByFn"
1010
class="po-checkbox-group-item po-md-{{ mdColumns }} po-lg-{{ columns }}"
1111
[class.po-checkbox-group-item-disabled]="option.disabled || disabled">
1212

@@ -17,14 +17,14 @@
1717
[class.po-checkbox-group-input-indeterminate]="checkedOptions[option.value] === null"
1818
[checked]="option.value"
1919
[disabled]="option.disabled || disabled"
20-
[id]="'checkbox_' + i"
20+
[id]="option.id"
2121
[required]="required"
2222
[value]="option.value">
2323

2424
<label #checkboxLabel
2525
class="po-checkbox-group-label"
26-
[class.po-clickable]="checkboxLabel.tabIndex === 0"
27-
[for]="'checkbox_' + i"
26+
[class.po-clickable]="!option.disabled && !disabled"
27+
[for]="option.id"
2828
[tabindex]="option.disabled || disabled ? -1 : 0"
2929
(click)="checkOption(option)"
3030
(keydown)="onKeyDown($event, option)">

projects/ui/src/lib/components/po-field/po-checkbox-group/po-checkbox-group.component.spec.ts

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { ChangeDetectorRef } from '@angular/core';
12
import { ComponentFixture, TestBed } from '@angular/core/testing';
23

34
import { configureTestSuite } from './../../../util-test/util-expect.spec';
@@ -7,6 +8,7 @@ import { PoFieldContainerBottomComponent } from './../po-field-container/po-fiel
78
import { PoFieldContainerComponent } from '../po-field-container/po-field-container.component';
89

910
describe('PoCheckboxGroupComponent:', () => {
11+
let changeDetector: any;
1012
let component: PoCheckboxGroupComponent;
1113
let fixture: ComponentFixture<PoCheckboxGroupComponent>;
1214
let nativeElement: any;
@@ -41,7 +43,8 @@ describe('PoCheckboxGroupComponent:', () => {
4143
{ value: '2', label: '2', disabled: true }
4244
];
4345

44-
fixture.detectChanges();
46+
changeDetector = fixture.componentRef.injector.get(ChangeDetectorRef);
47+
changeDetector.detectChanges();
4548

4649
nativeElement = fixture.debugElement.nativeElement;
4750
});
@@ -60,7 +63,7 @@ describe('PoCheckboxGroupComponent:', () => {
6063

6164
it('should be required', () => {
6265
component.required = true;
63-
fixture.detectChanges();
66+
changeDetector.detectChanges();
6467
expect(nativeElement.querySelector('.po-field-optional')).toBeFalsy();
6568
});
6669

@@ -80,14 +83,14 @@ describe('PoCheckboxGroupComponent:', () => {
8083

8184
it('should toggle checkbox option value 1', () => {
8285
component.checkOption(component.options[0]);
83-
fixture.detectChanges();
86+
changeDetector.detectChanges();
8487

8588
expect(nativeElement.querySelector('.po-checkbox-group-input-checked+label').innerHTML).toContain('1');
8689
expect(component.checkedOptions).toEqual({ 1: true });
8790
expect(component.checkedOptionsList).toEqual(['1']);
8891

8992
component.checkOption(component.options[0]);
90-
fixture.detectChanges();
93+
changeDetector.detectChanges();
9194

9295
expect(nativeElement.querySelector('.po-checkbox-group-input-checked')).toBeFalsy();
9396
expect(component.checkedOptions).toEqual({ 1: false });
@@ -98,7 +101,7 @@ describe('PoCheckboxGroupComponent:', () => {
98101
component.checkedOptions = { 1: null };
99102
component.indeterminate = true;
100103

101-
fixture.detectChanges();
104+
changeDetector.detectChanges();
102105

103106
expect(nativeElement.querySelector('.po-checkbox-group-input-indeterminate+label').innerHTML).toContain('1');
104107
});
@@ -108,7 +111,7 @@ describe('PoCheckboxGroupComponent:', () => {
108111
it('focus: should call `focus` of checkbox', () => {
109112
component.options = [{ label: 'teste1', value: 'teste1' }, { label: 'teste2', value: 'teste2' }];
110113

111-
fixture.detectChanges();
114+
changeDetector.detectChanges();
112115

113116
spyOn(component.checkboxLabels.toArray()[0].nativeElement, 'focus');
114117

@@ -120,7 +123,7 @@ describe('PoCheckboxGroupComponent:', () => {
120123
it('focus: should`t call `focus` of checkbox if option is `disabled`', () => {
121124
component.options = [{ label: 'teste1', value: 'teste1', disabled: true }, { label: 'teste2', value: 'teste2' }];
122125

123-
fixture.detectChanges();
126+
changeDetector.detectChanges();
124127

125128
spyOn(component.checkboxLabels.toArray()[0].nativeElement, 'focus');
126129
spyOn(component.checkboxLabels.toArray()[1].nativeElement, 'focus');
@@ -135,7 +138,7 @@ describe('PoCheckboxGroupComponent:', () => {
135138
component.options = [{ label: 'teste1', value: 'teste1', disabled: true }, { label: 'teste2', value: 'teste2' }];
136139
component.disabled = true;
137140

138-
fixture.detectChanges();
141+
changeDetector.detectChanges();
139142

140143
spyOn(component.checkboxLabels.toArray()[0].nativeElement, 'focus');
141144
spyOn(component.checkboxLabels.toArray()[1].nativeElement, 'focus');
@@ -146,6 +149,11 @@ describe('PoCheckboxGroupComponent:', () => {
146149
expect(component.checkboxLabels.toArray()[1].nativeElement.focus).not.toHaveBeenCalled();
147150
});
148151

152+
it('trackByFn: should return index', () => {
153+
const index = 1;
154+
expect(component.trackByFn(index)).toBe(index);
155+
});
156+
149157
describe('onKeyDown:', () => {
150158
let option;
151159
let fakeEvent: any;
@@ -204,40 +212,53 @@ describe('PoCheckboxGroupComponent:', () => {
204212

205213
it('should set tabindex to -1 when checkbox-group is disabled', () => {
206214
component.disabled = true;
207-
fixture.detectChanges();
215+
changeDetector.detectChanges();
208216

209217
expect(nativeElement.querySelector('label.po-checkbox-group-label[tabindex="-1"]')).toBeTruthy();
210218
});
211219

212220
it('should set tabindex to 0 when checkbox-group disabled is false', () => {
213221
component.disabled = false;
214-
fixture.detectChanges();
222+
changeDetector.detectChanges();
215223

216224
expect(nativeElement.querySelector('label.po-checkbox-group-label[tabindex="0"]')).toBeTruthy();
217225
});
218226

219227
it('should set tabindex to -1 when option disabled is true', () => {
220228
component.options = [{ label: 'teste', value: 'teste', disabled: true }];
221-
fixture.detectChanges();
229+
changeDetector.detectChanges();
222230

223231
expect(nativeElement.querySelector('label.po-checkbox-group-label[tabindex="-1"]')).toBeTruthy();
224232
});
225233

226234
it('should set tabindex to 0 when option disabled not exists', () => {
227235
component.options = [{ label: 'teste', value: 'teste' }];
228-
fixture.detectChanges();
236+
changeDetector.detectChanges();
229237

230238
expect(nativeElement.querySelector('label.po-checkbox-group-label[tabindex="0"]')).toBeTruthy();
231239
});
232240

233-
it('should set `po-clickable` class if `tabIndex` is equal 0.', () => {
241+
it('should set `po-clickable` class if `disabled` and `options.disabled` are false.', () => {
242+
component.options = [
243+
{ value: '1', label: '1' },
244+
{ value: '2', label: '2', disabled: true }
245+
];
246+
component.disabled = false;
247+
248+
changeDetector.detectChanges();
249+
234250
expect(nativeElement.querySelectorAll('label.po-checkbox-group-label.po-clickable')[0]).toBeTruthy();
235251
expect(nativeElement.querySelectorAll('label.po-checkbox-group-label.po-clickable')[1]).toBeFalsy();
236252
});
237253

238-
it('shouldn`t set `po-clickable` class if `tabIndex` is equal -1.', () => {
254+
it('shouldn`t set `po-clickable` class if `disabled` is true.', () => {
255+
component.options = [
256+
{ value: '1', label: '1' },
257+
{ value: '2', label: '2' }
258+
];
239259
component.disabled = true;
240-
fixture.detectChanges();
260+
261+
changeDetector.detectChanges();
241262

242263
expect(nativeElement.querySelectorAll('label.po-checkbox-group-label.po-clickable')[0]).toBeFalsy();
243264
expect(nativeElement.querySelectorAll('label.po-checkbox-group-label.po-clickable')[1]).toBeFalsy();
@@ -248,7 +269,7 @@ describe('PoCheckboxGroupComponent:', () => {
248269
component.optional = true;
249270
component.label = 'label';
250271

251-
fixture.detectChanges();
272+
changeDetector.detectChanges();
252273

253274
expect(fixture.debugElement.nativeElement.querySelector('.po-field-optional')).toBeTruthy();
254275
});
@@ -258,7 +279,7 @@ describe('PoCheckboxGroupComponent:', () => {
258279
component.optional = true;
259280
component.label = 'label';
260281

261-
fixture.detectChanges();
282+
changeDetector.detectChanges();
262283

263284
expect(fixture.debugElement.nativeElement.querySelector('.po-field-optional')).toBeNull();
264285
});
@@ -268,7 +289,7 @@ describe('PoCheckboxGroupComponent:', () => {
268289
component.optional = false;
269290
component.label = 'label';
270291

271-
fixture.detectChanges();
292+
changeDetector.detectChanges();
272293

273294
expect(fixture.debugElement.nativeElement.querySelector('.po-field-optional')).toBeNull();
274295
});

projects/ui/src/lib/components/po-field/po-checkbox-group/po-checkbox-group.component.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import { AfterViewChecked, ChangeDetectorRef, Component, ElementRef, forwardRef, QueryList, ViewChildren } from '@angular/core';
1+
import { AfterViewChecked, ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef,
2+
forwardRef, QueryList, ViewChildren } from '@angular/core';
23
import { NG_VALIDATORS, NG_VALUE_ACCESSOR } from '@angular/forms';
34

45
import { PoCheckboxGroupBaseComponent } from './po-checkbox-group-base.component';
5-
import { PoCheckboxGroupOption } from './po-checkbox-group-option.interface';
6+
import { PoCheckboxGroupOption } from './interfaces/po-checkbox-group-option.interface';
67

78
/**
89
* @docsExtends PoCheckboxGroupBaseComponent
@@ -27,6 +28,7 @@ import { PoCheckboxGroupOption } from './po-checkbox-group-option.interface';
2728
@Component({
2829
selector: 'po-checkbox-group',
2930
templateUrl: './po-checkbox-group.component.html',
31+
changeDetection: ChangeDetectionStrategy.OnPush,
3032
providers: [
3133
{
3234
provide: NG_VALUE_ACCESSOR,
@@ -89,4 +91,8 @@ export class PoCheckboxGroupComponent extends PoCheckboxGroupBaseComponent imple
8991
}
9092
}
9193

94+
trackByFn(index) {
95+
return index;
96+
}
97+
9298
}

projects/ui/src/lib/components/po-field/po-checkbox-group/samples/sample-po-checkbox-group-labs/sample-po-checkbox-group-labs.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export class SamplePoCheckboxGroupLabsComponent implements OnInit {
3838
}
3939

4040
addOption() {
41-
this.options.push(this.option);
41+
this.options = [...this.options, this.option];
4242
this.clearOption();
4343
}
4444

0 commit comments

Comments
 (0)