@klippa/ngx-enhancy-forms 16.7.7 → 16.9.3

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.
@@ -1,10 +1,11 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Directive, Input, Component, SkipSelf, Optional, InjectionToken, Inject, ViewChild, EventEmitter, Host, Output, HostBinding, TemplateRef, ContentChild, NgModule } from '@angular/core';
2
+ import { Directive, Input, Component, SkipSelf, Optional, InjectionToken, Inject, ViewChild, EventEmitter, Host, Output, HostBinding, TemplateRef, ContentChild, inject, NgModule } from '@angular/core';
3
3
  import * as i1 from '@angular/common';
4
4
  import { CommonModule } from '@angular/common';
5
5
  import * as i2 from '@angular/forms';
6
6
  import { UntypedFormArray, UntypedFormGroup, UntypedFormControl, FormControl, FormArray, FormGroup, NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';
7
- import { isString, isArray } from 'lodash-es';
7
+ import { isString } from 'lodash-es';
8
+ import { isArray } from 'lodash';
8
9
  import * as i4 from '@ng-select/ng-select';
9
10
  import { NgSelectModule } from '@ng-select/ng-select';
10
11
  import * as i2$1 from '@dustfoundation/ngx-sortablejs';
@@ -84,6 +85,9 @@ function splitArrayByCondition(value, condition) {
84
85
  return acc;
85
86
  }, [[]]);
86
87
  }
88
+ function isArrayOf(arr, kind) {
89
+ return arr.reduce((acc, val) => acc && val instanceof kind, true);
90
+ }
87
91
 
88
92
  function mergeArray(arrA, arrB) {
89
93
  const arr = new Array(Math.max(arrA.length, arrB.length));
@@ -150,6 +154,9 @@ class FormComponent {
150
154
  this.activeControls = [];
151
155
  }
152
156
  ngOnInit() {
157
+ if (isValueSet(this.patchValueInterceptor)) {
158
+ this.addSupportForPatchValueInterceptor();
159
+ }
153
160
  if (isValueSet(this.parent) && isValueSet(this.subFormPlaceholder)) {
154
161
  const injectInto = this.subFormPlaceholder.injectInto;
155
162
  const injectAt = this.subFormPlaceholder.at;
@@ -180,9 +187,6 @@ class FormComponent {
180
187
  injectInto.setControl(injectAt, this.formGroup);
181
188
  }
182
189
  }
183
- if (isValueSet(this.patchValueInterceptor)) {
184
- this.addSupportForPatchValueInterceptor();
185
- }
186
190
  }
187
191
  ngOnChanges(simpleChanges) {
188
192
  if (simpleChanges.readOnly?.currentValue === true) {
@@ -281,6 +285,25 @@ class FormComponent {
281
285
  const formGroupValue = this.formGroup.value;
282
286
  const renderedAndEnabledValues = this.getRenderedFieldValuesFormGroup(this.formGroup, true);
283
287
  const renderedButDisabledValues = this.getRenderedFieldValuesFormGroup(this.formGroup, false);
288
+ return new Promise((resolve, reject) => {
289
+ if (this.formGroup.pending) {
290
+ const sub = this.formGroup.statusChanges.subscribe((res) => {
291
+ if (res !== 'PENDING') {
292
+ sub.unsubscribe();
293
+ this.handleSubmission(originalDisabledStates, renderedAndEnabledValues, renderedButDisabledValues, formGroupValue)
294
+ .then(resolve)
295
+ .catch(reject);
296
+ }
297
+ });
298
+ }
299
+ else {
300
+ this.handleSubmission(originalDisabledStates, renderedAndEnabledValues, renderedButDisabledValues, formGroupValue)
301
+ .then(resolve)
302
+ .catch(reject);
303
+ }
304
+ });
305
+ }
306
+ handleSubmission(originalDisabledStates, renderedAndEnabledValues, renderedButDisabledValues, formGroupValue) {
284
307
  if (this.formGroup.invalid) {
285
308
  this.activeControls.find((e) => !e.formControl.valid)?.formElement?.scrollTo();
286
309
  this.setDisabledStatesForAllControls(originalDisabledStates);
@@ -359,6 +382,86 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.1", ngImpor
359
382
  type: Input
360
383
  }] } });
361
384
 
385
+ const triangleSize = '12px';
386
+ class WithTooltipDirective {
387
+ constructor(el) {
388
+ this.klpWithTooltip = true;
389
+ el.nativeElement.addEventListener('mouseenter', () => {
390
+ if (!this.klpWithTooltip) {
391
+ return;
392
+ }
393
+ if (getComputedStyle(el.nativeElement).position === 'static') {
394
+ el.nativeElement.style.position = 'relative';
395
+ }
396
+ this.div = document.createElement('div');
397
+ this.div.style.zIndex = '2';
398
+ this.div.style.color = '#ff8000';
399
+ this.div.style.position = 'fixed';
400
+ this.div.style.left = `${el.nativeElement.getBoundingClientRect().x}px`;
401
+ this.div.style.top = `${el.nativeElement.getBoundingClientRect().y}px`;
402
+ this.div.style.transform = `translate(calc(-100% + ${el.nativeElement.getBoundingClientRect().width}px), calc(-100% - 0.3rem))`;
403
+ this.div.style.maxWidth = '200px';
404
+ this.div.style.whiteSpace = 'break-spaces';
405
+ this.div.style.backgroundColor = 'white';
406
+ this.div.style.border = '1px solid rgba(255, 128, 0, 0.1254901961)';
407
+ this.div.style.boxShadow = `2px 3px 10px 0px rgba(255, 128, 0, 0.1254901961)`;
408
+ this.div.style.padding = '0.3rem 0.5rem';
409
+ this.div.style.boxSizing = 'border-box';
410
+ this.div.style.borderRadius = '3px';
411
+ this.div.textContent = el.nativeElement.innerText;
412
+ el.nativeElement.prepend(this.div);
413
+ this.triangle = document.createElement('div');
414
+ this.triangle.style.zIndex = '1';
415
+ this.triangle.style.position = 'fixed';
416
+ this.triangle.style.left = `calc(${el.nativeElement.getBoundingClientRect().x + el.nativeElement.getBoundingClientRect().width}px - 2rem)`;
417
+ this.triangle.style.top = `${el.nativeElement.getBoundingClientRect().y}px`;
418
+ this.triangle.style.transform = `translate(-50%, calc(-100% + 0.1rem))`;
419
+ this.triangle.style.width = '0';
420
+ this.triangle.style.height = '0';
421
+ this.triangle.style.borderLeft = `${triangleSize} solid transparent`;
422
+ this.triangle.style.borderRight = `${triangleSize} solid transparent`;
423
+ this.triangle.style.borderTop = `${triangleSize} solid rgba(255, 128, 0, 0.1254901961)`;
424
+ el.nativeElement.prepend(this.triangle);
425
+ this.triangleWhite = document.createElement('div');
426
+ this.triangleWhite.style.zIndex = '3';
427
+ this.triangleWhite.style.position = 'fixed';
428
+ this.triangleWhite.style.left = `calc(${el.nativeElement.getBoundingClientRect().x + el.nativeElement.getBoundingClientRect().width}px - 2rem)`;
429
+ this.triangleWhite.style.top = `${el.nativeElement.getBoundingClientRect().y}px`;
430
+ this.triangleWhite.style.transform = `translate(-50%, calc(-100% + 0.1rem - 2px))`;
431
+ this.triangleWhite.style.width = '0';
432
+ this.triangleWhite.style.height = '0';
433
+ this.triangleWhite.style.borderLeft = `${triangleSize} solid transparent`;
434
+ this.triangleWhite.style.borderRight = `${triangleSize} solid transparent`;
435
+ this.triangleWhite.style.borderTop = `${triangleSize} solid white`;
436
+ el.nativeElement.prepend(this.triangleWhite);
437
+ });
438
+ el.nativeElement.addEventListener('mouseout', () => {
439
+ try {
440
+ el.nativeElement.removeChild(this.div);
441
+ }
442
+ catch (ex) { }
443
+ try {
444
+ el.nativeElement.removeChild(this.triangle);
445
+ }
446
+ catch (ex) { }
447
+ try {
448
+ el.nativeElement.removeChild(this.triangleWhite);
449
+ }
450
+ catch (ex) { }
451
+ });
452
+ }
453
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: WithTooltipDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
454
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.1", type: WithTooltipDirective, selector: "[klpWithTooltip]", inputs: { klpWithTooltip: "klpWithTooltip" }, ngImport: i0 }); }
455
+ }
456
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: WithTooltipDirective, decorators: [{
457
+ type: Directive,
458
+ args: [{
459
+ selector: '[klpWithTooltip]'
460
+ }]
461
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { klpWithTooltip: [{
462
+ type: Input
463
+ }] } });
464
+
362
465
  const FORM_ERROR_MESSAGES = new InjectionToken('form.error.messages');
