@klippa/ngx-enhancy-forms 14.7.17 → 14.9.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.
@@ -1,5 +1,5 @@
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';
@@ -85,6 +85,9 @@ function splitArrayByCondition(value, condition) {
85
85
  return acc;
86
86
  }, [[]]);
87
87
  }
88
+ function isArrayOf(arr, kind) {
89
+ return arr.reduce((acc, val) => acc && val instanceof kind, true);
90
+ }
88
91
 
89
92
  function mergeArray(arrA, arrB) {
90
93
  const arr = new Array(Math.max(arrA.length, arrB.length));
@@ -421,11 +424,11 @@ class WithTooltipDirective {
421
424
  });
422
425
  el.nativeElement.addEventListener('mouseout', () => {
423
426
  try {
424
- el.nativeElement.removeChild(this.div);
427
+ // el.nativeElement.removeChild(this.div);
425
428
  }
426
429
  catch (ex) { }
427
430
  try {
428
- el.nativeElement.removeChild(this.triangle);
431
+ // el.nativeElement.removeChild(this.triangle);
429
432
  }
430
433
  catch (ex) { }
431
434
  });
@@ -462,6 +465,7 @@ class FormElementComponent {
462
465
  this.captionSpacing = 'percentages';
463
466
  this.spaceDistribution = '40-60';
464
467
  this.swapInputAndCaption = false;
468
+ this.errorMessageAsTooltip = false;
465
469
  this.errorMessages = DEFAULT_ERROR_MESSAGES;
466
470
  this.customErrorHandlers = [];
467
471
  }
@@ -533,10 +537,10 @@ class FormElementComponent {
533
537
  }
534
538
  }
535
539
  FormElementComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: FormElementComponent, deps: [{ token: FormComponent, optional: true }, { token: FORM_ERROR_MESSAGES, optional: true }], target: i0.ɵɵFactoryTarget.Component });
536
- FormElementComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.8", 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'}\" [klpWithTooltip]=\"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'\" [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'\" [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.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{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"] }, { kind: "directive", type: WithTooltipDirective, selector: "[klpWithTooltip]", inputs: ["klpWithTooltip"] }] });
540
+ FormElementComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.8", 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=\"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:.8rem solid transparent;border-right:.8rem solid transparent;border-top:.8rem solid rgba(255,128,0,.125)}.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{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"] }] });
537
541
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: FormElementComponent, decorators: [{
538
542
  type: Component,
539
- 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]=\"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'\" [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'\" [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.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{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"] }]
543
+ 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=\"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:.8rem solid transparent;border-right:.8rem solid transparent;border-top:.8rem solid rgba(255,128,0,.125)}.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{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"] }]
540
544
  }], ctorParameters: function () { return [{ type: FormComponent, decorators: [{
541
545
  type: Optional
542
546
  }] }, { type: undefined, decorators: [{
@@ -554,6 +558,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImpor
554
558
  type: Input
555
559
  }], swapInputAndCaption: [{
556
560
  type: Input
561
+ }], errorMessageAsTooltip: [{
562
+ type: Input
557
563
  }], internalComponentRef: [{
558
564
  type: ViewChild,
559
565
  args: ['internalComponentRef']
@@ -1260,71 +1266,77 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImpor
1260
1266
  args: ['contentRef']
1261
1267
  }] } });
1262
1268
 
