@klippa/ngx-enhancy-forms 5.3.4 → 5.5.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.
@@ -55,6 +55,7 @@
55
55
  function FormComponent(parent, subFormPlaceholder) {
56
56
  this.parent = parent;
57
57
  this.subFormPlaceholder = subFormPlaceholder;
58
+ this.showErrorMessages = true;
58
59
  // we keep track of what form controls are actually rendered. Only those count when looking at form validation
59
60
  this.activeControls = [];
60
61
  }
@@ -206,6 +207,7 @@
206
207
  { type: SubFormDirective, decorators: [{ type: core.Optional }] }
207
208
  ]; };
208
209
  FormComponent.propDecorators = {
210
+ showErrorMessages: [{ type: core.Input }],
209
211
  formGroup: [{ type: core.Input }],
210
212
  patchValueInterceptor: [{ type: core.Input }]
211
213
  };
@@ -233,6 +235,10 @@
233
235
  this.errorMessages = DEFAULT_ERROR_MESSAGES;
234
236
  this.customErrorHandlers = [];
235
237
  }
238
+ FormElementComponent.prototype.shouldShowErrorMessages = function () {
239
+ var _a;
240
+ return ((_a = this.parent) === null || _a === void 0 ? void 0 : _a.showErrorMessages) !== false;
241
+ };
236
242
  FormElementComponent.prototype.substituteParameters = function (message, parameters) {
237
243
  return Object.keys(parameters).reduce(function (msg, key) {
238
244
  return msg.replace("%" + key + "%", parameters[key]);
@@ -302,8 +308,8 @@
302
308
  FormElementComponent.decorators = [
303
309
  { type: core.Component, args: [{
304
310
  selector: 'klp-form-element',
305
- template: "<ng-template #errorRef>\n\t<div *ngIf=\"getErrorToShow()\" class=\"errorContainer\">\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<ng-container *ngIf=\"direction === 'horizontal'\" [ngTemplateOutlet]=\"errorRef\"></ng-container>\n<div class=\"componentContainer\" [ngClass]=\"{vertical: direction === 'vertical', reverseOrder: swapInputAndCaption}\" #internalComponentRef>\n\t<div class=\"caption\" *ngIf=\"caption || captionRef\" [ngClass]=\"{ hasErrors: getErrorToShow() && attachedControl.touched, percentageSpacing: captionSpacing === 'percentages', 'd30-70': spaceDistribution === '30-70' }\">\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</div>\n\t<ng-container *ngIf=\"direction === 'vertical'\" [ngTemplateOutlet]=\"errorRef\"></ng-container>\n\t<div class=\"inputContainer\" [ngClass]=\"{ percentageSpacing: captionSpacing === 'percentages', 'd30-70': spaceDistribution === '30-70' }\">\n\t\t<ng-content></ng-content>\n\t</div>\n</div>\n",
306
- styles: [":host{display:block}.componentContainer{align-items:center;display:flex}.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}.captionRefContainer{display:flex}.caption{color:#515365;flex:0 0 auto;font-weight:700}.caption.percentageSpacing{flex:0 0 40%}.caption.percentageSpacing.d30-70{flex-basis:30%}.caption.hasErrors{color:#ff8000}.inputContainer{flex:1}.inputContainer.percentageSpacing{flex:0 0 60%}.inputContainer.percentageSpacing.d30-70{flex-basis:70%}.errorContainer{color:#ff8000;margin-left:40%}.errorContainer.d30-70{margin-left:30%}"]
311
+ template: "<ng-template #errorRef>\n\t<div *ngIf=\"shouldShowErrorMessages() && getErrorToShow()\" class=\"errorContainer\" [ngClass]=\"{hasCaption: caption || captionRef, 'd30-70': spaceDistribution === '30-70'}\">\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]=\"{vertical: direction === 'vertical', reverseOrder: swapInputAndCaption}\" #internalComponentRef>\n\t<div class=\"caption\" *ngIf=\"caption || captionRef\" [ngClass]=\"{ hasErrors: getErrorToShow() && attachedControl.touched, percentageSpacing: captionSpacing === 'percentages', 'd30-70': spaceDistribution === '30-70' }\">\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</div>\n\t<ng-container *ngIf=\"direction === 'vertical'\" [ngTemplateOutlet]=\"errorRef\"></ng-container>\n\t<div class=\"inputContainer\" [ngClass]=\"{ percentageSpacing: captionSpacing === 'percentages', 'd30-70': spaceDistribution === '30-70' }\">\n\t\t<ng-content></ng-content>\n\t</div>\n</div>\n",
312
+ styles: [":host{display:block}.componentContainer{align-items:center;display:flex}.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}.captionRefContainer{display:flex}.caption{color:#515365;flex:0 0 auto;font-weight:700}.caption.percentageSpacing{flex:0 0 40%}.caption.percentageSpacing.d30-70{flex-basis:30%}.caption.hasErrors{color:#ff8000}.inputContainer{flex:1}.inputContainer.percentageSpacing{flex:0 0 60%}.inputContainer.percentageSpacing.d30-70{flex-basis:70%}.errorContainer{color:#ff8000}.errorContainer.hasCaption{margin-left:40%}.errorContainer.hasCaption.d30-70{margin-left:30%}"]
307
313
  },] }
308
314
  ];
309
315
  FormElementComponent.ctorParameters = function () { return [
@@ -786,21 +792,23 @@
786
792
  var CheckboxComponent = /** @class */ (function (_super) {
787
793
  __extends(CheckboxComponent, _super);
788
794
  function CheckboxComponent() {
789
- return _super !== null && _super.apply(this, arguments) || this;
795
+ var _this = _super.apply(this, __spread(arguments)) || this;
796
+ _this.renderUndefinedAsIndeterminate = false;
797
+ return _this;
790
798
  }
791
799
  return CheckboxComponent;
792
800
  }(ValueAccessorBase));
793
801
  CheckboxComponent.decorators = [
794
802
  { type: core.Component, args: [{
795
803
  selector: 'klp-form-checkbox',
796
- template: "<label class=\"componentContainer\">\n\t<div class=\"checkboxContainer\">\n\t\t<input type=\"checkbox\" class=\"checkboxNative\"\n\t\t\t[(ngModel)]=\"innerValue\"\n\t\t\t(change)=\"setInnerValueAndNotify(innerValue); touch()\"\n\t\t\t[disabled]=\"disabled\"\n\t\t/>\n <div class=\"checkboxVisual\">\n <svg *ngIf=\"innerValue\" version=\"1.1\" viewBox=\"0 0 4.2333 4.2333\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"m0.17014 2.7065 1.3073 1.1798 2.5656-3.7404\" stroke=\"currentColor\" fill=\"none\" stroke-width=\".4646px\" />\n </svg>\n </div>\n\t</div>\n\t<div *ngIf=\"caption\" class=\"caption\">{{ caption }}</div>\n</label>\n",
804
+ template: "<label class=\"componentContainer\">\n\t<div class=\"checkboxContainer\">\n\t\t<input type=\"checkbox\" class=\"checkboxNative\"\n\t\t\t[(ngModel)]=\"innerValue\"\n\t\t\t(change)=\"setInnerValueAndNotify(innerValue); touch()\"\n\t\t\t[disabled]=\"disabled\"\n\t\t/>\n <div class=\"checkboxVisual\">\n <svg *ngIf=\"innerValue === true\" version=\"1.1\" viewBox=\"0 0 4.2333 4.2333\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"m0.17014 2.7065 1.3073 1.1798 2.5656-3.7404\" stroke=\"currentColor\" fill=\"none\" stroke-width=\".4646px\" />\n </svg>\n\t\t\t<svg *ngIf=\"renderUndefinedAsIndeterminate && innerValue === undefined\" version=\"1.1\" viewBox=\"0 0 4.2333 4.2333\" xmlns=\"http://www.w3.org/2000/svg\">\n\t\t\t\t<path d=\"m0.5 2.11665 3.2333 0\" stroke=\"currentColor\" fill=\"none\" stroke-width=\".4646px\" />\n\t\t\t</svg>\n </div>\n\t</div>\n\t<div *ngIf=\"caption\" class=\"caption\">{{ caption }}</div>\n</label>\n",
797
805
  providers: [{ provide: forms.NG_VALUE_ACCESSOR, useExisting: CheckboxComponent, multi: true }],
798
806
  styles: [":host{display:block}.componentContainer{display:flex;margin-bottom:0}.checkboxContainer{position:relative}.caption{color:#888da8;cursor:pointer;font-weight:700}.checkboxNative{left:0;opacity:0;position:absolute;top:0}.checkboxNative,.checkboxVisual{cursor:pointer;height:22px;width:22px}.checkboxVisual{background-color:#fff;border:2px solid #e6ecf5;border-radius:3px;color:#27bb5f;display:inline-block;font-size:15px;font-weight:400;line-height:19px;margin-right:10px;padding:.125rem;pointer-events:none;text-align:center;vertical-align:bottom}.checkboxNative[disabled]{cursor:not-allowed}.checkboxNative[disabled]+.checkboxVisual:before{color:#666}"]
799
807
  },] }
800
808
  ];
801
809
  CheckboxComponent.propDecorators = {
802
810
  caption: [{ type: core.Input }],
803
- disabled: [{ type: core.Input }]
811
+ renderUndefinedAsIndeterminate: [{ type: core.Input }]
804
812
  };
805
813
 
806
814
  var EmailInputComponent = /** @class */ (function (_super) {
@@ -853,7 +861,7 @@
853
861
  NumberInputComponent.decorators = [
854
862
  { type: core.Component, args: [{
855
863
  selector: 'klp-form-number-input',
856
- template: "<input\n\ttype=\"number\"\n\tclass=\"form-control\"\n\t[(ngModel)]=\"innerValue\"\n\t(input)=\"setInnerValueAndNotify($event.target.value)\"\n\t[placeholder]=\"placeholder ? placeholder : ''\"\n/>\n",
864
+ template: "<input\n\ttype=\"number\"\n\tclass=\"form-control\"\n\t[(ngModel)]=\"innerValue\"\n\t(input)=\"setInnerValueAndNotify($event.target.value)\"\n\t[placeholder]=\"placeholder ? placeholder : ''\"\n\t[ngClass]=\"{showErrors: isInErrorState()}\"\n/>\n",
857
865
  providers: [{ provide: forms.NG_VALUE_ACCESSOR, useExisting: NumberInputComponent, multi: true }],
858
866
  styles: [":host,input{display:block}input{-moz-transition:all .2s ease-in;-ms-transition:all .2s ease-in;-o-transition:all .2s ease-in;-webkit-transition:all .2s ease-in;border:1px solid #e6ecf5;border-radius:2px;box-shadow:none;color:#888da8;font-size:14px;height:42px;outline:none;padding:.375rem .625rem;transition:all .2s ease-in;width:100%}input::-webkit-input-placeholder{color:#adadad}input:-moz-placeholder,input::-moz-placeholder{color:#adadad}input:-ms-input-placeholder{color:#adadad}input:focus{border-color:#3ed778;box-shadow:none;outline:0 none}input.input-sm{height:30px}input.input-lg{height:50px}input.error{background-color:#ffeff4;border-color:#ff3c7e}input.valid{background-color:#ebfaeb;border-color:#37c936;color:#278d26}.showErrors{border-color:#ff8000}"]
859
867
  },] }
@@ -1380,6 +1388,7 @@
1380
1388
  _this.clearable = false;
1381
1389
  _this.showTimeInput = true;
1382
1390
  _this.invalidTimeAsMidnight = false; // if the time is not valid, use 00:00 as the time
1391
+ _this.openPickerOnDate = null;
1383
1392
  _this.minDateStartOfDay = undefined;
1384
1393
  _this.maxDateEndOfDay = undefined;
1385
1394
  _this.selectedDates = [];
@@ -1555,6 +1564,9 @@
1555
1564
  this.selectedDates = value;
1556
1565
  this.determineMinAndMaxDates();
1557
1566
  this.valueForMaterialDatePicker = null;
1567
+ if (arrayIsSetAndFilled(value)) {
1568
+ this.openPickerOnDate = this.selectedDates[0];
1569
+ }
1558
1570
  }
1559
1571
  else {
1560
1572
  this.valueForMaterialDatePicker = value === invalidDateKey ? null : value;
@@ -1562,10 +1574,12 @@
1562
1574
  this.hours = String(value.getHours());
1563
1575
  this.minutes = String(value.getMinutes());
1564
1576
  this.formatTime();
1577
+ this.openPickerOnDate = value;
1565
1578
  }
1566
1579
  else {
1567
1580
  this.hours = '';
1568
1581
  this.minutes = '';
1582
+ this.openPickerOnDate = null;
1569
1583
  }
1570
1584
  }
1571
1585
  };
@@ -1642,7 +1656,7 @@
1642
1656
  DateTimePickerComponent.decorators = [
1643
1657
  { type: core.Component, args: [{
1644
1658
  selector: 'klp-form-date-time-picker',
1645
- template: "<div class=\"componentContainer\" [ngClass]=\"{showErrors: isInErrorState()}\">\n\t<div class=\"dateContainer\" [ngClass]=\"{noRightBorder: !showTimeInput && clearable && !disabled, disabled: disabled}\">\n\t\t<mat-form-field floatLabel=\"never\">\n\t\t\t<div *ngIf=\"multiple\" class=\"daysSelectedCaption\" (click)=\"picker.open()\" [ngClass]=\"{disabled: disabled}\">\n\t\t\t\t<ng-container *ngIf=\"selectedDates.length >= 2\">\n\t\t\t\t\t<span>{{getTranslation('daysSelected', selectedDates.length)}}</span>\n\t\t\t\t\t<span *ngIf=\"getSelectedMonths() === 1\">{{getTranslation('selectedInMonth', selectedDates[0])}}</span>\n\t\t\t\t</ng-container>\n\t\t\t\t<span *ngIf=\"selectedDates.length === 1\">{{getTranslation('selectedDate', selectedDates[0])}}</span>\n\t\t\t\t<span *ngIf=\"selectedDates.length === 0\" class=\"placeholderForMultipleSelection\">{{getTranslation('selectDays')}}</span>\n\t\t\t</div>\n\t\t\t<input\n\t\t\t\t#nativeInput\n\t\t\t\tmatInput\n\t\t\t\t[matDatepicker]=\"picker\"\n\t\t\t\t[matDatepickerFilter]=\"filterDates\"\n\t\t\t\t[(ngModel)]=\"valueForMaterialDatePicker\"\n\t\t\t\t(dateInput)=\"dateChanged($event)\"\n\t\t\t\t(input)=\"nativeValueChanged()\"\n\t\t\t\t[min]=\"minDateStartOfDay\"\n\t\t\t\t[max]=\"maxDateEndOfDay\"\n\t\t\t\t[placeholder]=\"getTranslation('placeholder')\"\n\t\t\t\t(click)=\"picker.open()\"\n\t\t\t\t(blur)=\"touchDate()\"\n\t\t\t\t[ngClass]=\"{inputForMultipleDays: multiple}\"\n\t\t\t>\n\t\t\t<mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n\t\t\t<mat-datepicker\n\t\t\t\t#picker\n\t\t\t\t[dateClass]=\"isSelected\"\n\t\t\t></mat-datepicker>\n\t\t</mat-form-field>\n\t</div>\n\t<div class=\"timeContainer\" *ngIf=\"showTimeInput\" [ngClass]=\"{disabled: disabled}\">\n\t\t<input maxlength=\"2\" placeholder=\"__\" [disabled]=\"disabled\" [(ngModel)]=\"hours\" (ngModelChange)=\"notifyNewDate()\" (blur)=\"formatTime(); touchHours()\">\n\t\t<div class=\"divider\">:</div>\n\t\t<input maxlength=\"2\" placeholder=\"__\" [disabled]=\"disabled\" [(ngModel)]=\"minutes\" (ngModelChange)=\"notifyNewDate()\" (blur)=\"formatTime(); touchMinutes()\">\n\t</div>\n\t<button *ngIf=\"clearable && !disabled\" class=\"clearButton\" (click)=\"resetToNull()\" [ngClass]=\"{withoutSpacing: !showTimeInput}\">\u00D7</button>\n</div>\n",
1659
+ template: "<div class=\"componentContainer\" [ngClass]=\"{showErrors: isInErrorState()}\">\n\t<div class=\"dateContainer\" [ngClass]=\"{noRightBorder: !showTimeInput && clearable && !disabled, disabled: disabled}\">\n\t\t<mat-form-field floatLabel=\"never\">\n\t\t\t<div *ngIf=\"multiple\" class=\"daysSelectedCaption\" (click)=\"picker.open()\" [ngClass]=\"{disabled: disabled}\">\n\t\t\t\t<ng-container *ngIf=\"selectedDates.length >= 2\">\n\t\t\t\t\t<span>{{getTranslation('daysSelected', selectedDates.length)}}</span>\n\t\t\t\t\t<span *ngIf=\"getSelectedMonths() === 1\">{{getTranslation('selectedInMonth', selectedDates[0])}}</span>\n\t\t\t\t</ng-container>\n\t\t\t\t<span *ngIf=\"selectedDates.length === 1\">{{getTranslation('selectedDate', selectedDates[0])}}</span>\n\t\t\t\t<span *ngIf=\"selectedDates.length === 0\" class=\"placeholderForMultipleSelection\">{{getTranslation('selectDays')}}</span>\n\t\t\t</div>\n\t\t\t<input\n\t\t\t\t#nativeInput\n\t\t\t\tmatInput\n\t\t\t\t[matDatepicker]=\"picker\"\n\t\t\t\t[matDatepickerFilter]=\"filterDates\"\n\t\t\t\t[(ngModel)]=\"valueForMaterialDatePicker\"\n\t\t\t\t(dateInput)=\"dateChanged($event)\"\n\t\t\t\t(input)=\"nativeValueChanged()\"\n\t\t\t\t[min]=\"minDateStartOfDay\"\n\t\t\t\t[max]=\"maxDateEndOfDay\"\n\t\t\t\t[placeholder]=\"getTranslation('placeholder')\"\n\t\t\t\t(click)=\"picker.open()\"\n\t\t\t\t(blur)=\"touchDate()\"\n\t\t\t\t[ngClass]=\"{inputForMultipleDays: multiple}\"\n\t\t\t>\n\t\t\t<mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n\t\t\t<mat-datepicker\n\t\t\t\t#picker\n\t\t\t\t[dateClass]=\"isSelected\"\n\t\t\t\t[startAt]=\"openPickerOnDate\"\n\t\t\t></mat-datepicker>\n\t\t</mat-form-field>\n\t</div>\n\t<div class=\"timeContainer\" *ngIf=\"showTimeInput\" [ngClass]=\"{disabled: disabled}\">\n\t\t<input maxlength=\"2\" placeholder=\"__\" [disabled]=\"disabled\" [(ngModel)]=\"hours\" (ngModelChange)=\"notifyNewDate()\" (blur)=\"formatTime(); touchHours()\">\n\t\t<div class=\"divider\">:</div>\n\t\t<input maxlength=\"2\" placeholder=\"__\" [disabled]=\"disabled\" [(ngModel)]=\"minutes\" (ngModelChange)=\"notifyNewDate()\" (blur)=\"formatTime(); touchMinutes()\">\n\t</div>\n\t<button *ngIf=\"clearable && !disabled\" class=\"clearButton\" (click)=\"resetToNull()\" [ngClass]=\"{withoutSpacing: !showTimeInput}\">\u00D7</button>\n</div>\n",
1646
1660
  providers: [
1647
1661
  { provide: forms.NG_VALUE_ACCESSOR, useExisting: DateTimePickerComponent, multi: true },
1648
1662
  {