363
466
  const DEFAULT_ERROR_MESSAGES = {
364
467
  min: 'Use a number larger than %min%',
@@ -379,6 +482,7 @@ class FormElementComponent {
379
482
  this.captionSpacing = 'percentages';
380
483
  this.spaceDistribution = '40-60';
381
484
  this.swapInputAndCaption = false;
485
+ this.errorMessageAsTooltip = false;
382
486
  this.errorMessages = DEFAULT_ERROR_MESSAGES;
383
487
  this.customErrorHandlers = [];
384
488
  }
@@ -449,11 +553,11 @@ class FormElementComponent {
449
553
  return this.parent?.errorMessageLocation ?? 'belowCaption';
450
554
  }
451
555
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: FormElementComponent, deps: [{ token: FormComponent, optional: true }, { token: FORM_ERROR_MESSAGES, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
452
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.1", type: FormElementComponent, selector: "klp-form-element", inputs: { caption: "caption", direction: "direction", captionSpacing: "captionSpacing", spaceDistribution: "spaceDistribution", swapInputAndCaption: "swapInputAndCaption" }, viewQueries: [{ propertyName: "internalComponentRef", first: true, predicate: ["internalComponentRef"], descendants: true }], ngImport: i0, template: "<ng-template #errorRef>\n\t<div *ngIf=\"shouldShowErrorMessages() && getErrorToShow()\" class=\"errorContainer\" [ngClass]=\"{hasCaption: caption || captionRef, 'd30-70': spaceDistribution === '30-70', 'd34-66': spaceDistribution === '34-66'}\">\n\t\t<div *ngIf=\"showDefaultError('min')\">{{substituteParameters(getErrorMessage(\"min\"), {min: attachedControl.errors.min.min})}}</div>\n\t\t<div *ngIf=\"showDefaultError('max')\">{{substituteParameters(getErrorMessage(\"max\"), {max: attachedControl.errors.max.max})}}</div>\n\t\t<div *ngIf=\"showDefaultError('required')\">{{getErrorMessage(\"required\")}}</div>\n\t\t<div *ngIf=\"showDefaultError('email')\">{{getErrorMessage(\"email\")}}</div>\n\t\t<div *ngIf=\"showDefaultError('minlength')\">{{substituteParameters(getErrorMessage(\"minLength\"), {minLength: attachedControl.errors.minlength.requiredLength})}}</div>\n\t\t<div *ngIf=\"showDefaultError('maxlength')\">{{substituteParameters(getErrorMessage(\"maxLength\"), {maxLength: attachedControl.errors.maxlength.requiredLength})}}</div>\n\t\t<div *ngIf=\"showDefaultError('pattern')\">{{getErrorMessage(\"pattern\")}}</div>\n\t\t<div *ngIf=\"showDefaultError('MatchPassword')\">{{getErrorMessage(\"matchPassword\")}}</div>\n\t\t<div *ngIf=\"showDefaultError('date')\">{{getErrorMessage(\"date\")}}</div>\n\t\t<div *ngIf=\"showDefaultError('message')\">{{attachedControl.errors.message.value}}</div>\n\t\t<div [ngTemplateOutlet]=\"getCustomErrorHandler(getErrorToShow())?.templateRef\"></div>\n\t</div>\n</ng-template>\n\n<ng-container *ngIf=\"direction === 'horizontal'\" [ngTemplateOutlet]=\"errorRef\"></ng-container>\n\n<div class=\"componentContainer\" [ngClass]=\"{hasCaption: caption || captionRef, vertical: direction === 'vertical', reverseOrder: swapInputAndCaption}\" #internalComponentRef>\n\t<div class=\"caption\" *ngIf=\"caption || captionRef\"\n\t\t[ngClass]=\"{\n\t\t\thasErrors: getErrorToShow() && attachedControl.touched,\n\t\t\tpercentageSpacing: captionSpacing === 'percentages',\n\t\t\t'd30-70': spaceDistribution === '30-70',\n\t\t\t'd34-66': spaceDistribution === '34-66',\n\t\t\twithErrorRightOfCaption: getErrorLocation() === 'rightOfCaption'\n\t\t}\"\n\t>\n\t\t<div *ngIf=\"captionRef\" class=\"captionRefContainer\">\n\t\t\t<ng-container [ngTemplateOutlet]=\"captionRef\"></ng-container>\n\t\t\t<div *ngIf=\"isRequired()\">&nbsp;*</div>\n\t\t</div>\n\t\t<div *ngIf=\"!captionRef\">{{caption}}<span *ngIf=\"isRequired()\">&nbsp;*</span></div>\n\t\t<div class=\"rightOfCaptionError\">\n\t\t\t<ng-container *ngIf=\"direction === 'vertical' && getErrorLocation() === 'rightOfCaption'\" [ngTemplateOutlet]=\"errorRef\"></ng-container>\n\t\t</div>\n\t</div>\n\t<ng-container *ngIf=\"direction === 'vertical' && getErrorLocation() === 'belowCaption'\" [ngTemplateOutlet]=\"errorRef\"></ng-container>\n\t<div class=\"inputContainer\" [ngClass]=\"{\n\t\tpercentageSpacing: captionSpacing === 'percentages',\n\t\t'd30-70': spaceDistribution === '30-70',\n\t\t'd34-66': spaceDistribution === '34-66'\n\t}\">\n\t\t<ng-content></ng-content>\n\t</div>\n</div>\n", styles: [":host{display:block}.componentContainer{display:flex;align-items:center;min-height:42px}.componentContainer:not(.hasCaption){display:block}.componentContainer:not(.hasCaption) .inputContainer{margin-top:0}.componentContainer.reverseOrder{flex-direction:row-reverse;justify-content:flex-end}.componentContainer.vertical{display:block}.componentContainer.vertical .inputContainer{margin-top:.3125rem}.componentContainer.vertical .errorContainer{margin-left:0}.componentContainer.vertical .caption{padding-right:0}.captionRefContainer{display:flex}.caption{font-weight:700;flex:0 0 auto;padding-right:1.25rem;color:#515365}.caption.percentageSpacing{flex:40}.caption.percentageSpacing.d30-70{flex:30}.caption.percentageSpacing.d34-66{flex:34}.caption.hasErrors{color:#ff8000}.caption.withErrorRightOfCaption{display:flex;justify-content:space-between;gap:2.5rem}.caption.withErrorRightOfCaption .rightOfCaptionError{font-weight:400;overflow:hidden}.caption.withErrorRightOfCaption .rightOfCaptionError *{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.inputContainer{flex:1}.inputContainer.percentageSpacing{flex:60}.inputContainer.percentageSpacing.d30-70{flex:70}.inputContainer.percentageSpacing.d34-66{flex:66}.errorContainer{color:#ff8000}.errorContainer.hasCaption{margin-left:40%}.errorContainer.hasCaption.d30-70{margin-left:30%}.errorContainer.hasCaption.d34-66{margin-left:34%}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] }); }
556
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.1", type: FormElementComponent, selector: "klp-form-element", inputs: { caption: "caption", direction: "direction", captionSpacing: "captionSpacing", spaceDistribution: "spaceDistribution", swapInputAndCaption: "swapInputAndCaption", errorMessageAsTooltip: "errorMessageAsTooltip" }, viewQueries: [{ propertyName: "internalComponentRef", first: true, predicate: ["internalComponentRef"], descendants: true }], ngImport: i0, template: "<ng-template #errorRef>\n\t<div *ngIf=\"shouldShowErrorMessages() && getErrorToShow()\" class=\"errorContainer\" [ngClass]=\"{hasCaption: caption || captionRef, 'd30-70': spaceDistribution === '30-70', 'd34-66': spaceDistribution === '34-66'}\" [klpWithTooltip]=\"!errorMessageAsTooltip && getErrorLocation() === 'rightOfCaption'\">\n\t\t<div *ngIf=\"showDefaultError('min')\">{{substituteParameters(getErrorMessage(\"min\"), {min: attachedControl.errors.min.min})}}</div>\n\t\t<div *ngIf=\"showDefaultError('max')\">{{substituteParameters(getErrorMessage(\"max\"), {max: attachedControl.errors.max.max})}}</div>\n\t\t<div *ngIf=\"showDefaultError('required')\">{{getErrorMessage(\"required\")}}</div>\n\t\t<div *ngIf=\"showDefaultError('email')\">{{getErrorMessage(\"email\")}}</div>\n\t\t<div *ngIf=\"showDefaultError('minlength')\">{{substituteParameters(getErrorMessage(\"minLength\"), {minLength: attachedControl.errors.minlength.requiredLength})}}</div>\n\t\t<div *ngIf=\"showDefaultError('maxlength')\">{{substituteParameters(getErrorMessage(\"maxLength\"), {maxLength: attachedControl.errors.maxlength.requiredLength})}}</div>\n\t\t<div *ngIf=\"showDefaultError('pattern')\">{{getErrorMessage(\"pattern\")}}</div>\n\t\t<div *ngIf=\"showDefaultError('MatchPassword')\">{{getErrorMessage(\"matchPassword\")}}</div>\n\t\t<div *ngIf=\"showDefaultError('date')\">{{getErrorMessage(\"date\")}}</div>\n\t\t<div *ngIf=\"showDefaultError('message')\">{{attachedControl.errors.message.value}}</div>\n\t\t<div [ngTemplateOutlet]=\"getCustomErrorHandler(getErrorToShow())?.templateRef\"></div>\n\t</div>\n</ng-template>\n\n<ng-container *ngIf=\"direction === 'horizontal' && !errorMessageAsTooltip\" [ngTemplateOutlet]=\"errorRef\"></ng-container>\n\n<div class=\"componentContainer\" [ngClass]=\"{hasCaption: caption || captionRef, vertical: direction === 'vertical', reverseOrder: swapInputAndCaption}\" #internalComponentRef>\n\t<div class=\"caption\" *ngIf=\"caption || captionRef\"\n\t\t[ngClass]=\"{\n\t\t\thasErrors: getErrorToShow() && attachedControl.touched,\n\t\t\tpercentageSpacing: captionSpacing === 'percentages',\n\t\t\t'd30-70': spaceDistribution === '30-70',\n\t\t\t'd34-66': spaceDistribution === '34-66',\n\t\t\twithErrorRightOfCaption: getErrorLocation() === 'rightOfCaption'\n\t\t}\"\n\t>\n\t\t<div *ngIf=\"captionRef\" class=\"captionRefContainer\">\n\t\t\t<ng-container [ngTemplateOutlet]=\"captionRef\"></ng-container>\n\t\t\t<div *ngIf=\"isRequired()\">&nbsp;*</div>\n\t\t</div>\n\t\t<div *ngIf=\"!captionRef\" class=\"captionText\">{{caption}}<span *ngIf=\"isRequired()\">&nbsp;*</span></div>\n\t\t<div class=\"rightOfCaptionError\">\n\t\t\t<ng-container *ngIf=\"direction === 'vertical' && getErrorLocation() === 'rightOfCaption' && !errorMessageAsTooltip\" [ngTemplateOutlet]=\"errorRef\"></ng-container>\n\t\t</div>\n\t</div>\n\t<ng-container *ngIf=\"direction === 'vertical' && getErrorLocation() === 'belowCaption' && !errorMessageAsTooltip\" [ngTemplateOutlet]=\"errorRef\"></ng-container>\n\t<div class=\"inputContainer\" [ngClass]=\"{\n\t\tpercentageSpacing: captionSpacing === 'percentages',\n\t\t'd30-70': spaceDistribution === '30-70',\n\t\t'd34-66': spaceDistribution === '34-66'\n\t}\">\n\t\t<ng-container *ngIf=\"errorMessageAsTooltip && shouldShowErrorMessages() && getErrorToShow()\">\n\t\t\t<div class=\"errorTooltipTriangle\"></div>\n\t\t\t<div class=\"errorTooltipTriangleWhite\"></div>\n\t\t\t<div class=\"errorTooltip\">\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"errorRef\"></ng-container>\n\t\t\t</div>\n\t\t</ng-container>\n\t\t<ng-content></ng-content>\n\t</div>\n</div>\n", styles: [":host{display:block}.componentContainer{display:flex;align-items:center;min-height:42px}.componentContainer:not(.hasCaption){display:block}.componentContainer:not(.hasCaption) .inputContainer{margin-top:0}.componentContainer.reverseOrder{flex-direction:row-reverse;justify-content:flex-end}.componentContainer.vertical{display:block}.componentContainer.vertical .inputContainer{margin-top:.3125rem}.componentContainer.vertical .errorContainer{margin-left:0}.componentContainer.vertical .caption{padding-right:0}.captionRefContainer{display:flex}.caption{font-weight:700;flex:0 0 auto;padding-right:1.25rem;color:#515365}.caption.percentageSpacing{flex:40}.caption.percentageSpacing.d30-70{flex:30}.caption.percentageSpacing.d34-66{flex:34}.caption.hasErrors{color:#ff8000}.caption.hasErrors.withErrorRightOfCaption .rightOfCaptionError{display:block}.caption.withErrorRightOfCaption{display:flex;justify-content:space-between;gap:1rem}.caption.withErrorRightOfCaption .captionText{flex:1 2 auto;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.caption.withErrorRightOfCaption .rightOfCaptionError{display:none;font-weight:400;overflow:hidden;flex:1 1 auto;text-align:right}.caption.withErrorRightOfCaption .rightOfCaptionError ::ng-deep *{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.inputContainer{position:relative;flex:1}.inputContainer .errorTooltipTriangle{z-index:1;position:absolute;display:none;right:0;transform:translate(-50%,calc(-100% + .1rem));width:0px;height:0px;border-left:12px solid transparent;border-right:12px solid transparent;border-top:12px solid rgba(255,128,0,.125)}.inputContainer .errorTooltipTriangleWhite{z-index:3;position:absolute;display:none;right:0;transform:translate(-50%,calc(-100% + .1rem - 2px));width:0px;height:0px;border-left:12px solid transparent;border-right:12px solid transparent;border-top:12px solid white}.inputContainer .errorTooltip{position:absolute;top:-.6rem;right:0;display:none;z-index:2;color:#515365;transform:translateY(-100%);max-width:20rem;white-space:break-spaces;background-color:#fff;border:1px solid rgba(255,128,0,.125);box-shadow:#ff800020 2px 3px 10px;padding:.3rem .5rem;box-sizing:border-box;border-radius:3px}.inputContainer .errorTooltip .errorContainer{margin-left:initial}.inputContainer:hover .errorTooltip,.inputContainer:hover .errorTooltipTriangle,.inputContainer:hover .errorTooltipTriangleWhite{display:block}.inputContainer.percentageSpacing{flex:60}.inputContainer.percentageSpacing.d30-70{flex:70}.inputContainer.percentageSpacing.d34-66{flex:66}.errorContainer{color:#ff8000}.errorContainer.hasCaption{margin-left:40%}.errorContainer.hasCaption.d30-70{margin-left:30%}.errorContainer.hasCaption.d34-66{margin-left:34%}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: WithTooltipDirective, selector: "[klpWithTooltip]", inputs: ["klpWithTooltip"] }] }); }
453
557
  }
454
558
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: FormElementComponent, decorators: [{
455
559
  type: Component,
456
- args: [{ selector: 'klp-form-element', template: "<ng-template #errorRef>\n\t<div *ngIf=\"shouldShowErrorMessages() && getErrorToShow()\" class=\"errorContainer\" [ngClass]=\"{hasCaption: caption || captionRef, 'd30-70': spaceDistribution === '30-70', 'd34-66': spaceDistribution === '34-66'}\">\n\t\t<div *ngIf=\"showDefaultError('min')\">{{substituteParameters(getErrorMessage(\"min\"), {min: attachedControl.errors.min.min})}}</div>\n\t\t<div *ngIf=\"showDefaultError('max')\">{{substituteParameters(getErrorMessage(\"max\"), {max: attachedControl.errors.max.max})}}</div>\n\t\t<div *ngIf=\"showDefaultError('required')\">{{getErrorMessage(\"required\")}}</div>\n\t\t<div *ngIf=\"showDefaultError('email')\">{{getErrorMessage(\"email\")}}</div>\n\t\t<div *ngIf=\"showDefaultError('minlength')\">{{substituteParameters(getErrorMessage(\"minLength\"), {minLength: attachedControl.errors.minlength.requiredLength})}}</div>\n\t\t<div *ngIf=\"showDefaultError('maxlength')\">{{substituteParameters(getErrorMessage(\"maxLength\"), {maxLength: attachedControl.errors.maxlength.requiredLength})}}</div>\n\t\t<div *ngIf=\"showDefaultError('pattern')\">{{getErrorMessage(\"pattern\")}}</div>\n\t\t<div *ngIf=\"showDefaultError('MatchPassword')\">{{getErrorMessage(\"matchPassword\")}}</div>\n\t\t<div *ngIf=\"showDefaultError('date')\">{{getErrorMessage(\"date\")}}</div>\n\t\t<div *ngIf=\"showDefaultError('message')\">{{attachedControl.errors.message.value}}</div>\n\t\t<div [ngTemplateOutlet]=\"getCustomErrorHandler(getErrorToShow())?.templateRef\"></div>\n\t</div>\n</ng-template>\n\n<ng-container *ngIf=\"direction === 'horizontal'\" [ngTemplateOutlet]=\"errorRef\"></ng-container>\n\n<div class=\"componentContainer\" [ngClass]=\"{hasCaption: caption || captionRef, vertical: direction === 'vertical', reverseOrder: swapInputAndCaption}\" #internalComponentRef>\n\t<div class=\"caption\" *ngIf=\"caption || captionRef\"\n\t\t[ngClass]=\"{\n\t\t\thasErrors: getErrorToShow() && attachedControl.touched,\n\t\t\tpercentageSpacing: captionSpacing === 'percentages',\n\t\t\t'd30-70': spaceDistribution === '30-70',\n\t\t\t'd34-66': spaceDistribution === '34-66',\n\t\t\twithErrorRightOfCaption: getErrorLocation() === 'rightOfCaption'\n\t\t}\"\n\t>\n\t\t<div *ngIf=\"captionRef\" class=\"captionRefContainer\">\n\t\t\t<ng-container [ngTemplateOutlet]=\"captionRef\"></ng-container>\n\t\t\t<div *ngIf=\"isRequired()\">&nbsp;*</div>\n\t\t</div>\n\t\t<div *ngIf=\"!captionRef\">{{caption}}<span *ngIf=\"isRequired()\">&nbsp;*</span></div>\n\t\t<div class=\"rightOfCaptionError\">\n\t\t\t<ng-container *ngIf=\"direction === 'vertical' && getErrorLocation() === 'rightOfCaption'\" [ngTemplateOutlet]=\"errorRef\"></ng-container>\n\t\t</div>\n\t</div>\n\t<ng-container *ngIf=\"direction === 'vertical' && getErrorLocation() === 'belowCaption'\" [ngTemplateOutlet]=\"errorRef\"></ng-container>\n\t<div class=\"inputContainer\" [ngClass]=\"{\n\t\tpercentageSpacing: captionSpacing === 'percentages',\n\t\t'd30-70': spaceDistribution === '30-70',\n\t\t'd34-66': spaceDistribution === '34-66'\n\t}\">\n\t\t<ng-content></ng-content>\n\t</div>\n</div>\n", styles: [":host{display:block}.componentContainer{display:flex;align-items:center;min-height:42px}.componentContainer:not(.hasCaption){display:block}.componentContainer:not(.hasCaption) .inputContainer{margin-top:0}.componentContainer.reverseOrder{flex-direction:row-reverse;justify-content:flex-end}.componentContainer.vertical{display:block}.componentContainer.vertical .inputContainer{margin-top:.3125rem}.componentContainer.vertical .errorContainer{margin-left:0}.componentContainer.vertical .caption{padding-right:0}.captionRefContainer{display:flex}.caption{font-weight:700;flex:0 0 auto;padding-right:1.25rem;color:#515365}.caption.percentageSpacing{flex:40}.caption.percentageSpacing.d30-70{flex:30}.caption.percentageSpacing.d34-66{flex:34}.caption.hasErrors{color:#ff8000}.caption.withErrorRightOfCaption{display:flex;justify-content:space-between;gap:2.5rem}.caption.withErrorRightOfCaption .rightOfCaptionError{font-weight:400;overflow:hidden}.caption.withErrorRightOfCaption .rightOfCaptionError *{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.inputContainer{flex:1}.inputContainer.percentageSpacing{flex:60}.inputContainer.percentageSpacing.d30-70{flex:70}.inputContainer.percentageSpacing.d34-66{flex:66}.errorContainer{color:#ff8000}.errorContainer.hasCaption{margin-left:40%}.errorContainer.hasCaption.d30-70{margin-left:30%}.errorContainer.hasCaption.d34-66{margin-left:34%}\n"] }]
560
+ args: [{ selector: 'klp-form-element', template: "<ng-template #errorRef>\n\t<div *ngIf=\"shouldShowErrorMessages() && getErrorToShow()\" class=\"errorContainer\" [ngClass]=\"{hasCaption: caption || captionRef, 'd30-70': spaceDistribution === '30-70', 'd34-66': spaceDistribution === '34-66'}\" [klpWithTooltip]=\"!errorMessageAsTooltip && getErrorLocation() === 'rightOfCaption'\">\n\t\t<div *ngIf=\"showDefaultError('min')\">{{substituteParameters(getErrorMessage(\"min\"), {min: attachedControl.errors.min.min})}}</div>\n\t\t<div *ngIf=\"showDefaultError('max')\">{{substituteParameters(getErrorMessage(\"max\"), {max: attachedControl.errors.max.max})}}</div>\n\t\t<div *ngIf=\"showDefaultError('required')\">{{getErrorMessage(\"required\")}}</div>\n\t\t<div *ngIf=\"showDefaultError('email')\">{{getErrorMessage(\"email\")}}</div>\n\t\t<div *ngIf=\"showDefaultError('minlength')\">{{substituteParameters(getErrorMessage(\"minLength\"), {minLength: attachedControl.errors.minlength.requiredLength})}}</div>\n\t\t<div *ngIf=\"showDefaultError('maxlength')\">{{substituteParameters(getErrorMessage(\"maxLength\"), {maxLength: attachedControl.errors.maxlength.requiredLength})}}</div>\n\t\t<div *ngIf=\"showDefaultError('pattern')\">{{getErrorMessage(\"pattern\")}}</div>\n\t\t<div *ngIf=\"showDefaultError('MatchPassword')\">{{getErrorMessage(\"matchPassword\")}}</div>\n\t\t<div *ngIf=\"showDefaultError('date')\">{{getErrorMessage(\"date\")}}</div>\n\t\t<div *ngIf=\"showDefaultError('message')\">{{attachedControl.errors.message.value}}</div>\n\t\t<div [ngTemplateOutlet]=\"getCustomErrorHandler(getErrorToShow())?.templateRef\"></div>\n\t</div>\n</ng-template>\n\n<ng-container *ngIf=\"direction === 'horizontal' && !errorMessageAsTooltip\" [ngTemplateOutlet]=\"errorRef\"></ng-container>\n\n<div class=\"componentContainer\" [ngClass]=\"{hasCaption: caption || captionRef, vertical: direction === 'vertical', reverseOrder: swapInputAndCaption}\" #internalComponentRef>\n\t<div class=\"caption\" *ngIf=\"caption || captionRef\"\n\t\t[ngClass]=\"{\n\t\t\thasErrors: getErrorToShow() && attachedControl.touched,\n\t\t\tpercentageSpacing: captionSpacing === 'percentages',\n\t\t\t'd30-70': spaceDistribution === '30-70',\n\t\t\t'd34-66': spaceDistribution === '34-66',\n\t\t\twithErrorRightOfCaption: getErrorLocation() === 'rightOfCaption'\n\t\t}\"\n\t>\n\t\t<div *ngIf=\"captionRef\" class=\"captionRefContainer\">\n\t\t\t<ng-container [ngTemplateOutlet]=\"captionRef\"></ng-container>\n\t\t\t<div *ngIf=\"isRequired()\">&nbsp;*</div>\n\t\t</div>\n\t\t<div *ngIf=\"!captionRef\" class=\"captionText\">{{caption}}<span *ngIf=\"isRequired()\">&nbsp;*</span></div>\n\t\t<div class=\"rightOfCaptionError\">\n\t\t\t<ng-container *ngIf=\"direction === 'vertical' && getErrorLocation() === 'rightOfCaption' && !errorMessageAsTooltip\" [ngTemplateOutlet]=\"errorRef\"></ng-container>\n\t\t</div>\n\t</div>\n\t<ng-container *ngIf=\"direction === 'vertical' && getErrorLocation() === 'belowCaption' && !errorMessageAsTooltip\" [ngTemplateOutlet]=\"errorRef\"></ng-container>\n\t<div class=\"inputContainer\" [ngClass]=\"{\n\t\tpercentageSpacing: captionSpacing === 'percentages',\n\t\t'd30-70': spaceDistribution === '30-70',\n\t\t'd34-66': spaceDistribution === '34-66'\n\t}\">\n\t\t<ng-container *ngIf=\"errorMessageAsTooltip && shouldShowErrorMessages() && getErrorToShow()\">\n\t\t\t<div class=\"errorTooltipTriangle\"></div>\n\t\t\t<div class=\"errorTooltipTriangleWhite\"></div>\n\t\t\t<div class=\"errorTooltip\">\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"errorRef\"></ng-container>\n\t\t\t</div>\n\t\t</ng-container>\n\t\t<ng-content></ng-content>\n\t</div>\n</div>\n", styles: [":host{display:block}.componentContainer{display:flex;align-items:center;min-height:42px}.componentContainer:not(.hasCaption){display:block}.componentContainer:not(.hasCaption) .inputContainer{margin-top:0}.componentContainer.reverseOrder{flex-direction:row-reverse;justify-content:flex-end}.componentContainer.vertical{display:block}.componentContainer.vertical .inputContainer{margin-top:.3125rem}.componentContainer.vertical .errorContainer{margin-left:0}.componentContainer.vertical .caption{padding-right:0}.captionRefContainer{display:flex}.caption{font-weight:700;flex:0 0 auto;padding-right:1.25rem;color:#515365}.caption.percentageSpacing{flex:40}.caption.percentageSpacing.d30-70{flex:30}.caption.percentageSpacing.d34-66{flex:34}.caption.hasErrors{color:#ff8000}.caption.hasErrors.withErrorRightOfCaption .rightOfCaptionError{display:block}.caption.withErrorRightOfCaption{display:flex;justify-content:space-between;gap:1rem}.caption.withErrorRightOfCaption .captionText{flex:1 2 auto;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.caption.withErrorRightOfCaption .rightOfCaptionError{display:none;font-weight:400;overflow:hidden;flex:1 1 auto;text-align:right}.caption.withErrorRightOfCaption .rightOfCaptionError ::ng-deep *{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.inputContainer{position:relative;flex:1}.inputContainer .errorTooltipTriangle{z-index:1;position:absolute;display:none;right:0;transform:translate(-50%,calc(-100% + .1rem));width:0px;height:0px;border-left:12px solid transparent;border-right:12px solid transparent;border-top:12px solid rgba(255,128,0,.125)}.inputContainer .errorTooltipTriangleWhite{z-index:3;position:absolute;display:none;right:0;transform:translate(-50%,calc(-100% + .1rem - 2px));width:0px;height:0px;border-left:12px solid transparent;border-right:12px solid transparent;border-top:12px solid white}.inputContainer .errorTooltip{position:absolute;top:-.6rem;right:0;display:none;z-index:2;color:#515365;transform:translateY(-100%);max-width:20rem;white-space:break-spaces;background-color:#fff;border:1px solid rgba(255,128,0,.125);box-shadow:#ff800020 2px 3px 10px;padding:.3rem .5rem;box-sizing:border-box;border-radius:3px}.inputContainer .errorTooltip .errorContainer{margin-left:initial}.inputContainer:hover .errorTooltip,.inputContainer:hover .errorTooltipTriangle,.inputContainer:hover .errorTooltipTriangleWhite{display:block}.inputContainer.percentageSpacing{flex:60}.inputContainer.percentageSpacing.d30-70{flex:70}.inputContainer.percentageSpacing.d34-66{flex:66}.errorContainer{color:#ff8000}.errorContainer.hasCaption{margin-left:40%}.errorContainer.hasCaption.d30-70{margin-left:30%}.errorContainer.hasCaption.d34-66{margin-left:34%}\n"] }]
457
561
  }], ctorParameters: function () { return [{ type: FormComponent, decorators: [{
458
562
  type: Optional
459
563
  }] }, { type: undefined, decorators: [{
@@ -471,6 +575,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.1", ngImpor
471
575
  type: Input
472
576
  }], swapInputAndCaption: [{
473
577
  type: Input
578
+ }], errorMessageAsTooltip: [{
579
+ type: Input
474
580
  }], internalComponentRef: [{
475
581
  type: ViewChild,
476
582
  args: ['internalComponentRef']
@@ -496,6 +602,7 @@ class ValueAccessorBase {
496
602
  // we support both providing just the formControlName and the full formControl
497
603
  this.formControlName = null;
498
604
  this.formControl = null;
605
+ this.inErrorState = false;
499
606
  this.onTouch = new EventEmitter();
500
607
  this.focus = () => {
501
608
  if (isValueSet(this.nativeInputRef?.nativeElement)) {
@@ -525,6 +632,9 @@ class ValueAccessorBase {
525
632
  }
526
633
  }
527
634
  isInErrorState() {
635
+ if (this.inErrorState) {
636
+ return true;
637
+ }
528
638
  return this.attachedFormControl && this.attachedFormControl.status === 'INVALID' && this.attachedFormControl.touched;
529
639
  }
530
640
  ngOnDestroy() {
@@ -585,7 +695,7 @@ class ValueAccessorBase {
585
695
  return false;
586
696
  }
587
697
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: ValueAccessorBase, deps: [{ token: FormElementComponent, host: true, optional: true }, { token: i2.ControlContainer, host: true, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
588
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.1", type: ValueAccessorBase, selector: "ng-component", inputs: { disabled: "disabled", innerValueChangeInterceptor: "innerValueChangeInterceptor", formControlName: "formControlName", formControl: "formControl" }, outputs: { onTouch: "onTouch" }, viewQueries: [{ propertyName: "nativeInputRef", first: true, predicate: ["nativeInputRef"], descendants: true }], ngImport: i0, template: '', isInline: true }); }
698
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.1", type: ValueAccessorBase, selector: "ng-component", inputs: { disabled: "disabled", innerValueChangeInterceptor: "innerValueChangeInterceptor", formControlName: "formControlName", formControl: "formControl", inErrorState: "inErrorState" }, outputs: { onTouch: "onTouch" }, viewQueries: [{ propertyName: "nativeInputRef", first: true, predicate: ["nativeInputRef"], descendants: true }], ngImport: i0, template: '', isInline: true }); }
589
699
  }
590
700
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: ValueAccessorBase, decorators: [{
591
701
  type: Component,
@@ -609,6 +719,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.1", ngImpor
609
719
  type: Input
610
720
  }], formControl: [{
611
721
  type: Input
722
+ }], inErrorState: [{
723
+ type: Input
612
724
  }], onTouch: [{
613
725
  type: Output
614
726
  }], nativeInputRef: [{
@@ -1152,7 +1264,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.1", ngImpor
1152
1264
  class FormErrorComponent {
1153
1265
  constructor(parent) {
1154
1266
  this.parent = parent;
1155
- this.showErrorValueAsMessage = false;
1156
1267
  this.showError = false;
1157
1268
  }
1158
1269
  ngOnInit() {
@@ -1172,89 +1283,93 @@ class FormErrorComponent {
1172
1283
  return this.parent.getAttachedControl().errors[this.error];
1173
1284
  }
1174
1285
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: FormErrorComponent, deps: [{ token: FormElementComponent, host: true, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
1175
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.1", type: FormErrorComponent, selector: "klp-form-error", inputs: { error: "error", showErrorValueAsMessage: "showErrorValueAsMessage" }, viewQueries: [{ propertyName: "contentRef", first: true, predicate: ["contentRef"], descendants: true }], ngImport: i0, template: "<ng-template #contentRef>\n\t<ng-content *ngIf=\"!showErrorValueAsMessage\"></ng-content>\n\t<div *ngIf=\"showErrorValueAsMessage\">{{getErrorValueMessage()}}</div>\n</ng-template>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
1286
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.1", type: FormErrorComponent, selector: "klp-form-error", inputs: { error: "error" }, viewQueries: [{ propertyName: "contentRef", first: true, predicate: ["contentRef"], descendants: true }], ngImport: i0, template: "<ng-template #contentRef>\n\t<ng-content *ngIf=\"error !== 'async'\"></ng-content>\n\t<div *ngIf=\"error === 'async'\">{{getErrorValueMessage()}}</div>\n</ng-template>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
1176
1287
  }
1177
1288
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: FormErrorComponent, decorators: [{
1178
1289
  type: Component,
1179
- args: [{ selector: 'klp-form-error', template: "<ng-template #contentRef>\n\t<ng-content *ngIf=\"!showErrorValueAsMessage\"></ng-content>\n\t<div *ngIf=\"showErrorValueAsMessage\">{{getErrorValueMessage()}}</div>\n</ng-template>\n", styles: [":host{display:block}\n"] }]
1290
+ args: [{ selector: 'klp-form-error', template: "<ng-template #contentRef>\n\t<ng-content *ngIf=\"error !== 'async'\"></ng-content>\n\t<div *ngIf=\"error === 'async'\">{{getErrorValueMessage()}}</div>\n</ng-template>\n", styles: [":host{display:block}\n"] }]
1180
1291
  }], ctorParameters: function () { return [{ type: FormElementComponent, decorators: [{
1181
1292
  type: Host
1182
1293
  }, {
1183
1294
  type: Optional
1184
1295
  }] }]; }, propDecorators: { error: [{
1185
1296
  type: Input
1186
- }], showErrorValueAsMessage: [{
1187
- type: Input
1188
1297
  }], contentRef: [{
1189
1298
  type: ViewChild,
1190
1299
  args: ['contentRef']
1191
1300
  }] } });
1192
1301
 
1193
- class FormSubmitButtonComponent {
1194
- get _() {
1195
- return this.fullWidth;
1302
+ class FormValidationError extends Error {
1303
+ constructor(path, message) {
1304
+ super(message);
1305
+ this.name = 'FormValidationError';
1306
+ this.path = path;
1307
+ }
1308
+ }
1309
+ const KLP_FORM_ERROR_HANDLER = new InjectionToken('KLP_FORM_ERROR_HANDLER');
1310
+ const DefaultErrorHandler = (error) => {
1311
+ if (Array.isArray(error) && isArrayOf(error, FormValidationError)) {
1312
+ // If the error is an array of FormValidationErrors, then pass it along.
1313
+ return error;
1196
1314
  }
1197
- constructor(parentForm) {
1198
- this.parentForm = parentForm;
1315
+ else if (error instanceof FormValidationError) {
1316
+ // If the error is a FormValidationError, then wrap it and pass it on.
1317
+ return [error];
1318
+ }
1319
+ throw error;
1320
+ };
1321
+
1322
+ class FormSubmitButtonComponent {
1323
+ constructor() {
1324
+ this.parentForm = inject(FormComponent, { optional: true });
1325
+ this.handleError = inject(KLP_FORM_ERROR_HANDLER, { optional: true }) ?? DefaultErrorHandler;
1199
1326
  this.isLoading = false;
1200
1327
  this.fullWidth = false;
1201
1328
  this.variant = 'greenFilled';
1202
1329
  this.before = () => Promise.resolve();
1203
1330
  this.after = () => Promise.resolve();
1331
+ this.setValidationError = (e) => {
1332
+ this.parentForm.formGroup.get(e.path)?.setErrors({ message: { value: e.message } });
1333
+ };
1204
1334
  }
1205
1335
  async submitForm() {
1336
+ await this.before().catch(() => null);
1206
1337
  try {
1207
- await this.before();
1338
+ const [renderedAndEnabledValues, renderedValues] = await this.parentForm.trySubmit();
1339
+ this.isLoading = true;
1340
+ await this.submitCallback(renderedAndEnabledValues, renderedValues)
1341
+ .finally(() => this.isLoading = false);
1208
1342
  }
1209
1343
  catch (e) {
1210
- return;
1211
- }
1212
- this.parentForm
1213
- .trySubmit()
1214
- .then(([renderedAndEnabledValues, renderedValues]) => {
1215
- this.isLoading = true;
1216
- const submitCallbackResult = this.submitCallback(renderedAndEnabledValues, renderedValues);
1217
- if (isNullOrUndefined(submitCallbackResult)) {
1218
- throw new Error('No promise is returned in your submit function.');
1219
- }
1220
- return submitCallbackResult.then(() => (this.isLoading = false)).catch((e) => {
1221
- this.isLoading = false;
1222
- throw e;
1223
- });
1224
- })
1225
- .catch((e) => {
1226
1344
  if (e === invalidFieldsSymbol) {
1227
1345
  return; // swallow the error, the framework will scroll to the field that needs attention
1228
1346
  }
1229
- throw e;
1230
- });
1347
+ this.handleError(e).forEach(this.setValidationError);
1348
+ return;
1349
+ }
1231
1350
  await this.after();
1232
1351
  }
1233
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: FormSubmitButtonComponent, deps: [{ token: FormComponent, host: true, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
1234
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.1", type: FormSubmitButtonComponent, selector: "klp-form-submit-button", inputs: { isLoading: "isLoading", fullWidth: "fullWidth", variant: "variant", before: "before", after: "after", submitCallback: "submitCallback" }, host: { properties: { "class._fullWidth": "this._" } }, ngImport: i0, template: "<klp-form-button\n\t\t[variant]=\"variant\"\n\t\t(click)=\"submitForm()\"\n\t\t[disabled]=\"isLoading\"\n\t\t[isLoading]=\"isLoading\"\n\t\t[fullWidth]=\"fullWidth\"\n\t\ttype=\"submit\"\n\t\t[ngClass]=\"fullWidth ? 'fullWidth' : ''\"\n\t>\n\t<ng-content></ng-content>\n</klp-form-button>\n", styles: [":host{display:inline-block}:host._fullWidth{display:block}.fullWidth{width:100%}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ButtonComponent, selector: "klp-form-button", inputs: ["variant", "size", "fullWidth", "hasBorder", "disabled", "isLoading", "type", "clickCallback"] }] }); }
1352
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: FormSubmitButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1353
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.1", type: FormSubmitButtonComponent, selector: "klp-form-submit-button", inputs: { isLoading: "isLoading", fullWidth: "fullWidth", variant: "variant", submitCallback: "submitCallback", before: "before", after: "after" }, host: { properties: { "class._fullWidth": "this.fullWidth" } }, ngImport: i0, template: "<klp-form-button\n\t\t[variant]=\"variant\"\n\t\t(click)=\"submitForm()\"\n\t\t[disabled]=\"isLoading\"\n\t\t[isLoading]=\"isLoading\"\n\t\t[fullWidth]=\"fullWidth\"\n\t\ttype=\"submit\"\n\t\t[ngClass]=\"fullWidth ? 'fullWidth' : ''\"\n\t>\n\t<ng-content></ng-content>\n</klp-form-button>\n", styles: [":host{display:inline-block}:host._fullWidth{display:block}.fullWidth{width:100%}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ButtonComponent, selector: "klp-form-button", inputs: ["variant", "size", "fullWidth", "hasBorder", "disabled", "isLoading", "type", "clickCallback"] }] }); }
1235
1354
  }
1236
1355
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: FormSubmitButtonComponent, decorators: [{
1237
1356
  type: Component,
1238
1357
  args: [{ selector: 'klp-form-submit-button', template: "<klp-form-button\n\t\t[variant]=\"variant\"\n\t\t(click)=\"submitForm()\"\n\t\t[disabled]=\"isLoading\"\n\t\t[isLoading]=\"isLoading\"\n\t\t[fullWidth]=\"fullWidth\"\n\t\ttype=\"submit\"\n\t\t[ngClass]=\"fullWidth ? 'fullWidth' : ''\"\n\t>\n\t<ng-content></ng-content>\n</klp-form-button>\n", styles: [":host{display:inline-block}:host._fullWidth{display:block}.fullWidth{width:100%}\n"] }]
1239
- }], ctorParameters: function () { return [{ type: FormComponent, decorators: [{
1240
- type: Host
1241
- }, {
1242
- type: Optional
1243
- }] }]; }, propDecorators: { isLoading: [{
1358
+ }], propDecorators: { isLoading: [{
1244
1359
  type: Input
1245
1360
  }], fullWidth: [{
1246
1361
  type: Input
1362
+ }, {
1363
+ type: HostBinding,
1364
+ args: ['class._fullWidth']
1247
1365
  }], variant: [{
1248
1366
  type: Input
1367
+ }], submitCallback: [{
1368
+ type: Input
1249
1369
  }], before: [{
1250
1370
  type: Input
1251
1371
  }], after: [{
1252
1372
  type: Input
1253
- }], submitCallback: [{
1254
- type: Input
1255
- }], _: [{
1256
- type: HostBinding,
1257
- args: ['class._fullWidth']
1258
1373
  }] } });
1259
1374
 
1260
1375
  class MultipleValueAccessorBase extends ValueAccessorBase {
@@ -2021,7 +2136,8 @@ class NgxEnhancyFormsModule {
2021
2136
  FormComponent,
2022
2137
  SubFormDirective,
2023
2138
  HourMinuteInputComponent,
2024
- RadioComponent], imports: [CommonModule,
2139
+ RadioComponent,
2140
+ WithTooltipDirective], imports: [CommonModule,
2025
2141
  FormsModule,
2026
2142
  NgSelectModule,
2027
2143
  SortablejsModule,
@@ -2050,7 +2166,8 @@ class NgxEnhancyFormsModule {
2050
2166
  FormComponent,
2051
2167
  SubFormDirective,
2052
2168
  HourMinuteInputComponent,
2053
- RadioComponent] }); }
2169
+ RadioComponent,
2170
+ WithTooltipDirective] }); }
2054
2171
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: NgxEnhancyFormsModule, imports: [CommonModule,
2055
2172
  FormsModule,
2056
2173
  NgSelectModule,
@@ -2094,6 +2211,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.1", ngImpor
2094
2211
  SubFormDirective,
2095
2212
  HourMinuteInputComponent,
2096
2213
  RadioComponent,
2214
+ WithTooltipDirective,
2097
2215
  ],
2098
2216
  exports: [
2099
2217
  ValueAccessorBase,
@@ -2122,6 +2240,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.1", ngImpor
2122
2240
  SubFormDirective,
2123
2241
  HourMinuteInputComponent,
2124
2242
  RadioComponent,
2243
+ WithTooltipDirective,
2125
2244
  ],
2126
2245
  }]
2127
2246
  }] });
@@ -2134,5 +2253,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.1", ngImpor
2134
2253
  * Generated bundle index. Do not edit.
2135
2254
  */
2136
2255
 
2137
- export { ButtonComponent, CheckboxComponent, DATE_PICKER_LOCALE, DATE_PICKER_TRANSLATIONS, DATE_TIME_PICKER_TRANSLATIONS, DEFAULT_ERROR_MESSAGES, DatePickerComponent, DateTimePickerComponent, EmailInputComponent, FORM_ERROR_MESSAGES, FileInputComponent, FormCaptionComponent, FormComponent, FormElementComponent, FormErrorComponent, FormSubmitButtonComponent, HourMinuteInputComponent, KLP_DATE_FORMATS, KlpSelectOptionTemplateDirective, LoadingIndicatorComponent, MultipleValueAccessorBase, NgxEnhancyFormsModule, NumberInputComponent, Orientation, PasswordFieldComponent, RadioComponent, SELECT_TRANSLATIONS, SelectComponent, SelectFooterComponent, SortableGroupedItemsComponent, SortableItemsComponent, SubFormDirective, TextInputComponent, ToggleComponent, ValueAccessorBase, dateValidator, invalidDateKey, invalidFieldsSymbol, matDateFormatsFactory };
2256
+ export { ButtonComponent, CheckboxComponent, DATE_PICKER_LOCALE, DATE_PICKER_TRANSLATIONS, DATE_TIME_PICKER_TRANSLATIONS, DEFAULT_ERROR_MESSAGES, DatePickerComponent, DateTimePickerComponent, DefaultErrorHandler, EmailInputComponent, FORM_ERROR_MESSAGES, FileInputComponent, FormCaptionComponent, FormComponent, FormElementComponent, FormErrorComponent, FormSubmitButtonComponent, FormValidationError, HourMinuteInputComponent, KLP_DATE_FORMATS, KLP_FORM_ERROR_HANDLER, KlpSelectOptionTemplateDirective, LoadingIndicatorComponent, MultipleValueAccessorBase, NgxEnhancyFormsModule, NumberInputComponent, Orientation, PasswordFieldComponent, RadioComponent, SELECT_TRANSLATIONS, SelectComponent, SelectFooterComponent, SortableGroupedItemsComponent, SortableItemsComponent, SubFormDirective, TextInputComponent, ToggleComponent, ValueAccessorBase, WithTooltipDirective, dateValidator, invalidDateKey, invalidFieldsSymbol, matDateFormatsFactory };
2138
2257
  //# sourceMappingURL=klippa-ngx-enhancy-forms.mjs.map