1269
+ class FormValidationError extends Error {
1270
+ constructor(path, message) {
1271
+ super(message);
1272
+ this.name = 'FormValidationError';
1273
+ this.path = path;
1274
+ }
1275
+ }
1276
+ const KLP_FORM_ERROR_HANDLER = new InjectionToken('KLP_FORM_ERROR_HANDLER');
1277
+ const DefaultErrorHandler = (error) => {
1278
+ if (Array.isArray(error) && isArrayOf(error, FormValidationError)) {
1279
+ // If the error is an array of FormValidationErrors, then pass it along.
1280
+ return error;
1281
+ }
1282
+ else if (error instanceof FormValidationError) {
1283
+ // If the error is a FormValidationError, then wrap it and pass it on.
1284
+ return [error];
1285
+ }
1286
+ throw error;
1287
+ };
1288
+
1263
1289
  class FormSubmitButtonComponent {
1264
- constructor(parentForm) {
1265
- this.parentForm = parentForm;
1290
+ constructor() {
1291
+ this.parentForm = inject(FormComponent, { host: true, optional: true });
1292
+ this.handleError = inject(KLP_FORM_ERROR_HANDLER, { optional: true }) ?? DefaultErrorHandler;
1266
1293
  this.isLoading = false;
1267
1294
  this.fullWidth = false;
1268
1295
  this.variant = 'greenFilled';
1269
1296
  this.before = () => Promise.resolve();
1270
1297
  this.after = () => Promise.resolve();
1271
- }
1272
- get _() {
1273
- return this.fullWidth;
1298
+ this.setValidationError = (e) => {
1299
+ this.parentForm.formGroup.get(e.path)?.setErrors({ message: { value: e.message } });
1300
+ };
1274
1301
  }
1275
1302
  async submitForm() {
1303
+ await this.before().catch(() => null);
1276
1304
  try {
1277
- await this.before();
1305
+ const [renderedAndEnabledValues, renderedValues] = await this.parentForm.trySubmit();
1306
+ this.isLoading = true;
1307
+ await this.submitCallback(renderedAndEnabledValues, renderedValues)
1308
+ .finally(() => this.isLoading = false);
1278
1309
  }
1279
1310
  catch (e) {
1280
- return;
1281
- }
1282
- this.parentForm
1283
- .trySubmit()
1284
- .then(([renderedAndEnabledValues, renderedValues]) => {
1285
- this.isLoading = true;
1286
- const submitCallbackResult = this.submitCallback(renderedAndEnabledValues, renderedValues);
1287
- if (isNullOrUndefined(submitCallbackResult)) {
1288
- throw new Error('No promise is returned in your submit function.');
1289
- }
1290
- return submitCallbackResult.then(() => (this.isLoading = false)).catch((e) => {
1291
- this.isLoading = false;
1292
- throw e;
1293
- });
1294
- })
1295
- .catch((e) => {
1296
1311
  if (e === invalidFieldsSymbol) {
1297
1312
  return; // swallow the error, the framework will scroll to the field that needs attention
1298
1313
  }
1299
- throw e;
1300
- });
1314
+ this.handleError(e).forEach(this.setValidationError);
1315
+ return;
1316
+ }
1301
1317
  await this.after();
1302
1318
  }
1303
1319
  }
1304
- FormSubmitButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: FormSubmitButtonComponent, deps: [{ token: FormComponent, host: true, optional: true }], target: i0.ɵɵFactoryTarget.Component });
1305
- FormSubmitButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.8", 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"] }] });
1320
+ FormSubmitButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: FormSubmitButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1321
+ FormSubmitButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.8", 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"] }] });
1306
1322
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: FormSubmitButtonComponent, decorators: [{
1307
1323
  type: Component,
1308
1324
  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"] }]
1309
- }], ctorParameters: function () { return [{ type: FormComponent, decorators: [{
1310
- type: Host
1311
- }, {
1312
- type: Optional
1313
- }] }]; }, propDecorators: { isLoading: [{
1325
+ }], propDecorators: { isLoading: [{
1314
1326
  type: Input
1315
1327
  }], fullWidth: [{
1316
1328
  type: Input
1329
+ }, {
1330
+ type: HostBinding,
1331
+ args: ['class._fullWidth']
1317
1332
  }], variant: [{
1318
1333
  type: Input
1334
+ }], submitCallback: [{
1335
+ type: Input
1319
1336
  }], before: [{
1320
1337
  type: Input
1321
1338
  }], after: [{
1322
1339
  type: Input
1323
- }], submitCallback: [{
1324
- type: Input
1325
- }], _: [{
1326
- type: HostBinding,
1327
- args: ['class._fullWidth']
1328
1340
  }] } });
1329
1341
 
1330
1342
  class MultipleValueAccessorBase extends ValueAccessorBase {
@@ -2208,5 +2220,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImpor
2208
2220
  * Generated bundle index. Do not edit.
2209
2221
  */
2210
2222
 
2211
- 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, WithTooltipDirective, dateValidator, invalidDateKey, invalidFieldsSymbol, matDateFormatsFactory };
2223
+ 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 };
2212
2224
  //# sourceMappingURL=klippa-ngx-enhancy-forms.mjs.map