@acpaas-ui/ngx-forms 6.1.9 → 6.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.json +42 -0
- package/LICENSE.md +21 -0
- package/dist/README.md +23 -0
- package/dist/esm2020/lib/datepicker/components/datepicker/datepicker.component.mjs +232 -0
- package/{fesm2015 → dist/fesm2015}/acpaas-ui-ngx-forms.mjs +7 -4
- package/dist/fesm2015/acpaas-ui-ngx-forms.mjs.map +1 -0
- package/{fesm2020 → dist/fesm2020}/acpaas-ui-ngx-forms.mjs +7 -4
- package/dist/fesm2020/acpaas-ui-ngx-forms.mjs.map +1 -0
- package/dist/package.json +44 -0
- package/karma.conf.js +38 -0
- package/ng-package.json +8 -0
- package/package.json +6 -27
- package/src/lib/auto-complete/README.md +148 -0
- package/src/lib/auto-complete/auto-complete.module.ts +15 -0
- package/src/lib/auto-complete/components/auto-complete/auto-complete.component.html +51 -0
- package/src/lib/auto-complete/components/auto-complete/auto-complete.component.scss +4 -0
- package/src/lib/auto-complete/components/auto-complete/auto-complete.component.spec.ts +378 -0
- package/src/lib/auto-complete/components/auto-complete/auto-complete.component.ts +281 -0
- package/src/lib/auto-complete/public-api.ts +2 -0
- package/src/lib/datepicker/README.md +110 -0
- package/src/lib/datepicker/components/datepicker/datepicker.component.html +47 -0
- package/src/lib/datepicker/components/datepicker/datepicker.component.scss +13 -0
- package/src/lib/datepicker/components/datepicker/datepicker.component.spec.ts +204 -0
- package/src/lib/datepicker/components/datepicker/datepicker.component.ts +251 -0
- package/src/lib/datepicker/datepicker.conf.ts +11 -0
- package/src/lib/datepicker/datepicker.module.ts +50 -0
- package/src/lib/datepicker/public-api.ts +8 -0
- package/src/lib/datepicker/types/datepicker.types.ts +8 -0
- package/src/lib/range-slider/README.md +56 -0
- package/src/lib/range-slider/components/range-slider/range-slider.component.html +46 -0
- package/src/lib/range-slider/components/range-slider/range-slider.component.scss +12 -0
- package/src/lib/range-slider/components/range-slider/range-slider.component.spec.ts +216 -0
- package/src/lib/range-slider/components/range-slider/range-slider.component.ts +301 -0
- package/src/lib/range-slider/public-api.ts +3 -0
- package/src/lib/range-slider/range-slider.module.ts +11 -0
- package/src/lib/range-slider/types/range-slider.types.ts +4 -0
- package/src/lib/search-filter/README.md +86 -0
- package/src/lib/search-filter/components/search-filter/search-filter.component.html +66 -0
- package/src/lib/search-filter/components/search-filter/search-filter.component.scss +23 -0
- package/src/lib/search-filter/components/search-filter/search-filter.component.spec.ts +264 -0
- package/src/lib/search-filter/components/search-filter/search-filter.component.ts +140 -0
- package/src/lib/search-filter/public-api.ts +3 -0
- package/src/lib/search-filter/search-filter.module.ts +13 -0
- package/src/lib/search-filter/types/search-filter.types.ts +4 -0
- package/src/lib/shared/services/search.service.spec.ts +78 -0
- package/src/lib/shared/services/search.service.ts +32 -0
- package/src/lib/shared/types/search.types.ts +6 -0
- package/src/lib/timepicker/README.md +84 -0
- package/src/lib/timepicker/classes/timepicker.validators.spec.ts +54 -0
- package/src/lib/timepicker/classes/timepicker.validators.ts +61 -0
- package/src/lib/timepicker/components/timepicker/timepicker.component.html +37 -0
- package/src/lib/timepicker/components/timepicker/timepicker.component.scss +3 -0
- package/src/lib/timepicker/components/timepicker/timepicker.component.spec.ts +161 -0
- package/src/lib/timepicker/components/timepicker/timepicker.component.ts +128 -0
- package/src/lib/timepicker/public-api.ts +4 -0
- package/src/lib/timepicker/timepicker.module.ts +13 -0
- package/src/lib/timepicker/types/timepicker.types.ts +5 -0
- package/src/lib/upload/README.md +283 -0
- package/src/lib/upload/classes/uploader.class.spec.ts +100 -0
- package/src/lib/upload/classes/uploader.class.ts +144 -0
- package/src/lib/upload/components/upload/upload.component.html +28 -0
- package/src/lib/upload/components/upload/upload.component.scss +3 -0
- package/src/lib/upload/components/upload/upload.component.spec.ts +117 -0
- package/src/lib/upload/components/upload/upload.component.ts +50 -0
- package/src/lib/upload/components/upload-input/upload-input.component.html +11 -0
- package/src/lib/upload/components/upload-input/upload-input.component.spec.ts +55 -0
- package/src/lib/upload/components/upload-input/upload-input.component.ts +35 -0
- package/src/lib/upload/components/upload-queue/upload-queue.component.html +16 -0
- package/src/lib/upload/components/upload-queue/upload-queue.component.spec.ts +99 -0
- package/src/lib/upload/components/upload-queue/upload-queue.component.ts +36 -0
- package/src/lib/upload/components/upload-zone/upload-zone.component.html +55 -0
- package/src/lib/upload/components/upload-zone/upload-zone.component.scss +3 -0
- package/src/lib/upload/components/upload-zone/upload-zone.component.spec.ts +144 -0
- package/src/lib/upload/components/upload-zone/upload-zone.component.ts +142 -0
- package/src/lib/upload/components/validation-list/validation-list.component.html +15 -0
- package/src/lib/upload/components/validation-list/validation-list.component.spec.ts +57 -0
- package/src/lib/upload/components/validation-list/validation-list.component.ts +29 -0
- package/src/lib/upload/public-api.ts +10 -0
- package/src/lib/upload/services/validation-messages.service.spec.ts +66 -0
- package/src/lib/upload/services/validation-messages.service.ts +27 -0
- package/src/lib/upload/types/upload.types.ts +20 -0
- package/src/lib/upload/upload.conf.ts +15 -0
- package/src/lib/upload/upload.module.ts +34 -0
- package/src/public-api.ts +6 -0
- package/src/test.ts +9 -0
- package/tsconfig.lib.json +26 -0
- package/tsconfig.spec.json +17 -0
- package/esm2020/lib/datepicker/components/datepicker/datepicker.component.mjs +0 -229
- package/fesm2015/acpaas-ui-ngx-forms.mjs.map +0 -1
- package/fesm2020/acpaas-ui-ngx-forms.mjs.map +0 -1
- /package/{esm2020 → dist/esm2020}/acpaas-ui-ngx-forms.mjs +0 -0
- /package/{esm2020 → dist/esm2020}/lib/auto-complete/auto-complete.module.mjs +0 -0
- /package/{esm2020 → dist/esm2020}/lib/auto-complete/components/auto-complete/auto-complete.component.mjs +0 -0
- /package/{esm2020 → dist/esm2020}/lib/auto-complete/public-api.mjs +0 -0
- /package/{esm2020 → dist/esm2020}/lib/datepicker/datepicker.conf.mjs +0 -0
- /package/{esm2020 → dist/esm2020}/lib/datepicker/datepicker.module.mjs +0 -0
- /package/{esm2020 → dist/esm2020}/lib/datepicker/public-api.mjs +0 -0
- /package/{esm2020 → dist/esm2020}/lib/datepicker/types/datepicker.types.mjs +0 -0
- /package/{esm2020 → dist/esm2020}/lib/range-slider/components/range-slider/range-slider.component.mjs +0 -0
- /package/{esm2020 → dist/esm2020}/lib/range-slider/public-api.mjs +0 -0
- /package/{esm2020 → dist/esm2020}/lib/range-slider/range-slider.module.mjs +0 -0
- /package/{esm2020 → dist/esm2020}/lib/range-slider/types/range-slider.types.mjs +0 -0
- /package/{esm2020 → dist/esm2020}/lib/search-filter/components/search-filter/search-filter.component.mjs +0 -0
- /package/{esm2020 → dist/esm2020}/lib/search-filter/public-api.mjs +0 -0
- /package/{esm2020 → dist/esm2020}/lib/search-filter/search-filter.module.mjs +0 -0
- /package/{esm2020 → dist/esm2020}/lib/search-filter/types/search-filter.types.mjs +0 -0
- /package/{esm2020 → dist/esm2020}/lib/shared/services/search.service.mjs +0 -0
- /package/{esm2020 → dist/esm2020}/lib/shared/types/search.types.mjs +0 -0
- /package/{esm2020 → dist/esm2020}/lib/timepicker/classes/timepicker.validators.mjs +0 -0
- /package/{esm2020 → dist/esm2020}/lib/timepicker/components/timepicker/timepicker.component.mjs +0 -0
- /package/{esm2020 → dist/esm2020}/lib/timepicker/public-api.mjs +0 -0
- /package/{esm2020 → dist/esm2020}/lib/timepicker/timepicker.module.mjs +0 -0
- /package/{esm2020 → dist/esm2020}/lib/timepicker/types/timepicker.types.mjs +0 -0
- /package/{esm2020 → dist/esm2020}/lib/upload/classes/uploader.class.mjs +0 -0
- /package/{esm2020 → dist/esm2020}/lib/upload/components/upload/upload.component.mjs +0 -0
- /package/{esm2020 → dist/esm2020}/lib/upload/components/upload-input/upload-input.component.mjs +0 -0
- /package/{esm2020 → dist/esm2020}/lib/upload/components/upload-queue/upload-queue.component.mjs +0 -0
- /package/{esm2020 → dist/esm2020}/lib/upload/components/upload-zone/upload-zone.component.mjs +0 -0
- /package/{esm2020 → dist/esm2020}/lib/upload/components/validation-list/validation-list.component.mjs +0 -0
- /package/{esm2020 → dist/esm2020}/lib/upload/public-api.mjs +0 -0
- /package/{esm2020 → dist/esm2020}/lib/upload/services/validation-messages.service.mjs +0 -0
- /package/{esm2020 → dist/esm2020}/lib/upload/types/upload.types.mjs +0 -0
- /package/{esm2020 → dist/esm2020}/lib/upload/upload.conf.mjs +0 -0
- /package/{esm2020 → dist/esm2020}/lib/upload/upload.module.mjs +0 -0
- /package/{esm2020 → dist/esm2020}/public-api.mjs +0 -0
- /package/{index.d.ts → dist/index.d.ts} +0 -0
- /package/{lib → dist/lib}/auto-complete/auto-complete.module.d.ts +0 -0
- /package/{lib → dist/lib}/auto-complete/components/auto-complete/auto-complete.component.d.ts +0 -0
- /package/{lib → dist/lib}/auto-complete/public-api.d.ts +0 -0
- /package/{lib → dist/lib}/datepicker/components/datepicker/datepicker.component.d.ts +0 -0
- /package/{lib → dist/lib}/datepicker/datepicker.conf.d.ts +0 -0
- /package/{lib → dist/lib}/datepicker/datepicker.module.d.ts +0 -0
- /package/{lib → dist/lib}/datepicker/public-api.d.ts +0 -0
- /package/{lib → dist/lib}/datepicker/types/datepicker.types.d.ts +0 -0
- /package/{lib → dist/lib}/range-slider/components/range-slider/range-slider.component.d.ts +0 -0
- /package/{lib → dist/lib}/range-slider/public-api.d.ts +0 -0
- /package/{lib → dist/lib}/range-slider/range-slider.module.d.ts +0 -0
- /package/{lib → dist/lib}/range-slider/types/range-slider.types.d.ts +0 -0
- /package/{lib → dist/lib}/search-filter/components/search-filter/search-filter.component.d.ts +0 -0
- /package/{lib → dist/lib}/search-filter/public-api.d.ts +0 -0
- /package/{lib → dist/lib}/search-filter/search-filter.module.d.ts +0 -0
- /package/{lib → dist/lib}/search-filter/types/search-filter.types.d.ts +0 -0
- /package/{lib → dist/lib}/shared/services/search.service.d.ts +0 -0
- /package/{lib → dist/lib}/shared/types/search.types.d.ts +0 -0
- /package/{lib → dist/lib}/timepicker/classes/timepicker.validators.d.ts +0 -0
- /package/{lib → dist/lib}/timepicker/components/timepicker/timepicker.component.d.ts +0 -0
- /package/{lib → dist/lib}/timepicker/public-api.d.ts +0 -0
- /package/{lib → dist/lib}/timepicker/timepicker.module.d.ts +0 -0
- /package/{lib → dist/lib}/timepicker/types/timepicker.types.d.ts +0 -0
- /package/{lib → dist/lib}/upload/classes/uploader.class.d.ts +0 -0
- /package/{lib → dist/lib}/upload/components/upload/upload.component.d.ts +0 -0
- /package/{lib → dist/lib}/upload/components/upload-input/upload-input.component.d.ts +0 -0
- /package/{lib → dist/lib}/upload/components/upload-queue/upload-queue.component.d.ts +0 -0
- /package/{lib → dist/lib}/upload/components/upload-zone/upload-zone.component.d.ts +0 -0
- /package/{lib → dist/lib}/upload/components/validation-list/validation-list.component.d.ts +0 -0
- /package/{lib → dist/lib}/upload/public-api.d.ts +0 -0
- /package/{lib → dist/lib}/upload/services/validation-messages.service.d.ts +0 -0
- /package/{lib → dist/lib}/upload/types/upload.types.d.ts +0 -0
- /package/{lib → dist/lib}/upload/upload.conf.d.ts +0 -0
- /package/{lib → dist/lib}/upload/upload.module.d.ts +0 -0
- /package/{public-api.d.ts → dist/public-api.d.ts} +0 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { AbstractControl, ValidatorFn } from '@angular/forms';
|
|
2
|
+
|
|
3
|
+
export class TimePickerValidators {
|
|
4
|
+
// time `hh:mm` 24h format
|
|
5
|
+
public static minTime(time: string): ValidatorFn {
|
|
6
|
+
const validator = (control: AbstractControl): { [key: string]: any } => {
|
|
7
|
+
const splittedControlValue = control.value.split(':');
|
|
8
|
+
const controlHours = parseInt(splittedControlValue[0], 10);
|
|
9
|
+
const controlMinutes = parseInt(splittedControlValue[1], 10);
|
|
10
|
+
const splittedMinTime = time.split(':');
|
|
11
|
+
const minHours = parseInt(splittedMinTime[0], 10);
|
|
12
|
+
const minMinutes = parseInt(splittedMinTime[1], 10);
|
|
13
|
+
|
|
14
|
+
// Don't throw error --> use Validator.required
|
|
15
|
+
if (isNaN(controlHours) || isNaN(controlMinutes) || isNaN(minHours) || isNaN(minMinutes)) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (minHours < controlHours) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (minHours === controlHours && minMinutes <= controlMinutes) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return { minTime: { value: control.value } };
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
return validator;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// time `hh:mm` 24h format
|
|
34
|
+
public static maxTime(time: string): ValidatorFn {
|
|
35
|
+
const validator = (control: AbstractControl): { [key: string]: any } => {
|
|
36
|
+
const splittedControlValue = control.value.split(':');
|
|
37
|
+
const controlHours = parseInt(splittedControlValue[0], 10);
|
|
38
|
+
const controlMinutes = parseInt(splittedControlValue[1], 10);
|
|
39
|
+
const splittedMinTime = time.split(':');
|
|
40
|
+
const maxHours = parseInt(splittedMinTime[0], 10);
|
|
41
|
+
const maxMinutes = parseInt(splittedMinTime[1], 10);
|
|
42
|
+
|
|
43
|
+
// Don't throw error --> use Validator.required
|
|
44
|
+
if (isNaN(controlHours) || isNaN(controlMinutes) || isNaN(maxHours) || isNaN(maxMinutes)) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (maxHours > controlHours) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (maxHours === controlHours && maxMinutes >= controlMinutes) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return { maxTime: { value: control.value } };
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
return validator;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<div class="m-timepicker">
|
|
2
|
+
<div *ngIf="!shouldUseFallback" [class]="'a-input--' + size" [ngClass]="{ 'has-error': hasError }" class="a-input">
|
|
3
|
+
<label class="a-input__label" for="id" *ngIf="label">{{ label }}</label>
|
|
4
|
+
<small class="a-input__description" id="id" [ngClass]="{ 'is-error': hasError }" *ngIf="description">
|
|
5
|
+
<aui-icon *ngIf="hasError" name="ai-alert-triangle"></aui-icon>
|
|
6
|
+
{{ description }}</small
|
|
7
|
+
>
|
|
8
|
+
<input
|
|
9
|
+
[attr.aria-label]="ariaLabelHours + ':' + ariaLabelMinutes"
|
|
10
|
+
[formControl]="timeControl"
|
|
11
|
+
[id]="id"
|
|
12
|
+
type="time"
|
|
13
|
+
/>
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<div *ngIf="shouldUseFallback" [formGroup]="fallbackForm">
|
|
17
|
+
<div [class]="'a-input--' + size" [ngClass]="{ 'has-error': hasError }" class="a-input has-icon-right">
|
|
18
|
+
<div class="a-input__wrapper">
|
|
19
|
+
<select [attr.aria-label]="ariaLabelHours" [id]="id" formControlName="hours">
|
|
20
|
+
<option disabled value="null">{{ hoursPlaceholder }}</option>
|
|
21
|
+
<option *ngFor="let hour of hours" [value]="hour">{{ hour }}</option>
|
|
22
|
+
</select>
|
|
23
|
+
<aui-icon name="ai-arrow-down-1"></aui-icon>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
|
|
27
|
+
<div [class]="'a-input--' + size" [ngClass]="{ 'has-error': hasError }" class="a-input has-icon-right">
|
|
28
|
+
<div class="a-input__wrapper">
|
|
29
|
+
<select [attr.aria-label]="ariaLabelMinutes" formControlName="minutes">
|
|
30
|
+
<option disabled value="null">{{ minutesPlaceholder }}</option>
|
|
31
|
+
<option *ngFor="let minute of minutes" [value]="minute">{{ minute }}</option>
|
|
32
|
+
</select>
|
|
33
|
+
<aui-icon name="ai-arrow-down-1"></aui-icon>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
|
|
2
|
+
import { ReactiveFormsModule } from '@angular/forms';
|
|
3
|
+
import { IconModule } from '@acpaas-ui/ngx-icon';
|
|
4
|
+
|
|
5
|
+
import { TimepickerComponent } from './timepicker.component';
|
|
6
|
+
|
|
7
|
+
describe('The Timepicker Component', () => {
|
|
8
|
+
let comp: TimepickerComponent;
|
|
9
|
+
let fixture: ComponentFixture<TimepickerComponent>;
|
|
10
|
+
|
|
11
|
+
// waitForAsync beforeEach
|
|
12
|
+
beforeEach(waitForAsync(() => {
|
|
13
|
+
TestBed.configureTestingModule({
|
|
14
|
+
imports: [ReactiveFormsModule, IconModule],
|
|
15
|
+
declarations: [TimepickerComponent],
|
|
16
|
+
providers: [],
|
|
17
|
+
}).compileComponents();
|
|
18
|
+
}));
|
|
19
|
+
|
|
20
|
+
// synchronous beforeEach
|
|
21
|
+
beforeEach(() => {
|
|
22
|
+
fixture = TestBed.createComponent(TimepickerComponent);
|
|
23
|
+
comp = fixture.componentInstance;
|
|
24
|
+
comp.ngOnInit();
|
|
25
|
+
comp.registerOnChange((model) => {});
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
describe('init', () => {
|
|
29
|
+
it('should calc hours and minutes for fallback timepicker', () => {
|
|
30
|
+
expect(comp.hours).toEqual([
|
|
31
|
+
'00',
|
|
32
|
+
'01',
|
|
33
|
+
'02',
|
|
34
|
+
'03',
|
|
35
|
+
'04',
|
|
36
|
+
'05',
|
|
37
|
+
'06',
|
|
38
|
+
'07',
|
|
39
|
+
'08',
|
|
40
|
+
'09',
|
|
41
|
+
'10',
|
|
42
|
+
'11',
|
|
43
|
+
'12',
|
|
44
|
+
'13',
|
|
45
|
+
'14',
|
|
46
|
+
'15',
|
|
47
|
+
'16',
|
|
48
|
+
'17',
|
|
49
|
+
'18',
|
|
50
|
+
'19',
|
|
51
|
+
'20',
|
|
52
|
+
'21',
|
|
53
|
+
'22',
|
|
54
|
+
'23',
|
|
55
|
+
]); // eslint-disable-line max-len
|
|
56
|
+
expect(comp.minutes).toEqual([
|
|
57
|
+
'00',
|
|
58
|
+
'01',
|
|
59
|
+
'02',
|
|
60
|
+
'03',
|
|
61
|
+
'04',
|
|
62
|
+
'05',
|
|
63
|
+
'06',
|
|
64
|
+
'07',
|
|
65
|
+
'08',
|
|
66
|
+
'09',
|
|
67
|
+
'10',
|
|
68
|
+
'11',
|
|
69
|
+
'12',
|
|
70
|
+
'13',
|
|
71
|
+
'14',
|
|
72
|
+
'15',
|
|
73
|
+
'16',
|
|
74
|
+
'17',
|
|
75
|
+
'18',
|
|
76
|
+
'19',
|
|
77
|
+
'20',
|
|
78
|
+
'21',
|
|
79
|
+
'22',
|
|
80
|
+
'23',
|
|
81
|
+
'24',
|
|
82
|
+
'25',
|
|
83
|
+
'26',
|
|
84
|
+
'27',
|
|
85
|
+
'28',
|
|
86
|
+
'29',
|
|
87
|
+
'30',
|
|
88
|
+
'31',
|
|
89
|
+
'32',
|
|
90
|
+
'33',
|
|
91
|
+
'34',
|
|
92
|
+
'35',
|
|
93
|
+
'36',
|
|
94
|
+
'37',
|
|
95
|
+
'38',
|
|
96
|
+
'39',
|
|
97
|
+
'40',
|
|
98
|
+
'41',
|
|
99
|
+
'42',
|
|
100
|
+
'43',
|
|
101
|
+
'44',
|
|
102
|
+
'45',
|
|
103
|
+
'46',
|
|
104
|
+
'47',
|
|
105
|
+
'48',
|
|
106
|
+
'49',
|
|
107
|
+
'50',
|
|
108
|
+
'51',
|
|
109
|
+
'52',
|
|
110
|
+
'53',
|
|
111
|
+
'54',
|
|
112
|
+
'55',
|
|
113
|
+
'56',
|
|
114
|
+
'57',
|
|
115
|
+
'58',
|
|
116
|
+
'59',
|
|
117
|
+
]); // eslint-disable-line max-len
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
describe('native timepicker', () => {
|
|
122
|
+
it('should disable native form control', () => {
|
|
123
|
+
comp.setDisabledState(true);
|
|
124
|
+
expect(comp.timeControl.disabled).toBeTruthy();
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it('should enable native form control', () => {
|
|
128
|
+
comp.setDisabledState(false);
|
|
129
|
+
expect(comp.timeControl.enabled).toBeTruthy();
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it('should write value to native form control', () => {
|
|
133
|
+
comp.writeValue('20:30');
|
|
134
|
+
expect(comp.timeControl.value).toEqual('20:30');
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
describe('fallback timepicker', () => {
|
|
139
|
+
it('should disable fallback control', () => {
|
|
140
|
+
comp.setDisabledState(true);
|
|
141
|
+
expect(comp.fallbackForm.disabled).toBeTruthy();
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
it('should enable fallback control', () => {
|
|
145
|
+
comp.setDisabledState(false);
|
|
146
|
+
expect(comp.fallbackForm.enabled).toBeTruthy();
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it('should write value to fallback control', () => {
|
|
150
|
+
comp.writeValue('20:30');
|
|
151
|
+
expect(comp.fallbackForm.value).toEqual({ hours: '20', minutes: '30' });
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it('should update model if value changes', () => {
|
|
155
|
+
spyOn(comp, 'updateModel');
|
|
156
|
+
comp.fallbackForm.get('hours').setValue('20');
|
|
157
|
+
comp.fallbackForm.get('minutes').setValue('30');
|
|
158
|
+
expect(comp.updateModel).toHaveBeenCalledWith('20:30');
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
});
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { ChangeDetectionStrategy, Component, forwardRef, Input, OnDestroy, OnInit, Renderer2 } from '@angular/core';
|
|
2
|
+
import {
|
|
3
|
+
ControlValueAccessor,
|
|
4
|
+
UntypedFormBuilder,
|
|
5
|
+
UntypedFormControl,
|
|
6
|
+
UntypedFormGroup,
|
|
7
|
+
NG_VALUE_ACCESSOR,
|
|
8
|
+
} from '@angular/forms';
|
|
9
|
+
import { Subject } from 'rxjs';
|
|
10
|
+
import { takeUntil } from 'rxjs/operators';
|
|
11
|
+
|
|
12
|
+
import { DateHelper } from '@acpaas-ui/ngx-utils';
|
|
13
|
+
|
|
14
|
+
import { TimepickerInputSize } from '../../types/timepicker.types';
|
|
15
|
+
|
|
16
|
+
@Component({
|
|
17
|
+
selector: 'aui-timepicker',
|
|
18
|
+
templateUrl: './timepicker.component.html',
|
|
19
|
+
styleUrls: ['./timepicker.component.scss'],
|
|
20
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
21
|
+
providers: [
|
|
22
|
+
{
|
|
23
|
+
provide: NG_VALUE_ACCESSOR,
|
|
24
|
+
useExisting: forwardRef(() => TimepickerComponent), // eslint-disable-line @angular-eslint/no-forward-ref
|
|
25
|
+
multi: true,
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
})
|
|
29
|
+
export class TimepickerComponent implements OnInit, OnDestroy, ControlValueAccessor {
|
|
30
|
+
@Input() public id = 'aui-timepicker-' + Math.random().toString(36).substring(2);
|
|
31
|
+
@Input() public hoursPlaceholder = 'uu';
|
|
32
|
+
@Input() public minutesPlaceholder = 'mm';
|
|
33
|
+
@Input() public hasError = false;
|
|
34
|
+
@Input() public size: TimepickerInputSize = TimepickerInputSize.Auto;
|
|
35
|
+
@Input() public ariaLabelHours = 'Uur';
|
|
36
|
+
@Input() public ariaLabelMinutes = 'Minuten';
|
|
37
|
+
@Input() public label: string;
|
|
38
|
+
@Input() public description: string;
|
|
39
|
+
|
|
40
|
+
public shouldUseFallback = false;
|
|
41
|
+
public minutes: string[] = [];
|
|
42
|
+
public hours: string[] = [];
|
|
43
|
+
public updateModel: (value: string) => any;
|
|
44
|
+
|
|
45
|
+
public timeControl = new UntypedFormControl();
|
|
46
|
+
public fallbackForm: UntypedFormGroup;
|
|
47
|
+
|
|
48
|
+
private componentDestroyed$: Subject<boolean> = new Subject<boolean>();
|
|
49
|
+
|
|
50
|
+
constructor(private formBuilder: UntypedFormBuilder, private renderer: Renderer2) {}
|
|
51
|
+
|
|
52
|
+
public ngOnInit() {
|
|
53
|
+
this.shouldUseFallback = this.supportsNativeTimepicker();
|
|
54
|
+
this.minutes = this.getMinutes();
|
|
55
|
+
this.hours = this.getHours();
|
|
56
|
+
|
|
57
|
+
this.fallbackForm = this.formBuilder.group({
|
|
58
|
+
hours: null,
|
|
59
|
+
minutes: null,
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
this.fallbackForm.valueChanges.pipe(takeUntil(this.componentDestroyed$)).subscribe((formData) => {
|
|
63
|
+
if (formData.hours && formData.minutes) {
|
|
64
|
+
this.updateModel(`${formData.hours}:${formData.minutes}`);
|
|
65
|
+
} else {
|
|
66
|
+
this.updateModel('');
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
this.timeControl.valueChanges.pipe(takeUntil(this.componentDestroyed$)).subscribe((time) => {
|
|
71
|
+
this.updateModel(time);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
public ngOnDestroy() {
|
|
76
|
+
this.componentDestroyed$.next(true);
|
|
77
|
+
this.componentDestroyed$.complete();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
public writeValue(value: any): void {
|
|
81
|
+
this.timeControl.setValue(value, { emitEvent: false });
|
|
82
|
+
|
|
83
|
+
if (value) {
|
|
84
|
+
const splitted = value.split(':');
|
|
85
|
+
this.fallbackForm.get('hours').setValue(splitted[0], { emitEvent: false });
|
|
86
|
+
this.fallbackForm.get('minutes').setValue(splitted[1], { emitEvent: false });
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
public registerOnChange(onChange): void {
|
|
91
|
+
this.updateModel = onChange;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
public registerOnTouched(): void {}
|
|
95
|
+
|
|
96
|
+
public setDisabledState(isDisabled: boolean) {
|
|
97
|
+
if (isDisabled) {
|
|
98
|
+
this.timeControl.disable({ emitEvent: false });
|
|
99
|
+
this.fallbackForm.disable({ emitEvent: false });
|
|
100
|
+
} else {
|
|
101
|
+
this.timeControl.enable({ emitEvent: false });
|
|
102
|
+
this.fallbackForm.enable({ emitEvent: false });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
private supportsNativeTimepicker(): boolean {
|
|
107
|
+
const element = this.renderer.createElement('input');
|
|
108
|
+
element.type = 'time';
|
|
109
|
+
|
|
110
|
+
return element.type === 'text';
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
private getMinutes(): string[] {
|
|
114
|
+
return Array(60)
|
|
115
|
+
.fill('')
|
|
116
|
+
.map((value, index) => {
|
|
117
|
+
return DateHelper.addLeadingZero(index);
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
private getHours(): string[] {
|
|
122
|
+
return Array(24)
|
|
123
|
+
.fill('')
|
|
124
|
+
.map((value, index) => {
|
|
125
|
+
return DateHelper.addLeadingZero(index);
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { TimePickerValidators } from './classes/timepicker.validators';
|
|
2
|
+
export { TimepickerComponent } from './components/timepicker/timepicker.component';
|
|
3
|
+
export { TimepickerInputSize } from './types/timepicker.types';
|
|
4
|
+
export { TimepickerModule } from './timepicker.module';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { NgModule } from '@angular/core';
|
|
2
|
+
import { ReactiveFormsModule } from '@angular/forms';
|
|
3
|
+
import { CommonModule } from '@angular/common';
|
|
4
|
+
import { IconModule } from '@acpaas-ui/ngx-icon';
|
|
5
|
+
import { TimepickerComponent } from './components/timepicker/timepicker.component';
|
|
6
|
+
|
|
7
|
+
@NgModule({
|
|
8
|
+
imports: [ReactiveFormsModule, CommonModule, IconModule],
|
|
9
|
+
declarations: [TimepickerComponent],
|
|
10
|
+
exports: [TimepickerComponent],
|
|
11
|
+
providers: [],
|
|
12
|
+
})
|
|
13
|
+
export class TimepickerModule {}
|