@gravitee/ui-particles-angular 5.14.0 → 5.15.0
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/esm2020/lib/gio-form-focus-first-invalid/gio-form-focus-first-invalid.directive.mjs +6 -6
- package/esm2020/lib/gio-form-json-schema/gio-form-json-schema.component.mjs +32 -17
- package/esm2020/lib/gio-form-json-schema/gio-form-json-schema.module.mjs +21 -6
- package/esm2020/lib/gio-form-json-schema/gio-formly-json-schema.service.mjs +18 -1
- package/esm2020/lib/gio-form-json-schema/type-component/multischema-type.component.mjs +2 -2
- package/esm2020/lib/gio-form-json-schema/wrappers/gio-password-eye.component.mjs +72 -0
- package/fesm2015/gravitee-ui-particles-angular.mjs +136 -28
- package/fesm2015/gravitee-ui-particles-angular.mjs.map +1 -1
- package/fesm2020/gravitee-ui-particles-angular.mjs +142 -28
- package/fesm2020/gravitee-ui-particles-angular.mjs.map +1 -1
- package/lib/gio-form-json-schema/gio-form-json-schema.component.d.ts +2 -0
- package/lib/gio-form-json-schema/gio-form-json-schema.module.d.ts +12 -11
- package/lib/gio-form-json-schema/gio-formly-json-schema.service.d.ts +1 -0
- package/lib/gio-form-json-schema/wrappers/gio-password-eye.component.d.ts +12 -0
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { trigger, transition, style, animate } from '@angular/animations';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
3
|
import { EventEmitter, Component, HostBinding, Input, Output, HostListener, NgModule, Optional, Self, ViewChild, Directive, Inject, forwardRef, ChangeDetectionStrategy, Injectable, ViewEncapsulation, ContentChildren, Host, ContentChild, InjectionToken } from '@angular/core';
|
|
4
|
-
import { timer, Subject, fromEvent, of, BehaviorSubject, ReplaySubject } from 'rxjs';
|
|
4
|
+
import { timer, Subject, fromEvent, of, BehaviorSubject, combineLatest, ReplaySubject } from 'rxjs';
|
|
5
5
|
import * as i1 from '@angular/material/card';
|
|
6
6
|
import { MatCardModule } from '@angular/material/card';
|
|
7
7
|
import * as i2 from '@angular/material/button';
|
|
@@ -14,7 +14,7 @@ import { coerceBooleanProperty } from '@angular/cdk/coercion';
|
|
|
14
14
|
import * as i3$1 from '@angular/material/form-field';
|
|
15
15
|
import { MatFormFieldControl, MatFormFieldModule, MAT_FORM_FIELD_DEFAULT_OPTIONS } from '@angular/material/form-field';
|
|
16
16
|
import { isEmpty, toLower, dropRight, isNil, isArray, remove, isObject, cloneDeep, set, uniqueId } from 'lodash';
|
|
17
|
-
import { startWith, map, distinctUntilChanged, tap, debounce, takeUntil, delay, filter, switchMap } from 'rxjs/operators';
|
|
17
|
+
import { startWith, map, distinctUntilChanged, tap, debounce, takeUntil, delay, filter, switchMap, debounceTime } from 'rxjs/operators';
|
|
18
18
|
import * as i7 from '@angular/forms';
|
|
19
19
|
import { FormsModule, FormArray, FormGroup, FormControl, NG_VALUE_ACCESSOR, ReactiveFormsModule, NgControl } from '@angular/forms';
|
|
20
20
|
import * as i2$2 from '@angular/cdk/a11y';
|
|
@@ -2762,6 +2762,7 @@ class GioFormlyJsonSchemaService {
|
|
|
2762
2762
|
return this.formlyJsonschema.toFieldConfig(jsonSchema, {
|
|
2763
2763
|
map: (mappedField, mapSource) => {
|
|
2764
2764
|
mappedField = this.uiTypeMap(mappedField, mapSource);
|
|
2765
|
+
mappedField = this.formatMap(mappedField, mapSource);
|
|
2765
2766
|
mappedField = this.bannerMap(mappedField, mapSource);
|
|
2766
2767
|
mappedField = this.toggleMap(mappedField, mapSource);
|
|
2767
2768
|
return mappedField;
|
|
@@ -2773,6 +2774,16 @@ class GioFormlyJsonSchemaService {
|
|
|
2773
2774
|
mappedField.type = (_b = (_a = mapSource.gioConfig) === null || _a === void 0 ? void 0 : _a.uiType) !== null && _b !== void 0 ? _b : mappedField.type;
|
|
2774
2775
|
return mappedField;
|
|
2775
2776
|
}
|
|
2777
|
+
formatMap(mappedField, mapSource) {
|
|
2778
|
+
if (mapSource.type === 'string' && mapSource.format === 'text') {
|
|
2779
|
+
mappedField.type = 'textarea';
|
|
2780
|
+
mappedField.props = Object.assign(Object.assign({}, mappedField.props), { autosize: true });
|
|
2781
|
+
}
|
|
2782
|
+
else if (mapSource.type === 'string' && mapSource.format === 'password') {
|
|
2783
|
+
mappedField.props = Object.assign(Object.assign({}, mappedField.props), { type: 'password' });
|
|
2784
|
+
}
|
|
2785
|
+
return mappedField;
|
|
2786
|
+
}
|
|
2776
2787
|
bannerMap(mappedField, mapSource) {
|
|
2777
2788
|
var _a;
|
|
2778
2789
|
mappedField.props = Object.assign(Object.assign({}, mappedField.props), (((_a = mapSource.gioConfig) === null || _a === void 0 ? void 0 : _a.banner) ? getBannerProperties(mapSource.gioConfig.banner) : {}));
|
|
@@ -2823,9 +2834,11 @@ class GioFormJsonSchemaComponent {
|
|
|
2823
2834
|
this.options = {};
|
|
2824
2835
|
this.model = {};
|
|
2825
2836
|
this.fields = [];
|
|
2837
|
+
this.loading = true;
|
|
2826
2838
|
this._onChange = () => ({});
|
|
2827
2839
|
this._onTouched = () => ({});
|
|
2828
2840
|
this.touched = false;
|
|
2841
|
+
this.stateChanges$ = new Subject();
|
|
2829
2842
|
if (ngControl) {
|
|
2830
2843
|
// Setting the value accessor directly (instead of using
|
|
2831
2844
|
// the providers `NG_VALUE_ACCESSOR`) to avoid running into a circular import.
|
|
@@ -2846,24 +2859,37 @@ class GioFormJsonSchemaComponent {
|
|
|
2846
2859
|
}
|
|
2847
2860
|
ngOnInit() {
|
|
2848
2861
|
var _a, _b, _c;
|
|
2849
|
-
// When the parent form is touched, mark all the sub formGroup as touched
|
|
2862
|
+
// When the parent form is touched, mark all the sub formGroup as touched ony once
|
|
2850
2863
|
const parentControl = (_b = (_a = this.ngControl) === null || _a === void 0 ? void 0 : _a.control) === null || _b === void 0 ? void 0 : _b.parent;
|
|
2851
|
-
(_c = parentControl === null || parentControl === void 0 ? void 0 : parentControl.statusChanges) === null || _c === void 0 ? void 0 : _c.pipe(takeUntil(this.unsubscribe$), map(() => parentControl === null || parentControl === void 0 ? void 0 : parentControl.touched), filter(touched => touched === true),
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
if (status === 'VALID') {
|
|
2855
|
-
(_b = (_a = this.ngControl) === null || _a === void 0 ? void 0 : _a.control) === null || _b === void 0 ? void 0 : _b.setErrors(null);
|
|
2856
|
-
}
|
|
2857
|
-
if (status === 'INVALID') {
|
|
2858
|
-
(_d = (_c = this.ngControl) === null || _c === void 0 ? void 0 : _c.control) === null || _d === void 0 ? void 0 : _d.setErrors({ invalid: true });
|
|
2859
|
-
}
|
|
2864
|
+
(_c = parentControl === null || parentControl === void 0 ? void 0 : parentControl.statusChanges) === null || _c === void 0 ? void 0 : _c.pipe(takeUntil(this.unsubscribe$), map(() => parentControl === null || parentControl === void 0 ? void 0 : parentControl.touched), filter(touched => touched === true), distinctUntilChanged()).subscribe(() => {
|
|
2865
|
+
this.formGroup.markAllAsTouched();
|
|
2866
|
+
this.stateChanges$.next();
|
|
2860
2867
|
});
|
|
2861
2868
|
// To simulate the behavior of classic form controls, emit value only when the form is touched
|
|
2862
2869
|
// Allow to keep the formControl pristine until the user interact with it
|
|
2863
|
-
this.formGroup.valueChanges
|
|
2864
|
-
.pipe(takeUntil(this.unsubscribe$),
|
|
2865
|
-
|
|
2866
|
-
|
|
2870
|
+
combineLatest([this.formGroup.statusChanges, this.formGroup.valueChanges])
|
|
2871
|
+
.pipe(takeUntil(this.unsubscribe$),
|
|
2872
|
+
// Group all valueChanges events emit by formly in a single one
|
|
2873
|
+
debounceTime(100))
|
|
2874
|
+
.subscribe(() => {
|
|
2875
|
+
this.stateChanges$.next();
|
|
2876
|
+
});
|
|
2877
|
+
this.stateChanges$.pipe(takeUntil(this.unsubscribe$)).subscribe(() => {
|
|
2878
|
+
var _a, _b, _c, _d;
|
|
2879
|
+
const { status, value, touched } = this.formGroup;
|
|
2880
|
+
if (touched) {
|
|
2881
|
+
this._onTouched();
|
|
2882
|
+
this.touched = true;
|
|
2883
|
+
}
|
|
2884
|
+
if (this.touched) {
|
|
2885
|
+
this._onChange(value);
|
|
2886
|
+
if (status === 'VALID') {
|
|
2887
|
+
(_b = (_a = this.ngControl) === null || _a === void 0 ? void 0 : _a.control) === null || _b === void 0 ? void 0 : _b.setErrors(null);
|
|
2888
|
+
}
|
|
2889
|
+
if (status === 'INVALID') {
|
|
2890
|
+
(_d = (_c = this.ngControl) === null || _c === void 0 ? void 0 : _c.control) === null || _d === void 0 ? void 0 : _d.setErrors({ invalid: true });
|
|
2891
|
+
}
|
|
2892
|
+
}
|
|
2867
2893
|
});
|
|
2868
2894
|
}
|
|
2869
2895
|
ngOnDestroy() {
|
|
@@ -3329,7 +3355,7 @@ GioFjsMultiSchemaTypeComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
|
3329
3355
|
</div>
|
|
3330
3356
|
<formly-field *ngFor="let f of field.fieldGroup" [field]="f"></formly-field>
|
|
3331
3357
|
</div>
|
|
3332
|
-
`, isInline: true, styles: [".
|
|
3358
|
+
`, isInline: true, styles: [".wrapper__title{font-size:16px;font-weight:500;line-height:24px;font:600 14px/20px Golos UI,Roboto,Helvetica Neue,sans-serif;letter-spacing:.4px;margin-bottom:4px}.wrapper:empty{display:none}.wrapper__error{font:400 12px/16px Golos UI,Roboto,Helvetica Neue,sans-serif;letter-spacing:normal;color:#ec4899}\n"], components: [{ type: i1$4.ɵFormlyValidationMessage, selector: "formly-validation-message", inputs: ["field"] }, { type: i1$4.FormlyField, selector: "formly-field", inputs: ["field"] }], directives: [{ type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
|
|
3333
3359
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: GioFjsMultiSchemaTypeComponent, decorators: [{
|
|
3334
3360
|
type: Component,
|
|
3335
3361
|
args: [{ selector: 'gio-fjs-multi-schema-type', template: `
|
|
@@ -3341,7 +3367,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImpo
|
|
|
3341
3367
|
</div>
|
|
3342
3368
|
<formly-field *ngFor="let f of field.fieldGroup" [field]="f"></formly-field>
|
|
3343
3369
|
</div>
|
|
3344
|
-
`, styles: [".
|
|
3370
|
+
`, styles: [".wrapper__title{font-size:16px;font-weight:500;line-height:24px;font:600 14px/20px Golos UI,Roboto,Helvetica Neue,sans-serif;letter-spacing:.4px;margin-bottom:4px}.wrapper:empty{display:none}.wrapper__error{font:400 12px/16px Golos UI,Roboto,Helvetica Neue,sans-serif;letter-spacing:normal;color:#ec4899}\n"] }]
|
|
3345
3371
|
}] });
|
|
3346
3372
|
|
|
3347
3373
|
/*
|
|
@@ -3479,6 +3505,74 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImpo
|
|
|
3479
3505
|
`, styles: [".wrapper{display:flex;flex-direction:column;padding:8px;border:1px solid #d3d5dc;border-radius:8px}.wrapper__header{display:flex}.wrapper__header__text{flex:1 1 auto}.wrapper__header__text__title{font:600 16px/24px Golos UI,Roboto,Helvetica Neue,sans-serif;letter-spacing:.4px;margin-bottom:8px}.wrapper__header__collapse{flex:0 0 auto}.wrapper__header__collapse .collapse-open{transform:rotate(180deg);transition:transform 225ms cubic-bezier(.4,0,.2,1)}.wrapper__header__collapse .collapse-close{transform:rotate(0);transition:transform 225ms cubic-bezier(.4,0,.2,1)}.wrapper__error{font:400 12px/16px Golos UI,Roboto,Helvetica Neue,sans-serif;letter-spacing:normal;color:#ec4899}\n"] }]
|
|
3480
3506
|
}] });
|
|
3481
3507
|
|
|
3508
|
+
/*
|
|
3509
|
+
* Copyright (C) 2023 The Gravitee team (http://gravitee.io)
|
|
3510
|
+
*
|
|
3511
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
3512
|
+
* you may not use this file except in compliance with the License.
|
|
3513
|
+
* You may obtain a copy of the License at
|
|
3514
|
+
*
|
|
3515
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
3516
|
+
*
|
|
3517
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
3518
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
3519
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
3520
|
+
* See the License for the specific language governing permissions and
|
|
3521
|
+
* limitations under the License.
|
|
3522
|
+
*/
|
|
3523
|
+
class GioPasswordEyeWrapperComponent extends FieldWrapper {
|
|
3524
|
+
constructor() {
|
|
3525
|
+
super(...arguments);
|
|
3526
|
+
this.hide = true;
|
|
3527
|
+
}
|
|
3528
|
+
ngAfterViewInit() {
|
|
3529
|
+
if (this.matSuffix) {
|
|
3530
|
+
this.props.suffix = this.matSuffix;
|
|
3531
|
+
}
|
|
3532
|
+
}
|
|
3533
|
+
addonEyeClick($event) {
|
|
3534
|
+
$event.stopPropagation();
|
|
3535
|
+
this.hide = !this.hide;
|
|
3536
|
+
this.props.type = this.hide ? 'password' : 'text';
|
|
3537
|
+
}
|
|
3538
|
+
}
|
|
3539
|
+
GioPasswordEyeWrapperComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: GioPasswordEyeWrapperComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
3540
|
+
GioPasswordEyeWrapperComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.12", type: GioPasswordEyeWrapperComponent, selector: "gio-password-eye-wrapper", viewQueries: [{ propertyName: "matSuffix", first: true, predicate: ["matSuffix"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: `
|
|
3541
|
+
<ng-container #fieldComponent></ng-container>
|
|
3542
|
+
|
|
3543
|
+
<ng-template #matSuffix>
|
|
3544
|
+
<span style="cursor: pointer" (click)="addonEyeClick($event)">
|
|
3545
|
+
<mat-icon [svgIcon]="hide ? 'gio:eye-empty' : 'gio:eye-off'"></mat-icon>
|
|
3546
|
+
</span>
|
|
3547
|
+
</ng-template>
|
|
3548
|
+
`, isInline: true, components: [{ type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
|
|
3549
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: GioPasswordEyeWrapperComponent, decorators: [{
|
|
3550
|
+
type: Component,
|
|
3551
|
+
args: [{
|
|
3552
|
+
selector: 'gio-password-eye-wrapper',
|
|
3553
|
+
template: `
|
|
3554
|
+
<ng-container #fieldComponent></ng-container>
|
|
3555
|
+
|
|
3556
|
+
<ng-template #matSuffix>
|
|
3557
|
+
<span style="cursor: pointer" (click)="addonEyeClick($event)">
|
|
3558
|
+
<mat-icon [svgIcon]="hide ? 'gio:eye-empty' : 'gio:eye-off'"></mat-icon>
|
|
3559
|
+
</span>
|
|
3560
|
+
</ng-template>
|
|
3561
|
+
`,
|
|
3562
|
+
}]
|
|
3563
|
+
}], propDecorators: { matSuffix: [{
|
|
3564
|
+
type: ViewChild,
|
|
3565
|
+
args: ['matSuffix', { static: true }]
|
|
3566
|
+
}] } });
|
|
3567
|
+
function passwordEyeExtension(field) {
|
|
3568
|
+
if (!field.props || (field.wrappers && field.wrappers.indexOf('gio-password-eye') !== -1)) {
|
|
3569
|
+
return;
|
|
3570
|
+
}
|
|
3571
|
+
if (field.props.type === 'password') {
|
|
3572
|
+
field.wrappers = [...(field.wrappers || []), 'gio-password-eye'];
|
|
3573
|
+
}
|
|
3574
|
+
}
|
|
3575
|
+
|
|
3482
3576
|
/*
|
|
3483
3577
|
* Copyright (C) 2015 The Gravitee team (http://gravitee.io)
|
|
3484
3578
|
*
|
|
@@ -3504,7 +3598,8 @@ GioFormJsonSchemaModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0",
|
|
|
3504
3598
|
GioFjsArrayTypeComponent,
|
|
3505
3599
|
GioFjsToggleTypeComponent,
|
|
3506
3600
|
GioFjsHeadersTypeComponent,
|
|
3507
|
-
GioFormFieldWrapperComponent
|
|
3601
|
+
GioFormFieldWrapperComponent,
|
|
3602
|
+
GioPasswordEyeWrapperComponent], imports: [CommonModule,
|
|
3508
3603
|
A11yModule,
|
|
3509
3604
|
ReactiveFormsModule, i1$4.FormlyModule, FormlyMaterialModule,
|
|
3510
3605
|
GioIconsModule,
|
|
@@ -3532,7 +3627,10 @@ GioFormJsonSchemaModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0",
|
|
|
3532
3627
|
{ name: 'uniqueItems', message: 'Should NOT have duplicate items' },
|
|
3533
3628
|
{ name: 'const', message: constValidationMessage },
|
|
3534
3629
|
],
|
|
3535
|
-
wrappers: [
|
|
3630
|
+
wrappers: [
|
|
3631
|
+
{ name: 'gio-with-banner', component: GioFormFieldWrapperComponent },
|
|
3632
|
+
{ name: 'gio-password-eye', component: GioPasswordEyeWrapperComponent },
|
|
3633
|
+
],
|
|
3536
3634
|
types: [
|
|
3537
3635
|
{ name: 'null', component: GioFjsNullTypeComponent, wrappers: ['form-field'] },
|
|
3538
3636
|
{ name: 'array', component: GioFjsArrayTypeComponent },
|
|
@@ -3547,7 +3645,10 @@ GioFormJsonSchemaModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0",
|
|
|
3547
3645
|
component: GioFjsHeadersTypeComponent,
|
|
3548
3646
|
},
|
|
3549
3647
|
],
|
|
3550
|
-
extensions: [
|
|
3648
|
+
extensions: [
|
|
3649
|
+
{ name: 'banner', extension: { onPopulate: bannerExtension } },
|
|
3650
|
+
{ name: 'password-eye', extension: { onPopulate: passwordEyeExtension } },
|
|
3651
|
+
],
|
|
3551
3652
|
extras: {
|
|
3552
3653
|
checkExpressionOn: 'changeDetectionCheck',
|
|
3553
3654
|
},
|
|
@@ -3571,6 +3672,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImpo
|
|
|
3571
3672
|
GioFjsToggleTypeComponent,
|
|
3572
3673
|
GioFjsHeadersTypeComponent,
|
|
3573
3674
|
GioFormFieldWrapperComponent,
|
|
3675
|
+
GioPasswordEyeWrapperComponent,
|
|
3574
3676
|
],
|
|
3575
3677
|
imports: [
|
|
3576
3678
|
CommonModule,
|
|
@@ -3592,7 +3694,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImpo
|
|
|
3592
3694
|
{ name: 'uniqueItems', message: 'Should NOT have duplicate items' },
|
|
3593
3695
|
{ name: 'const', message: constValidationMessage },
|
|
3594
3696
|
],
|
|
3595
|
-
wrappers: [
|
|
3697
|
+
wrappers: [
|
|
3698
|
+
{ name: 'gio-with-banner', component: GioFormFieldWrapperComponent },
|
|
3699
|
+
{ name: 'gio-password-eye', component: GioPasswordEyeWrapperComponent },
|
|
3700
|
+
],
|
|
3596
3701
|
types: [
|
|
3597
3702
|
{ name: 'null', component: GioFjsNullTypeComponent, wrappers: ['form-field'] },
|
|
3598
3703
|
{ name: 'array', component: GioFjsArrayTypeComponent },
|
|
@@ -3607,7 +3712,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImpo
|
|
|
3607
3712
|
component: GioFjsHeadersTypeComponent,
|
|
3608
3713
|
},
|
|
3609
3714
|
],
|
|
3610
|
-
extensions: [
|
|
3715
|
+
extensions: [
|
|
3716
|
+
{ name: 'banner', extension: { onPopulate: bannerExtension } },
|
|
3717
|
+
{ name: 'password-eye', extension: { onPopulate: passwordEyeExtension } },
|
|
3718
|
+
],
|
|
3611
3719
|
extras: {
|
|
3612
3720
|
checkExpressionOn: 'changeDetectionCheck',
|
|
3613
3721
|
},
|
|
@@ -3647,17 +3755,17 @@ class GioFormFocusInvalidDirective {
|
|
|
3647
3755
|
onFormSubmit() {
|
|
3648
3756
|
const selector = '.ng-invalid[formControlName],input.ng-invalid,mat-select.ng-invalid,textarea.ng-invalid,.gio-ng-invalid';
|
|
3649
3757
|
try {
|
|
3758
|
+
// Mark all controls as touched to display errors
|
|
3759
|
+
if (this.formGroupDirective) {
|
|
3760
|
+
this.formGroupDirective.control.markAllAsTouched();
|
|
3761
|
+
this.formGroupDirective.control.updateValueAndValidity();
|
|
3762
|
+
}
|
|
3650
3763
|
let invalidControl = this.renderer.selectRootElement(selector, true);
|
|
3651
3764
|
// If the form is a GioFormJsonSchema, we need to focus the first invalid control inside
|
|
3652
3765
|
if (invalidControl.tagName === 'GIO-FORM-JSON-SCHEMA') {
|
|
3653
3766
|
invalidControl = invalidControl.querySelector(selector);
|
|
3654
3767
|
}
|
|
3655
3768
|
if (invalidControl) {
|
|
3656
|
-
// Mark all controls as touched to display errors
|
|
3657
|
-
if (this.formGroupDirective) {
|
|
3658
|
-
this.formGroupDirective.control.markAllAsTouched();
|
|
3659
|
-
this.formGroupDirective.control.updateValueAndValidity();
|
|
3660
|
-
}
|
|
3661
3769
|
invalidControl.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
3662
3770
|
invalidControl.focus({ preventScroll: true });
|
|
3663
3771
|
}
|