@sumaris-net/ngx-components 1.15.3 → 1.15.4

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.
@@ -4806,8 +4806,10 @@ class MatDate {
4806
4806
  this.formControl.setValidators(this.required ? [this.formControl.validator, Validators.required, SharedValidators.validDate] :
4807
4807
  [this.formControl.validator, SharedValidators.validDate]);
4808
4808
  }
4809
+ // Create the day control
4809
4810
  this.dayControl = this.formBuilder.control(null, () => this.formControl.errors);
4810
4811
  // Get patterns to display date
4812
+ this.updatePattern(this.translate.instant('COMMON.DATE_PATTERN'));
4811
4813
  this._subscription.add(this.translate.get('COMMON.DATE_PATTERN')
4812
4814
  .subscribe((pattern) => this.updatePattern(pattern)));
4813
4815
  this._subscription.add(this.dayControl.valueChanges
@@ -4829,14 +4831,15 @@ class MatDate {
4829
4831
  ngOnDestroy() {
4830
4832
  this._subscription.unsubscribe();
4831
4833
  }
4832
- writeValue(valueStr) {
4834
+ writeValue(value) {
4833
4835
  if (this._writing)
4834
4836
  return; // Skip
4835
4837
  this._writing = true;
4836
4838
  // DEBUG
4837
- // console.debug("[mat-date] writeValue() with:", valueStr);
4838
- const value = fromDateISOString(valueStr);
4839
- if (!value || !value.isValid()) {
4839
+ //console.debug("[mat-date] writeValue() with:", value);
4840
+ // Convert into date, and clone if necessary
4841
+ const date = isMoment(value) ? value.clone() : fromDateISOString(value);
4842
+ if (!date || !date.isValid()) {
4840
4843
  this.dayControl.patchValue(null, { emitEvent: false });
4841
4844
  if (this.formControl.value) {
4842
4845
  this.formControl.patchValue(null, { emitEvent: false });
@@ -4845,13 +4848,17 @@ class MatDate {
4845
4848
  }
4846
4849
  else {
4847
4850
  // Format day
4848
- // Move to the expected TZ (keeping local hour - e.g. midnight)
4849
- let day = value && this.timezone ? value.clone().tz(this.timezone) : value.clone();
4850
- // Reset hour
4851
+ let day = date && this.timezone
4852
+ // Move to the expected TZ (keeping local hour - e.g. midnight)
4853
+ ? date.tz(this.timezone)
4854
+ // Not TZ: important: do a clone
4855
+ : date;
4851
4856
  day = day.startOf('day');
4852
4857
  const dayStr = this.dateAdapter.format(day, this.dayPattern);
4853
- // Update control
4854
- this.dayControl.patchValue(dayStr, { emitEvent: false });
4858
+ if (this.dayControl.value !== dayStr) {
4859
+ // Update control
4860
+ this.dayControl.patchValue(dayStr, { emitEvent: false });
4861
+ }
4855
4862
  }
4856
4863
  this._writing = false;
4857
4864
  this.markForCheck();
@@ -4891,7 +4898,7 @@ class MatDate {
4891
4898
  }
4892
4899
  if (this.dayControl.value !== dateStr) {
4893
4900
  // DEBUG
4894
- console.debug("[mat-date] onDatePickerChange() new value:", dateStr);
4901
+ //console.debug("[mat-date] onDatePickerChange() new value:", dateStr);
4895
4902
  this.dayControl.setValue(dateStr, {
4896
4903
  emitEvent: true // Will call onFormChange
4897
4904
  });
@@ -4952,28 +4959,37 @@ class MatDate {
4952
4959
  this.markForCheck();
4953
4960
  }
4954
4961
  }
4955
- checkIfTouched() {
4962
+ checkIfTouched(opts) {
4956
4963
  if (this.dayControl.touched) {
4957
4964
  this._onTouchedCallback();
4958
- this.markForCheck();
4965
+ if (!opts || opts.emitEvent !== false) {
4966
+ this.markForCheck();
4967
+ }
4959
4968
  }
4960
4969
  }
4961
4970
  onFormChange(dayStr) {
4962
4971
  if (this._writing)
4963
4972
  return; // Skip if call by self
4964
4973
  this._writing = true;
4974
+ if (this.dayControl.invalid) {
4975
+ this.formControl.markAsPending({ onlySelf: true });
4976
+ this.formControl.setErrors(Object.assign(Object.assign({}, this.formControl.errors), this.dayControl.errors));
4977
+ this.formControl.markAsDirty();
4978
+ this._writing = false;
4979
+ return;
4980
+ }
4965
4981
  // Make to remove placeholder chars
4966
4982
  while (dayStr && dayStr.indexOf(this.placeholderChar) !== -1) {
4967
4983
  dayStr = dayStr.replace(this.placeholderChar, '');
4968
4984
  }
4969
4985
  // Parse day
4970
- let date = dayStr && this.dateAdapter.parse(dayStr, this.dayPattern);
4971
- // Move to the expected TZ (keeping local hour - e.g. midnight)
4972
- date = date && (this.timezone ? date.tz(this.timezone, true) : date);
4973
- date = date && date.startOf('day') // Reset hrou
4974
- .utc(); // Convert local date into utc (avoid TZ offset to be in the final string)
4975
- // Set model value
4976
- this.emitChange(date);
4986
+ let dayDate = dayStr && this.dateAdapter.parse(dayStr, this.dayPattern);
4987
+ // Move to the expected TZ, and keep the local hour (= midnight) to have midnight at local time
4988
+ dayDate = dayDate && (this.timezone ? dayDate.tz(this.timezone, true) : dayDate);
4989
+ dayDate = dayDate && dayDate
4990
+ .startOf('day') // Reset hour
4991
+ .utc(); // Convert to UTC (avoid TZ offset in final string)
4992
+ this.emitChange(dayDate);
4977
4993
  this._writing = false;
4978
4994
  }
4979
4995
  waitKeyboardHide(waitKeyboardDelay) {
@@ -4995,7 +5011,10 @@ class MatDate {
4995
5011
  const dateStr = toDateISOString(value) || null;
4996
5012
  if (this.formControl.value !== dateStr) {
4997
5013
  // DEBUG
4998
- //console.debug('[matèdate-time] Emit new value: ' + dateStr);
5014
+ //console.debug('[mat-date] Emit new value: ' + dateStr);
5015
+ // Apply to form control. => Will call writeValue()
5016
+ // NOT NEED, because a formControl should NOT be used by multiple fields
5017
+ //this.formControl.setValue(dateStr, {emitEvent: false})
4999
5018
  // Changes comes from inside function: use the callback
5000
5019
  this._onChangeCallback(dateStr);
5001
5020
  // Check if need to update controls
@@ -5028,7 +5047,7 @@ class MatDate {
5028
5047
  MatDate.decorators = [
5029
5048
  { type: Component, args: [{
5030
5049
  selector: 'mat-date-field',
5031
- template: "<!-- readonly -->\n<mat-form-field *ngIf=\"readonly; else writable\"\n [floatLabel]=\"floatLabel\"\n class=\"mat-form-field-disabled\">\n\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n <input matInput hidden type=\"text\"\n readonly\n [placeholder]=\"placeholder\"\n [formControl]=\"formControl\">\n <ion-text>{{formControl.value|dateFormat: {pattern: displayPattern} }}</ion-text>\n</mat-form-field>\n\n<!-- writable -->\n<ng-template #writable>\n <mat-form-field [floatLabel]=\"floatLabel\">\n\n <mat-label>{{placeholder}}</mat-label>\n\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n <input matInput #matInput autocomplete=\"off\" type=\"text\"\n *ngIf=\"!mobile\"\n [formControl]=\"dayControl\"\n [textMask]=\"{mask: dayMask, keepCharPositions: true, placeholderChar: placeholderChar}\"\n [placeholder]=\"'COMMON.DATE_PLACEHOLDER'|translate\"\n (blur)=\"checkIfTouched()\"\n (keyup.arrowdown)=\"openDatePicker($event, datePicker)\"\n (keyup.escape)=\"preventEvent($event)\"\n [required]=\"required\"\n [tabindex]=\"tabindex\"\n [appAutofocus]=\"autofocus\">\n <input matInput #matInput autocomplete=\"off\" type=\"text\"\n *ngIf=\"mobile\"\n [formControl]=\"dayControl\"\n (click)=\"openDatePickerIfMobile($event, datePicker)\"\n [required]=\"required\"\n [tabindex]=\"tabindex\"\n readonly>\n\n <!-- Hide the final input -->\n <input matInput type=\"text\" [formControl]=\"formControl\"\n hidden\n [matDatepicker]=\"datePicker\"\n (dateChange)=\"onDatePickerChange($event)\">\n\n <button type=\"button\" mat-icon-button tabindex=\"-1\" matSuffix\n (click)=\"openDatePicker($event, datePicker)\"\n [disabled]=\"formControl.disabled\">\n <div *ngIf=\"mobile; then iconDate; else iconDesktop\"></div>\n </button>\n <button matSuffix mat-icon-button tabindex=\"-1\"\n type=\"button\"\n *ngIf=\"clearable\"\n (click)=\"clear()\"\n [hidden]=\"formControl.disabled || !formControl.value\">\n <mat-icon>close</mat-icon>\n </button>\n\n <!-- errors -->\n <mat-error *ngIf=\"formControl.touched && formControl.errors|mapKeys|arrayFirst; let errorKey\">\n <ng-container [ngSwitch]=\"errorKey\">\n <span *ngSwitchCase=\"'required'\" translate>ERROR.FIELD_REQUIRED</span>\n <span *ngSwitchCase=\"'validDate'\" translate>ERROR.FIELD_NOT_VALID_DATE_TIME</span>\n <span *ngSwitchCase=\"'dateIsAfter'\">{{'ERROR.FIELD_NOT_VALID_DATE_AFTER' | translate: formControl.errors.dateIsAfter }}</span>\n <span *ngSwitchCase=\"'dateIsBefore'\">{{'ERROR.FIELD_NOT_VALID_DATE_BEFORE' | translate: formControl.errors.dateIsBefore }}</span>\n <span *ngSwitchCase=\"'dateRange'\" translate>ERROR.FIELD_NOT_VALID_DATE_RANGE</span>\n <span *ngSwitchCase=\"'dateMaxDuration'\" translate>ERROR.FIELD_NOT_VALID_DATE_MAX_DURATION</span>\n <span *ngSwitchCase=\"'dateMinDuration'\" translate>ERROR.FIELD_NOT_VALID_DATE_MIN_DURATION</span>\n <span *ngSwitchCase=\"'msg'\">{{(formControl.errors.msg?.key || formControl.errors.msg) | translate: formControl.errors.msg?.params}}</span>\n </ng-container>\n </mat-error>\n <ng-content select=\"mat-error\"></ng-content>\n\n <!-- mat hint -->\n <div class=\"mat-form-field-hint-wrapper\" [class.cdk-visually-hidden]=\"formControl.invalid\">\n <div class=\"mat-form-field-hint-spacer\"></div>\n <ng-content select=\"mat-hint\"></ng-content>\n </div>\n </mat-form-field>\n\n <mat-datepicker #datePicker\n [touchUi]=\"mobile\"\n [disabled]=\"formControl.disabled\"\n [startAt]=\"startDate\"></mat-datepicker>\n\n\n\n</ng-template>\n\n<ng-template #iconDesktop>\n <mat-icon>keyboard_arrow_down</mat-icon>\n</ng-template>\n\n<ng-template #iconDate>\n <mat-icon>date_range</mat-icon>\n</ng-template>\n\n<ng-template #matPrefixTemplate>\n <ng-content select=\"[matPrefix]\"></ng-content>\n</ng-template>\n",
5050
+ template: "<!-- readonly -->\n<mat-form-field *ngIf=\"readonly; else writable\"\n [floatLabel]=\"floatLabel\"\n class=\"mat-form-field-disabled\">\n\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n <input matInput hidden type=\"text\"\n readonly\n [placeholder]=\"placeholder\"\n [formControl]=\"formControl\">\n <ion-text>{{formControl.value|dateFormat: {pattern: displayPattern} }}</ion-text>\n</mat-form-field>\n\n<!-- writable -->\n<ng-template #writable>\n <mat-form-field [floatLabel]=\"floatLabel\">\n\n <mat-label>{{placeholder}}</mat-label>\n\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n <input matInput #matInput autocomplete=\"off\" type=\"text\"\n *ngIf=\"!mobile\"\n [formControl]=\"dayControl\"\n [textMask]=\"{mask: dayMask, keepCharPositions: true, placeholderChar: placeholderChar}\"\n [placeholder]=\"'COMMON.DATE_PLACEHOLDER'|translate\"\n (blur)=\"checkIfTouched()\"\n (keyup.arrowdown)=\"openDatePicker($event, datePicker)\"\n (keyup.escape)=\"preventEvent($event)\"\n [required]=\"required\"\n [tabindex]=\"tabindex\"\n [appAutofocus]=\"autofocus\">\n <input matInput #matInput autocomplete=\"off\" type=\"text\"\n *ngIf=\"mobile\"\n [formControl]=\"dayControl\"\n (click)=\"openDatePickerIfMobile($event, datePicker)\"\n [required]=\"required\"\n [tabindex]=\"tabindex\"\n readonly>\n\n <!-- Hide the final input -->\n <input matInput type=\"text\" [formControl]=\"formControl\"\n hidden\n [matDatepicker]=\"datePicker\"\n [matDatepickerFilter]=\"datePickerFilter\"\n (dateChange)=\"onDatePickerChange($event)\">\n\n <button type=\"button\" mat-icon-button tabindex=\"-1\" matSuffix\n (click)=\"openDatePicker($event, datePicker)\"\n [disabled]=\"formControl.disabled\">\n <div *ngIf=\"mobile; then iconDate; else iconDesktop\"></div>\n </button>\n <button matSuffix mat-icon-button tabindex=\"-1\"\n type=\"button\"\n *ngIf=\"clearable\"\n (click)=\"clear()\"\n [hidden]=\"formControl.disabled || !formControl.value\">\n <mat-icon>close</mat-icon>\n </button>\n\n <!-- errors -->\n <mat-error *ngIf=\"formControl.touched && formControl.errors|mapKeys|arrayFirst; let errorKey\">\n <ng-container [ngSwitch]=\"errorKey\">\n <span *ngSwitchCase=\"'required'\" translate>ERROR.FIELD_REQUIRED</span>\n <span *ngSwitchCase=\"'validDate'\" translate>ERROR.FIELD_NOT_VALID_DATE_TIME</span>\n <span *ngSwitchCase=\"'dateIsAfter'\">{{'ERROR.FIELD_NOT_VALID_DATE_AFTER' | translate: formControl.errors.dateIsAfter }}</span>\n <span *ngSwitchCase=\"'dateIsBefore'\">{{'ERROR.FIELD_NOT_VALID_DATE_BEFORE' | translate: formControl.errors.dateIsBefore }}</span>\n <span *ngSwitchCase=\"'dateRange'\" translate>ERROR.FIELD_NOT_VALID_DATE_RANGE</span>\n <span *ngSwitchCase=\"'dateMaxDuration'\" translate>ERROR.FIELD_NOT_VALID_DATE_MAX_DURATION</span>\n <span *ngSwitchCase=\"'dateMinDuration'\" translate>ERROR.FIELD_NOT_VALID_DATE_MIN_DURATION</span>\n <span *ngSwitchCase=\"'msg'\">{{(formControl.errors.msg?.key || formControl.errors.msg) | translate: formControl.errors.msg?.params}}</span>\n </ng-container>\n </mat-error>\n <ng-content select=\"mat-error\"></ng-content>\n\n <!-- mat hint -->\n <div class=\"mat-form-field-hint-wrapper\" [class.cdk-visually-hidden]=\"formControl.invalid\">\n <div class=\"mat-form-field-hint-spacer\"></div>\n <ng-content select=\"mat-hint\"></ng-content>\n </div>\n </mat-form-field>\n\n <mat-datepicker #datePicker\n [touchUi]=\"mobile\"\n [disabled]=\"formControl.disabled\"\n [startAt]=\"startDate\"\n ></mat-datepicker>\n\n\n\n</ng-template>\n\n<ng-template #iconDesktop>\n <mat-icon>keyboard_arrow_down</mat-icon>\n</ng-template>\n\n<ng-template #iconDate>\n <mat-icon>date_range</mat-icon>\n</ng-template>\n\n<ng-template #matPrefixTemplate>\n <ng-content select=\"[matPrefix]\"></ng-content>\n</ng-template>\n",
5032
5051
  providers: [
5033
5052
  DEFAULT_VALUE_ACCESSOR$5,
5034
5053
  ],
@@ -5058,6 +5077,7 @@ MatDate.propDecorators = {
5058
5077
  startDate: [{ type: Input }],
5059
5078
  clearable: [{ type: Input }],
5060
5079
  timezone: [{ type: Input }],
5080
+ datePickerFilter: [{ type: Input }],
5061
5081
  readonly: [{ type: Input }],
5062
5082
  tabindex: [{ type: Input }],
5063
5083
  datePicker: [{ type: ViewChild, args: ['datePicker',] }],
@@ -5133,18 +5153,18 @@ class MatDateTime {
5133
5153
  this.formControl.setValidators(this.required ? [this.formControl.validator, Validators.required, SharedValidators.validDate] :
5134
5154
  [this.formControl.validator, SharedValidators.validDate]);
5135
5155
  }
5136
- // Create the date control
5137
- this.dateFormControl = this.formBuilder.control(null, this.required ? Validators.required : null);
5138
- // Create the time control
5156
+ // Create the day control
5157
+ this.dayControl = this.formBuilder.control(null, this.required ? Validators.required : null);
5158
+ // Create the hour control
5139
5159
  const timeValidator = this.required ?
5140
5160
  (this.mobile ? Validators.required : Validators.compose([Validators.required, Validators.pattern(HOUR_REGEXP)])) :
5141
5161
  (this.mobile ? null : Validators.pattern(HOUR_REGEXP));
5142
- this.timeFormControl = this.formBuilder.control(null, timeValidator);
5162
+ this.hourControl = this.formBuilder.control(null, timeValidator);
5143
5163
  // Get patterns to display date and date+time
5144
5164
  this._subscription.add(this.translate.get(['COMMON.DATE_PATTERN', 'COMMON.DATE_TIME_PATTERN'])
5145
5165
  .subscribe((patterns) => this.updatePattern(patterns)));
5146
- this._subscription.add(merge(this.dateFormControl.valueChanges, this.timeFormControl.valueChanges)
5147
- .subscribe((event) => this.onFormChange(event)));
5166
+ this._subscription.add(merge(this.dayControl.valueChanges, this.hourControl.valueChanges)
5167
+ .subscribe((_) => this.onFormChange()));
5148
5168
  // Listen status changes (when done outside the component - e.g. when setErrors() is calling on the formControl)
5149
5169
  this._subscription.add(this.formControl.statusChanges
5150
5170
  .pipe(filter((_) => !this.readonly && !this._writing && !this._disabling) // Skip
@@ -5156,32 +5176,32 @@ class MatDateTime {
5156
5176
  ngOnDestroy() {
5157
5177
  this._subscription.unsubscribe();
5158
5178
  }
5159
- writeValue(valueStr) {
5179
+ writeValue(value) {
5160
5180
  if (this._writing)
5161
5181
  return; // Skip
5162
5182
  this._writing = true;
5163
5183
  // DEBUG
5164
- // console.debug("[mat-date-time] writeValue() with:", valueStr);
5165
- const value = fromDateISOString(valueStr);
5166
- if (!value || !value.isValid()) {
5167
- this.dateFormControl.patchValue(null, { emitEvent: false });
5168
- this.timeFormControl.patchValue(null, { emitEvent: false });
5184
+ // console.debug("[mat-date-time] writeValue() with:", value);
5185
+ const date = fromDateISOString(value);
5186
+ if (!date || !date.isValid()) {
5187
+ this.dayControl.patchValue(null, { emitEvent: false });
5188
+ this.hourControl.patchValue(null, { emitEvent: false });
5169
5189
  }
5170
5190
  else {
5171
5191
  // Format day
5172
- const day = value.clone().startOf('day');
5192
+ const day = date.clone().startOf('day');
5173
5193
  const dayStr = this.dateAdapter.format(day, this.dayPattern);
5174
5194
  // Format time
5175
5195
  // - Format hh
5176
- let hour = value.hour();
5196
+ let hour = date.hour();
5177
5197
  hour = hour < 10 ? ('0' + hour) : hour;
5178
5198
  // - Format mm
5179
- let minutes = value.minutes();
5199
+ let minutes = date.minutes();
5180
5200
  minutes = minutes < 10 ? ('0' + minutes) : minutes;
5181
5201
  const timeStr = `${hour}:${minutes}`;
5182
5202
  // Update controls
5183
- this.dateFormControl.patchValue(dayStr, { emitEvent: false });
5184
- this.timeFormControl.patchValue(timeStr, { emitEvent: false });
5203
+ this.dayControl.patchValue(dayStr, { emitEvent: false });
5204
+ this.hourControl.patchValue(timeStr, { emitEvent: false });
5185
5205
  }
5186
5206
  this._writing = false;
5187
5207
  this.markForCheck();
@@ -5197,12 +5217,12 @@ class MatDateTime {
5197
5217
  return; // Skip
5198
5218
  this._disabling = true;
5199
5219
  if (isDisabled) {
5200
- this.dateFormControl.disable({ emitEvent: false });
5201
- this.timeFormControl.disable({ emitEvent: false });
5220
+ this.dayControl.disable({ emitEvent: false });
5221
+ this.hourControl.disable({ emitEvent: false });
5202
5222
  }
5203
5223
  else {
5204
- this.dateFormControl.enable({ emitEvent: false });
5205
- this.timeFormControl.enable({ emitEvent: false });
5224
+ this.dayControl.enable({ emitEvent: false });
5225
+ this.hourControl.enable({ emitEvent: false });
5206
5226
  }
5207
5227
  this._disabling = false;
5208
5228
  this.markForCheck();
@@ -5215,25 +5235,25 @@ class MatDateTime {
5215
5235
  }
5216
5236
  // Convert to usable date, then convert to day pattern (e.g DD/MM/YYYY)
5217
5237
  const day = event.value && event.value
5218
- .locale(this.locale) // set as time as locale time
5238
+ .locale(this.locale) // set locale
5219
5239
  .hour(0).minute(0).seconds(0).millisecond(0) // Reset hour
5220
5240
  .utc(true);
5221
5241
  const dayStr = day && this.dateAdapter.format(day, this.dayPattern) || null;
5222
5242
  // Update the day control
5223
- if (this.dateFormControl.value !== dayStr) {
5243
+ if (this.dayControl.value !== dayStr) {
5224
5244
  // DEBUG
5225
5245
  // console.debug("[mat-date-time] onDatePickerChange() new value:", dayStr);
5226
- this.dateFormControl.setValue(dayStr, {
5246
+ this.dayControl.setValue(dayStr, {
5227
5247
  emitEvent: true // Will call onFormChange
5228
5248
  });
5229
5249
  }
5230
5250
  }
5231
5251
  onTimePickerChange(timeStr) {
5232
5252
  // Update the time control, if need
5233
- if (this.timeFormControl.value !== timeStr) {
5253
+ if (this.hourControl.value !== timeStr) {
5234
5254
  // DEBUG
5235
5255
  // console.debug("[mat-date-time] onTimePickerChange() new value:", timeStr);
5236
- this.timeFormControl.setValue(timeStr, {
5256
+ this.hourControl.setValue(timeStr, {
5237
5257
  emitEvent: true // Will call onFormChange
5238
5258
  });
5239
5259
  }
@@ -5305,26 +5325,24 @@ class MatDateTime {
5305
5325
  this.dayPattern = (patterns['COMMON.DATE_PATTERN'] !== 'COMMON.DATE_PATTERN' ? patterns['COMMON.DATE_PATTERN'] : 'L');
5306
5326
  }
5307
5327
  checkIfTouched() {
5308
- if (this.dateFormControl.touched || this.timeFormControl.touched) {
5328
+ if (this.dayControl.touched || this.hourControl.touched) {
5309
5329
  this._onTouchedCallback();
5310
5330
  this.markForCheck();
5311
5331
  }
5312
5332
  }
5313
- onFormChange(event) {
5333
+ onFormChange() {
5314
5334
  if (this._writing)
5315
5335
  return; // Skip if call by self
5316
5336
  this._writing = true;
5317
- let dayStr = this.dateFormControl.value;
5318
- const time = this.timeFormControl.value;
5337
+ let dayStr = this.dayControl.value;
5338
+ const time = this.hourControl.value;
5319
5339
  // DEBUG
5320
5340
  //console.debug(`[mat-date-time] onFormChange() from event: ${event} - controls values: `, [dayStr, time]);
5321
5341
  const incompleteValue = isNilOrBlank(time) !== isNilOrBlank(dayStr);
5322
- if (incompleteValue || this.dateFormControl.invalid || this.timeFormControl.invalid) {
5342
+ if (incompleteValue || this.dayControl.invalid || this.hourControl.invalid) {
5323
5343
  this.formControl.markAsPending({ onlySelf: true });
5324
- this.formControl.setErrors(Object.assign(Object.assign(Object.assign({ validDate: incompleteValue }, this.formControl.errors), this.dateFormControl.errors), this.timeFormControl.errors));
5344
+ this.formControl.setErrors(Object.assign(Object.assign(Object.assign({ validDate: incompleteValue }, this.formControl.errors), this.dayControl.errors), this.hourControl.errors));
5325
5345
  this.formControl.markAsDirty();
5326
- // Reset the value
5327
- //this.emitChange(null);
5328
5346
  this._writing = false;
5329
5347
  return;
5330
5348
  }
@@ -5366,7 +5384,10 @@ class MatDateTime {
5366
5384
  const dateStr = toDateISOString(value) || null;
5367
5385
  if (this.formControl.value !== dateStr) {
5368
5386
  // DEBUG
5369
- //console.debug('[matèdate-time] Emit new value: ' + dateStr);
5387
+ //console.debug('[mat-date-time] Emit new value: ' + dateStr);
5388
+ // Apply to form control. => Will call writeValue()
5389
+ // NOT NEED, because a formControl should NOT be used by multiple fields
5390
+ //this.formControl.setValue(dateStr, {emitEvent: false});
5370
5391
  // Changes comes from inside function: use the callback
5371
5392
  this._onChangeCallback(dateStr);
5372
5393
  // Check if need to update controls
@@ -5385,8 +5406,8 @@ class MatDateTime {
5385
5406
  });
5386
5407
  }
5387
5408
  markAsTouched(opts) {
5388
- this.dateFormControl.markAsTouched(opts);
5389
- this.timeFormControl.markAsTouched(opts);
5409
+ this.dayControl.markAsTouched(opts);
5410
+ this.hourControl.markAsTouched(opts);
5390
5411
  this._onTouchedCallback();
5391
5412
  this.markForCheck();
5392
5413
  }
@@ -5400,7 +5421,7 @@ class MatDateTime {
5400
5421
  MatDateTime.decorators = [
5401
5422
  { type: Component, args: [{
5402
5423
  selector: 'mat-date-time-field',
5403
- template: "<!-- readonly -->\n<mat-form-field *ngIf=\"readonly; else writable\"\n [floatLabel]=\"floatLabel\"\n class=\"mat-form-field-disabled\">\n\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n <input matInput hidden type=\"text\"\n readonly\n [placeholder]=\"placeholder\"\n [formControl]=\"formControl\">\n <ion-text>{{formControl.value|dateFormat: {pattern: displayPattern} }}</ion-text>\n</mat-form-field>\n\n<!-- writable + time -->\n<ng-template #writable >\n <ion-grid class=\"ion-no-padding\">\n <ion-row class=\"ion-no-padding no-wrap\" nowrap>\n\n <!-- day -->\n <ion-col class=\"day ion-no-padding\">\n <mat-form-field [floatLabel]=\"floatLabel\"\n [class.mat-form-field-invalid]=\"formControl.touched && formControl.invalid\">\n\n <mat-label>{{placeholder}}</mat-label>\n\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n <input matInput #matInput autocomplete=\"off\" type=\"text\"\n *ngIf=\"!mobile\"\n [formControl]=\"dateFormControl\"\n [textMask]=\"{mask: dayMask, keepCharPositions: true, placeholderChar: placeholderChar}\"\n [placeholder]=\"'COMMON.DATE_PLACEHOLDER'|translate\"\n (blur)=\"checkIfTouched()\"\n (keyup.arrowdown)=\"openDatePicker($event, datePicker)\"\n (keyup.escape)=\"preventEvent($event)\"\n [required]=\"required\"\n [tabindex]=\"tabindex\"\n [appAutofocus]=\"autofocus\">\n <input matInput #matInput autocomplete=\"off\" type=\"text\"\n *ngIf=\"mobile\"\n [formControl]=\"dateFormControl\"\n (click)=\"openDatePickerIfMobile($event, datePicker)\"\n [required]=\"required\"\n [tabindex]=\"tabindex\"\n readonly>\n\n <!-- Hide the final input -->\n <input matInput type=\"text\" [formControl]=\"formControl\"\n hidden\n [matDatepicker]=\"datePicker\"\n (dateChange)=\"onDatePickerChange($event)\">\n\n <button type=\"button\" mat-icon-button tabindex=\"-1\" matSuffix\n (click)=\"openDatePicker($event, datePicker)\"\n [disabled]=\"formControl.disabled\">\n <div *ngIf=\"mobile; then iconDate; else iconDesktop\"></div>\n </button>\n <button matSuffix mat-icon-button tabindex=\"-1\"\n type=\"button\"\n *ngIf=\"clearable\"\n (click)=\"clear()\"\n [hidden]=\"formControl.disabled || !formControl.value\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n <mat-datepicker #datePicker\n [touchUi]=\"mobile\"\n [disabled]=\"formControl.disabled\"\n [startAt]=\"startDate\"></mat-datepicker>\n <div class=\"mat-form-field-subscript mat-form-field-subscript-wrapper\" >\n <!-- errors -->\n <ng-container [ngSwitch]=\"formControl.touched && formControl.errors|mapKeys|arrayFirst\">\n <mat-error *ngSwitchCase=\"'required'\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngSwitchCase=\"'validDate'\" translate>ERROR.FIELD_NOT_VALID_DATE_TIME</mat-error>\n <mat-error *ngSwitchCase=\"'dateIsAfter'\">{{'ERROR.FIELD_NOT_VALID_DATE_AFTER' | translate: formControl.errors.dateIsAfter }}</mat-error>\n <mat-error *ngSwitchCase=\"'dateIsBefore'\">{{'ERROR.FIELD_NOT_VALID_DATE_BEFORE' | translate: formControl.errors.dateIsBefore }}</mat-error>\n <mat-error *ngSwitchCase=\"'dateRange'\" translate>ERROR.FIELD_NOT_VALID_DATE_RANGE</mat-error>\n <mat-error *ngSwitchCase=\"'dateMaxDuration'\" translate>ERROR.FIELD_NOT_VALID_DATE_MAX_DURATION</mat-error>\n <mat-error *ngSwitchCase=\"'dateMinDuration'\" translate>ERROR.FIELD_NOT_VALID_DATE_MIN_DURATION</mat-error>\n <mat-error *ngSwitchCase=\"'msg'\">{{(formControl.errors.msg?.key || formControl.errors.msg) | translate: formControl.errors.msg?.params}}</mat-error>\n </ng-container>\n <ng-content select=\"mat-error\"></ng-content>\n\n <!-- mat hint -->\n <div class=\"mat-form-field-hint-wrapper\" [class.cdk-visually-hidden]=\"formControl.invalid\">\n <div class=\"mat-form-field-hint-spacer\"></div>\n <ng-content select=\"mat-hint\"></ng-content>\n </div>\n </div>\n\n </ion-col>\n\n <!-- hour -->\n <ion-col class=\"hour ion-no-padding\">\n <mat-form-field [floatLabel]=\"floatLabel\"\n [class.mat-form-field-invalid]=\"formControl.touched && (timeFormControl.invalid || formControl.invalid)\">\n <mat-label *ngIf=\"placeholder && floatLabel != 'never'\" translate>COMMON.TIME</mat-label>\n <input matInput #matInput type=\"text\"\n *ngIf=\"!mobile\"\n [formControl]=\"timeFormControl\"\n autocomplete=\"off\"\n min=\"0\" max=\"23\"\n [textMask]=\"{mask: hourMask, keepCharPositions: true, placeholderChar: placeholderChar, guide: true}\"\n [placeholder]=\"'COMMON.TIME_PLACEHOLDER'|translate\"\n [required]=\"required\"\n (keyup.arrowdown)=\"openTimePicker($event)\"\n (keyup.escape)=\"preventEvent($event)\"\n (blur)=\"checkIfTouched()\"\n [tabindex]=\"tabindex !== undefined ? tabindex+1 : undefined\">\n\n <input matInput #matInput type=\"text\"\n *ngIf=\"mobile\"\n [formControl]=\"timeFormControl\"\n (click)=\"openTimePickerIfMobile($event)\"\n readonly>\n\n <input matInput type=\"text\"\n [formControl]=\"timeFormControl\"\n hidden\n [ngxTimepicker]=\"timePicker\"\n [format]=\"24\">\n\n <button matSuffix type=\"button\" mat-icon-button\n tabindex=\"-1\"\n *ngIf=\"!compact && !mobile\"\n [disabled]=\"formControl.disabled\"\n (click)=\"openTimePicker($event)\" >\n <mat-icon>keyboard_arrow_down</mat-icon>\n </button>\n <button matSuffix type=\"button\" mat-icon-button\n tabindex=\"-1\"\n *ngIf=\"!compact && mobile\"\n [disabled]=\"formControl.disabled\"\n (click)=\"openTimePickerIfMobile($event)\">\n <mat-icon>access_time</mat-icon>\n </button>\n\n <ngx-material-timepicker #timePicker [@.disabled]=\"true\"\n (timeSet)=\"onTimePickerChange($event)\"\n [ESC]=\"!mobile\"\n [defaultTime]=\"'00:00'\"\n [cancelBtnTmpl]=\"timePickerCancelButton\"\n [confirmBtnTmpl]=\"timePickerOkButton\"\n [preventOverlayClick]=\"mobile\"\n [enableKeyboardInput]=\"false\"\n [disableAnimation]=\"true\">\n <!-- cancel button -->\n <ng-template #timePickerCancelButton>\n <ion-button fill=\"clear\" color=\"dark\">\n <ion-label translate>COMMON.BTN_CANCEL</ion-label>\n </ion-button>\n </ng-template>\n\n <!-- confirm button -->\n <ng-template #timePickerOkButton>\n <ion-button fill=\"solid\" color=\"tertiary\">\n <ion-label translate>COMMON.BTN_VALIDATE</ion-label>\n </ion-button>\n </ng-template>\n\n </ngx-material-timepicker>\n </mat-form-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n\n</ng-template>\n\n<ng-template #iconDesktop>\n <mat-icon>keyboard_arrow_down</mat-icon>\n</ng-template>\n\n<ng-template #iconDate>\n <mat-icon>date_range</mat-icon>\n</ng-template>\n\n<ng-template #matPrefixTemplate>\n <ng-content select=\"[matPrefix]\"></ng-content>\n</ng-template>\n",
5424
+ template: "<!-- readonly -->\n<mat-form-field *ngIf=\"readonly; else writable\"\n [floatLabel]=\"floatLabel\"\n class=\"mat-form-field-disabled\">\n\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n <input matInput hidden type=\"text\"\n readonly\n [placeholder]=\"placeholder\"\n [formControl]=\"formControl\">\n <ion-text>{{formControl.value|dateFormat: {pattern: displayPattern} }}</ion-text>\n</mat-form-field>\n\n<!-- writable + time -->\n<ng-template #writable >\n <ion-grid class=\"ion-no-padding\">\n <ion-row class=\"ion-no-padding no-wrap\" nowrap>\n\n <!-- day -->\n <ion-col class=\"day ion-no-padding\">\n <mat-form-field [floatLabel]=\"floatLabel\"\n [class.mat-form-field-invalid]=\"formControl.touched && formControl.invalid\">\n\n <mat-label>{{placeholder}}</mat-label>\n\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n <input matInput #matInput autocomplete=\"off\" type=\"text\"\n *ngIf=\"!mobile\"\n [formControl]=\"dayControl\"\n [textMask]=\"{mask: dayMask, keepCharPositions: true, placeholderChar: placeholderChar}\"\n [placeholder]=\"'COMMON.DATE_PLACEHOLDER'|translate\"\n (blur)=\"checkIfTouched()\"\n (keyup.arrowdown)=\"openDatePicker($event, datePicker)\"\n (keyup.escape)=\"preventEvent($event)\"\n [required]=\"required\"\n [tabindex]=\"tabindex\"\n [appAutofocus]=\"autofocus\">\n <input matInput #matInput autocomplete=\"off\" type=\"text\"\n *ngIf=\"mobile\"\n [formControl]=\"dayControl\"\n (click)=\"openDatePickerIfMobile($event, datePicker)\"\n [required]=\"required\"\n [tabindex]=\"tabindex\"\n readonly>\n\n <!-- Hide the final input -->\n <input matInput type=\"text\" [formControl]=\"formControl\"\n hidden\n [matDatepicker]=\"datePicker\"\n [matDatepickerFilter]=\"datePickerFilter\"\n (dateChange)=\"onDatePickerChange($event)\">\n\n <button type=\"button\" mat-icon-button tabindex=\"-1\" matSuffix\n (click)=\"openDatePicker($event, datePicker)\"\n [disabled]=\"formControl.disabled\">\n <div *ngIf=\"mobile; then iconDate; else iconDesktop\"></div>\n </button>\n <button matSuffix mat-icon-button tabindex=\"-1\"\n type=\"button\"\n *ngIf=\"clearable\"\n (click)=\"clear()\"\n [hidden]=\"formControl.disabled || !formControl.value\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n <mat-datepicker #datePicker\n [touchUi]=\"mobile\"\n [disabled]=\"formControl.disabled\"\n [startAt]=\"startDate\"></mat-datepicker>\n <div class=\"mat-form-field-subscript mat-form-field-subscript-wrapper\" >\n <!-- errors -->\n <ng-container [ngSwitch]=\"formControl.touched && formControl.errors|mapKeys|arrayFirst\">\n <mat-error *ngSwitchCase=\"'required'\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngSwitchCase=\"'validDate'\" translate>ERROR.FIELD_NOT_VALID_DATE_TIME</mat-error>\n <mat-error *ngSwitchCase=\"'dateIsAfter'\">{{'ERROR.FIELD_NOT_VALID_DATE_AFTER' | translate: formControl.errors.dateIsAfter }}</mat-error>\n <mat-error *ngSwitchCase=\"'dateIsBefore'\">{{'ERROR.FIELD_NOT_VALID_DATE_BEFORE' | translate: formControl.errors.dateIsBefore }}</mat-error>\n <mat-error *ngSwitchCase=\"'dateRange'\" translate>ERROR.FIELD_NOT_VALID_DATE_RANGE</mat-error>\n <mat-error *ngSwitchCase=\"'dateMaxDuration'\" translate>ERROR.FIELD_NOT_VALID_DATE_MAX_DURATION</mat-error>\n <mat-error *ngSwitchCase=\"'dateMinDuration'\" translate>ERROR.FIELD_NOT_VALID_DATE_MIN_DURATION</mat-error>\n <mat-error *ngSwitchCase=\"'msg'\">{{(formControl.errors.msg?.key || formControl.errors.msg) | translate: formControl.errors.msg?.params}}</mat-error>\n </ng-container>\n <ng-content select=\"mat-error\"></ng-content>\n\n <!-- mat hint -->\n <div class=\"mat-form-field-hint-wrapper\" [class.cdk-visually-hidden]=\"formControl.invalid\">\n <div class=\"mat-form-field-hint-spacer\"></div>\n <ng-content select=\"mat-hint\"></ng-content>\n </div>\n </div>\n\n </ion-col>\n\n <!-- hour -->\n <ion-col class=\"hour ion-no-padding\">\n <mat-form-field [floatLabel]=\"floatLabel\"\n [class.mat-form-field-invalid]=\"formControl.touched && (hourControl.invalid || formControl.invalid)\">\n <mat-label *ngIf=\"placeholder && floatLabel != 'never'\" translate>COMMON.TIME</mat-label>\n <input matInput #matInput type=\"text\"\n *ngIf=\"!mobile\"\n [formControl]=\"hourControl\"\n autocomplete=\"off\"\n min=\"0\" max=\"23\"\n [textMask]=\"{mask: hourMask, keepCharPositions: true, placeholderChar: placeholderChar, guide: true}\"\n [placeholder]=\"'COMMON.TIME_PLACEHOLDER'|translate\"\n [required]=\"required\"\n (keyup.arrowdown)=\"openTimePicker($event)\"\n (keyup.escape)=\"preventEvent($event)\"\n (blur)=\"checkIfTouched()\"\n [tabindex]=\"tabindex !== undefined ? tabindex+1 : undefined\">\n\n <input matInput #matInput type=\"text\"\n *ngIf=\"mobile\"\n [formControl]=\"hourControl\"\n (click)=\"openTimePickerIfMobile($event)\"\n readonly>\n\n <input matInput type=\"text\"\n [formControl]=\"hourControl\"\n hidden\n [ngxTimepicker]=\"timePicker\"\n [format]=\"24\">\n\n <button matSuffix type=\"button\" mat-icon-button\n tabindex=\"-1\"\n *ngIf=\"!compact && !mobile\"\n [disabled]=\"formControl.disabled\"\n (click)=\"openTimePicker($event)\" >\n <mat-icon>keyboard_arrow_down</mat-icon>\n </button>\n <button matSuffix type=\"button\" mat-icon-button\n tabindex=\"-1\"\n *ngIf=\"!compact && mobile\"\n [disabled]=\"formControl.disabled\"\n (click)=\"openTimePickerIfMobile($event)\">\n <mat-icon>access_time</mat-icon>\n </button>\n\n <ngx-material-timepicker #timePicker [@.disabled]=\"true\"\n (timeSet)=\"onTimePickerChange($event)\"\n [ESC]=\"!mobile\"\n [defaultTime]=\"'00:00'\"\n [cancelBtnTmpl]=\"timePickerCancelButton\"\n [confirmBtnTmpl]=\"timePickerOkButton\"\n [preventOverlayClick]=\"mobile\"\n [enableKeyboardInput]=\"false\"\n [disableAnimation]=\"true\">\n <!-- cancel button -->\n <ng-template #timePickerCancelButton>\n <ion-button fill=\"clear\" color=\"dark\">\n <ion-label translate>COMMON.BTN_CANCEL</ion-label>\n </ion-button>\n </ng-template>\n\n <!-- confirm button -->\n <ng-template #timePickerOkButton>\n <ion-button fill=\"solid\" color=\"tertiary\">\n <ion-label translate>COMMON.BTN_VALIDATE</ion-label>\n </ion-button>\n </ng-template>\n\n </ngx-material-timepicker>\n </mat-form-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n\n</ng-template>\n\n<ng-template #iconDesktop>\n <mat-icon>keyboard_arrow_down</mat-icon>\n</ng-template>\n\n<ng-template #iconDate>\n <mat-icon>date_range</mat-icon>\n</ng-template>\n\n<ng-template #matPrefixTemplate>\n <ng-content select=\"[matPrefix]\"></ng-content>\n</ng-template>\n",
5404
5425
  providers: [
5405
5426
  DEFAULT_VALUE_ACCESSOR$4,
5406
5427
  ],
@@ -5429,6 +5450,7 @@ MatDateTime.propDecorators = {
5429
5450
  autofocus: [{ type: Input }],
5430
5451
  startDate: [{ type: Input }],
5431
5452
  clearable: [{ type: Input }],
5453
+ datePickerFilter: [{ type: Input }],
5432
5454
  readonly: [{ type: Input }],
5433
5455
  tabindex: [{ type: Input }],
5434
5456
  datePicker: [{ type: ViewChild, args: ['datePicker',] }],
@@ -26278,7 +26300,7 @@ class DateTestPage {
26278
26300
  DateTestPage.decorators = [
26279
26301
  { type: Component, args: [{
26280
26302
  selector: 'app-data-test',
26281
- template: "<ion-header>\n <ion-toolbar color=\"primary\">\n\n <ion-buttons slot=\"start\">\n <ion-back-button></ion-back-button>\n </ion-buttons>\n\n <ion-title>Date/Time field test page</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content class=\"ion-padding\">\n\n <form class=\"form-container\" [formGroup]=\"form\" (ngSubmit)=\"doSubmit($event)\">\n\n <ion-grid>\n\n <!-- debugging memory leak -->\n <ion-row><ion-col><ion-text><h4>Debug memory leak</h4></ion-text></ion-col></ion-row>\n <ion-row>\n <ion-col size=\"2\">\n <ion-button *ngIf=\"!memoryTimer\" (click)=\"startMemoryTimer()\">Start timer</ion-button>\n <ion-button *ngIf=\"memoryTimer\" (click)=\"stopMemoryTimer()\">Stop timer</ion-button>\n </ion-col>\n <ion-col size=\"2\">\n <mat-form-field floatLabel=\"never\">\n <input matInput type=\"text\" hidden>\n <mat-checkbox (change)=\"memoryMobile=$event.checked\" [value]=\"memoryMobile\">\n Mobile ?\n </mat-checkbox>\n </mat-form-field>\n </ion-col>\n <ion-col>\n <mat-date-field formControlName=\"empty\"\n *ngIf=\"!memoryHide\"\n placeholder=\"Date/Time\"\n [required]=\"true\"\n [mobile]=\"memoryMobile\"\n [clearable]=\"true\">\n <ion-icon matPrefix name=\"calendar-outline\"></ion-icon>\n </mat-date-field>\n </ion-col>\n </ion-row>\n\n <!-- Mobile mode -->\n <ion-row><ion-col><ion-text><h4>Mobile mode</h4></ion-text></ion-col></ion-row>\n <ion-row>\n <ion-col>\n\n <!-- Empty value -->\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Empty value\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>{{stringify(form.controls.empty.value)}}</pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-date-field formControlName=\"empty\"\n placeholder=\"Date/Time\"\n [required]=\"true\"\n [mobile]=\"true\"\n [clearable]=\"true\">\n <ion-icon matPrefix name=\"calendar-outline\"></ion-icon>\n </mat-date-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <!-- Enable -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n With value\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>{{stringify(form.controls.enable.value)}}</pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-date-field formControlName=\"enable\"\n placeholder=\"Date/Time\"\n [required]=\"true\"\n [mobile]=\"true\"\n [clearable]=\"true\">\n <ion-icon matPrefix name=\"calendar-outline\"></ion-icon>\n </mat-date-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <!-- Disable -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Disable\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>{{stringify(form.controls.disable.value)}}</pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-date-field formControlName=\"disable\"\n placeholder=\"Date/Time\"\n [required]=\"true\"\n [mobile]=\"true\">\n <ion-icon matPrefix name=\"calendar-outline\"></ion-icon>\n </mat-date-field>\n\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n <!-- debug console -->\n <ion-row>\n <!-- buttons -->\n <ion-col size=\"2\">\n <!-- submit form -->\n <ion-button (click)=\"doSubmit($event)\"\n fill=\"outline\">\n <ion-icon name=\"checkmark\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n\n <!-- clear log -->\n <ion-button (click)=\"clearLogPanel()\"\n fill=\"outline\">\n <ion-icon name=\"trash\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </ion-col>\n <ion-col size=\"10\" *ngIf=\"showLogPanel\">\n <ion-text color=\"primary\">Log:<br/></ion-text>\n <div class=\"ion-padding-start\">\n <ion-text color=\"medium\">\n <small [innerHTML]=\"logContent\"></small>\n </ion-text>\n </div>\n </ion-col>\n </ion-row>\n\n <!-- Desktop mode -->\n <ion-row><ion-col><ion-text><h4>Desktop mode</h4></ion-text></ion-col></ion-row>\n <ion-row>\n <ion-col>\n\n <!-- Empty value -->\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Empty value\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>{{stringify(form.controls.empty.value)}}</pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-date-field formControlName=\"empty\"\n placeholder=\"Date/Time\"\n [required]=\"true\"\n [mobile]=\"false\"\n [clearable]=\"true\">\n <ion-icon matPrefix name=\"calendar-outline\"></ion-icon>\n </mat-date-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <!-- Enable -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n With value\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>{{stringify(form.controls.enable.value)}}</pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-date-field formControlName=\"enable\"\n placeholder=\"Date/Time\"\n [required]=\"true\"\n [mobile]=\"false\"\n [clearable]=\"true\">\n <ion-icon matPrefix name=\"calendar-outline\"></ion-icon>\n </mat-date-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <!-- Disable -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Disable\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>{{stringify(form.controls.disable.value)}}</pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-date-field formControlName=\"disable\"\n placeholder=\"Date/Time\"\n [required]=\"true\"\n [mobile]=\"false\">\n <ion-icon matPrefix name=\"calendar-outline\"></ion-icon>\n </mat-date-field>\n\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <!-- TimeZone -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n TimeZone\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>timezone=\"{{timezone}}\" value=\"{{stringify(form.controls.timezone.value)}}\"</pre></small>\n <pre>Should display using the browser TZ,<br/>but serialize/deserialize for the given TZ</pre>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-date-field #readonlyField formControlName=\"timezone\"\n placeholder=\"Date\"\n [mobile]=\"false\"\n [clearable]=\"true\"\n timezone=\"Indian/Mahe\">\n <ion-icon matPrefix name=\"calendar-outline\"></ion-icon>\n </mat-date-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <!-- Readonly -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Readonly toggle\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>{{stringify(form.controls.readonly.value)}}</pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-checkbox (change)=\"readonlyField.readonly=$event.checked\" [checked]=\"readonlyField.readonly\">\n </mat-checkbox>\n\n <mat-date-field #readonlyField formControlName=\"readonly\"\n placeholder=\"Date/Time\"\n [readonly]=\"true\"\n [mobile]=\"false\"\n [clearable]=\"true\">\n <ion-icon matPrefix name=\"calendar-outline\"></ion-icon>\n </mat-date-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n </ion-row>\n </ion-grid>\n </form>\n\n</ion-content>\n"
26303
+ template: "<ion-header>\n <ion-toolbar color=\"primary\">\n\n <ion-buttons slot=\"start\">\n <ion-back-button></ion-back-button>\n </ion-buttons>\n\n <ion-title>Date field test page</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content class=\"ion-padding\">\n\n <form class=\"form-container\" [formGroup]=\"form\" (ngSubmit)=\"doSubmit($event)\">\n\n <ion-grid>\n\n <!-- debugging memory leak -->\n <ion-row><ion-col><ion-text><h4>Debug memory leak</h4></ion-text></ion-col></ion-row>\n <ion-row>\n <ion-col size=\"2\">\n <ion-button *ngIf=\"!memoryTimer\" (click)=\"startMemoryTimer()\">Start timer</ion-button>\n <ion-button *ngIf=\"memoryTimer\" (click)=\"stopMemoryTimer()\">Stop timer</ion-button>\n </ion-col>\n <ion-col size=\"2\">\n <mat-form-field floatLabel=\"never\">\n <input matInput type=\"text\" hidden>\n <mat-checkbox (change)=\"memoryMobile=$event.checked\" [value]=\"memoryMobile\">\n Mobile ?\n </mat-checkbox>\n </mat-form-field>\n </ion-col>\n <ion-col>\n <mat-date-field formControlName=\"empty\"\n *ngIf=\"!memoryHide\"\n placeholder=\"Date\"\n [required]=\"true\"\n [mobile]=\"memoryMobile\"\n [clearable]=\"true\">\n <ion-icon matPrefix name=\"calendar-outline\"></ion-icon>\n </mat-date-field>\n </ion-col>\n </ion-row>\n\n <!-- Mobile mode -->\n <ion-row><ion-col><ion-text><h4>Mobile mode</h4></ion-text></ion-col></ion-row>\n <ion-row>\n <ion-col>\n\n <!-- Empty value -->\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Empty value\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>{{stringify(form.controls.empty.value)}}</pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-date-field formControlName=\"empty\"\n placeholder=\"Date\"\n [required]=\"true\"\n [mobile]=\"true\"\n [clearable]=\"true\">\n <ion-icon matPrefix name=\"calendar-outline\"></ion-icon>\n </mat-date-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <!-- Enable -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n With value\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>{{stringify(form.controls.enable.value)}}</pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-date-field formControlName=\"enable\"\n placeholder=\"Date\"\n [required]=\"true\"\n [mobile]=\"true\"\n [clearable]=\"true\">\n <ion-icon matPrefix name=\"calendar-outline\"></ion-icon>\n </mat-date-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <!-- Disable -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Disable\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>{{stringify(form.controls.disable.value)}}</pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-date-field formControlName=\"disable\"\n placeholder=\"Date\"\n [required]=\"true\"\n [mobile]=\"true\">\n <ion-icon matPrefix name=\"calendar-outline\"></ion-icon>\n </mat-date-field>\n\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <!-- TimeZone -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n TimeZone\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>timezone=\"{{timezone}}\" value=\"{{stringify(form.controls.timezone.value)}}\"</pre></small>\n <pre>Should display using the browser TZ,<br/>but serialize/deserialize for the given TZ</pre>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-date-field #readonlyField formControlName=\"timezone\"\n placeholder=\"Date\"\n [mobile]=\"true\"\n [clearable]=\"true\"\n [timezone]=\"timezone\">\n <ion-icon matPrefix name=\"calendar-outline\"></ion-icon>\n </mat-date-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n <!-- debug console -->\n <ion-row>\n <!-- buttons -->\n <ion-col size=\"2\">\n <!-- submit form -->\n <ion-button (click)=\"doSubmit($event)\"\n fill=\"outline\">\n <ion-icon name=\"checkmark\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n\n <!-- clear log -->\n <ion-button (click)=\"clearLogPanel()\"\n fill=\"outline\">\n <ion-icon name=\"trash\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </ion-col>\n <ion-col size=\"10\" *ngIf=\"showLogPanel\">\n <ion-text color=\"primary\">Log:<br/></ion-text>\n <div class=\"ion-padding-start\">\n <ion-text color=\"medium\">\n <small [innerHTML]=\"logContent\"></small>\n </ion-text>\n </div>\n </ion-col>\n </ion-row>\n\n <hr/>\n\n <!-- Desktop mode -->\n <ion-row><ion-col><ion-text><h4>Desktop mode</h4></ion-text></ion-col></ion-row>\n <ion-row>\n <ion-col>\n\n <!-- Empty value -->\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Empty value\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>{{stringify(form.controls.empty.value)}}</pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-date-field formControlName=\"empty\"\n placeholder=\"Date\"\n [required]=\"true\"\n [mobile]=\"false\"\n [clearable]=\"true\">\n <ion-icon matPrefix name=\"calendar-outline\"></ion-icon>\n </mat-date-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <!-- Enable -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n With value\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>{{stringify(form.controls.enable.value)}}</pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-date-field formControlName=\"enable\"\n placeholder=\"Date\"\n [required]=\"true\"\n [mobile]=\"false\"\n [clearable]=\"true\">\n <ion-icon matPrefix name=\"calendar-outline\"></ion-icon>\n </mat-date-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <!-- Disable -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Disable\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>{{stringify(form.controls.disable.value)}}</pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-date-field formControlName=\"disable\"\n placeholder=\"Date\"\n [required]=\"true\"\n [mobile]=\"false\">\n <ion-icon matPrefix name=\"calendar-outline\"></ion-icon>\n </mat-date-field>\n\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <!-- TimeZone -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n TimeZone\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>timezone=\"{{timezone}}\" value={{stringify(form.controls.timezone.value)}}</pre></small>\n <pre>Should display using the browser TZ,<br/>but serialize/deserialize for the given TZ</pre>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-date-field #readonlyField formControlName=\"timezone\"\n placeholder=\"Date\"\n [mobile]=\"false\"\n [clearable]=\"true\"\n [timezone]=\"timezone\">\n <ion-icon matPrefix name=\"calendar-outline\"></ion-icon>\n </mat-date-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <!-- Readonly -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Readonly toggle\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>{{stringify(form.controls.readonly.value)}}</pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-checkbox (change)=\"readonlyField.readonly=$event.checked\" [checked]=\"readonlyField.readonly\">\n </mat-checkbox>\n\n <mat-date-field #readonlyField formControlName=\"readonly\"\n placeholder=\"Date\"\n [readonly]=\"true\"\n [mobile]=\"false\"\n [clearable]=\"true\">\n <ion-icon matPrefix name=\"calendar-outline\"></ion-icon>\n </mat-date-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n </ion-row>\n </ion-grid>\n </form>\n\n</ion-content>\n"
26282
26304
  },] }
26283
26305
  ];
26284
26306
  DateTestPage.ctorParameters = () => [