@syncfusion/ej2-calendars 30.1.37 → 31.1.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.json +263 -0
- package/dist/ej2-calendars.min.js +1 -1
- package/dist/ej2-calendars.umd.min.js +1 -1
- package/dist/global/ej2-calendars.min.js +1 -1
- package/dist/global/index.d.ts +1 -1
- package/dist/ts/calendar/calendar-model.d.ts +340 -0
- package/dist/ts/calendar/calendar.d.ts +733 -0
- package/dist/ts/calendar/calendar.ts +3009 -0
- package/dist/ts/calendar/index.d.ts +6 -0
- package/dist/ts/calendar/index.ts +6 -0
- package/dist/ts/calendar/islamic.d.ts +28 -0
- package/dist/ts/calendar/islamic.ts +597 -0
- package/dist/ts/common/index.d.ts +5 -0
- package/dist/ts/common/index.ts +5 -0
- package/dist/ts/common/maskplaceholder-model.d.ts +57 -0
- package/dist/ts/common/maskplaceholder.d.ts +45 -0
- package/dist/ts/common/maskplaceholder.ts +54 -0
- package/dist/ts/datepicker/datepicker-model.d.ts +364 -0
- package/dist/ts/datepicker/datepicker.d.ts +583 -0
- package/dist/ts/datepicker/datepicker.ts +2528 -0
- package/dist/ts/datepicker/index.d.ts +5 -0
- package/dist/ts/datepicker/index.ts +5 -0
- package/dist/ts/daterangepicker/daterangepicker-model.d.ts +496 -0
- package/dist/ts/daterangepicker/daterangepicker.d.ts +857 -0
- package/dist/ts/daterangepicker/daterangepicker.ts +5096 -0
- package/dist/ts/daterangepicker/index.d.ts +5 -0
- package/dist/ts/daterangepicker/index.ts +5 -0
- package/dist/ts/datetimepicker/datetimepicker-model.d.ts +479 -0
- package/dist/ts/datetimepicker/datetimepicker.d.ts +626 -0
- package/dist/ts/datetimepicker/datetimepicker.ts +2212 -0
- package/dist/ts/datetimepicker/index.d.ts +5 -0
- package/dist/ts/datetimepicker/index.ts +5 -0
- package/dist/ts/index.d.ts +9 -0
- package/dist/ts/index.ts +9 -0
- package/dist/ts/maskbase/index.d.ts +5 -0
- package/dist/ts/maskbase/index.ts +5 -0
- package/dist/ts/maskbase/interface.d.ts +28 -0
- package/dist/ts/maskbase/interface.ts +29 -0
- package/dist/ts/maskbase/masked-date-time.d.ts +77 -0
- package/dist/ts/maskbase/masked-date-time.ts +1013 -0
- package/dist/ts/timepicker/index.d.ts +5 -0
- package/dist/ts/timepicker/index.ts +5 -0
- package/dist/ts/timepicker/timepicker-model.d.ts +393 -0
- package/dist/ts/timepicker/timepicker.d.ts +681 -0
- package/dist/ts/timepicker/timepicker.ts +2944 -0
- package/package.json +59 -16
- package/styles/daterangepicker/_fluent2-definition.scss +2 -1
- package/styles/daterangepicker/fluent2.css +2 -1
- package/styles/datetimepicker/_fluent2-definition.scss +1 -1
- package/styles/datetimepicker/fluent2.css +1 -1
- package/styles/fluent2-lite.css +3 -2
- package/styles/fluent2.css +3 -2
- package/tslint.json +111 -0
|
@@ -0,0 +1,2528 @@
|
|
|
1
|
+
// eslint-disable-next-line @typescript-eslint/triple-slash-reference
|
|
2
|
+
/// <reference path='../calendar/calendar-model.d.ts'/>
|
|
3
|
+
import { EventHandler, Property, Internationalization, NotifyPropertyChanges, DateFormatOptions } from '@syncfusion/ej2-base';
|
|
4
|
+
import { KeyboardEvents, KeyboardEventArgs, Animation, EmitType, Event, extend, L10n, Browser, formatUnit } from '@syncfusion/ej2-base';
|
|
5
|
+
import { detach, addClass, removeClass, closest, attributes, Touch, SwipeEventArgs } from '@syncfusion/ej2-base';
|
|
6
|
+
import { isNullOrUndefined, setValue, getUniqueID, ModuleDeclaration } from '@syncfusion/ej2-base';
|
|
7
|
+
import { Popup } from '@syncfusion/ej2-popups';
|
|
8
|
+
import { Input, InputObject, IInput, FloatLabelType } from '@syncfusion/ej2-inputs';
|
|
9
|
+
import { ChangedEventArgs, CalendarView, Calendar, BlurEventArgs, FocusEventArgs, ClearedEventArgs } from '../calendar/calendar';
|
|
10
|
+
import { MaskPlaceholderModel } from '../common/maskplaceholder-model';
|
|
11
|
+
import { DatePickerModel } from './datepicker-model';
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
//class constant defination
|
|
15
|
+
const DATEWRAPPER: string = 'e-date-wrapper';
|
|
16
|
+
const ROOT: string = 'e-datepicker';
|
|
17
|
+
const LIBRARY: string = 'e-lib';
|
|
18
|
+
const CONTROL: string = 'e-control';
|
|
19
|
+
const POPUPWRAPPER: string = 'e-popup-wrapper';
|
|
20
|
+
const INPUTWRAPPER: string = 'e-input-group-icon';
|
|
21
|
+
const POPUP: string = 'e-popup';
|
|
22
|
+
const INPUTCONTAINER: string = 'e-input-group';
|
|
23
|
+
const INPUTFOCUS: string = 'e-input-focus';
|
|
24
|
+
const INPUTROOT: string = 'e-input';
|
|
25
|
+
const ERROR: string = 'e-error';
|
|
26
|
+
const ACTIVE: string = 'e-active';
|
|
27
|
+
const OVERFLOW: string = 'e-date-overflow';
|
|
28
|
+
const DATEICON: string = 'e-date-icon';
|
|
29
|
+
const CLEARICON: string = 'e-clear-icon';
|
|
30
|
+
const ICONS: string = 'e-icons';
|
|
31
|
+
const OPENDURATION: number = 300;
|
|
32
|
+
const OFFSETVALUE: number = 4;
|
|
33
|
+
const SELECTED: string = 'e-selected';
|
|
34
|
+
const FOCUSEDDATE: string = 'e-focused-date';
|
|
35
|
+
const NONEDIT: string = 'e-non-edit';
|
|
36
|
+
const containerAttr: string[] = ['title', 'class', 'style'];
|
|
37
|
+
export interface FormatObject {
|
|
38
|
+
/**
|
|
39
|
+
* Specifies the format in which the date format will process
|
|
40
|
+
*/
|
|
41
|
+
skeleton?: string
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Represents the DatePicker component that allows user to select
|
|
46
|
+
* or enter a date value.
|
|
47
|
+
* ```html
|
|
48
|
+
* <input id='datepicker'/>
|
|
49
|
+
* ```
|
|
50
|
+
* ```typescript
|
|
51
|
+
* <script>
|
|
52
|
+
* let datePickerObject:DatePicker = new DatePicker({ value: new Date() });
|
|
53
|
+
* datePickerObject.appendTo('#datepicker');
|
|
54
|
+
* </script>
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
@NotifyPropertyChanges
|
|
58
|
+
export class DatePicker extends Calendar implements IInput {
|
|
59
|
+
protected popupObj: Popup;
|
|
60
|
+
protected inputWrapper: InputObject;
|
|
61
|
+
private modal: HTMLElement;
|
|
62
|
+
protected inputElement: HTMLInputElement;
|
|
63
|
+
protected popupWrapper: HTMLElement;
|
|
64
|
+
protected changedArgs: ChangedEventArgs;
|
|
65
|
+
protected previousDate: Date;
|
|
66
|
+
private keyboardModules: KeyboardEvents;
|
|
67
|
+
private calendarKeyboardModules: KeyboardEvents;
|
|
68
|
+
protected previousElementValue: string;
|
|
69
|
+
protected ngTag: string;
|
|
70
|
+
protected dateTimeFormat: string;
|
|
71
|
+
protected inputElementCopy: HTMLElement;
|
|
72
|
+
protected inputValueCopy: Date;
|
|
73
|
+
protected l10n: L10n;
|
|
74
|
+
protected preventArgs: PopupObjectArgs;
|
|
75
|
+
private isDateIconClicked: boolean = false;
|
|
76
|
+
protected isAltKeyPressed: boolean = false;
|
|
77
|
+
private isInteracted: boolean = true;
|
|
78
|
+
private index: number;
|
|
79
|
+
private formElement: HTMLElement;
|
|
80
|
+
protected invalidValueString: string = null;
|
|
81
|
+
private checkPreviousValue: Date = null;
|
|
82
|
+
protected formatString: string;
|
|
83
|
+
protected inputFormatsString: string[];
|
|
84
|
+
protected tabIndex: string;
|
|
85
|
+
protected maskedDateValue: string = '';
|
|
86
|
+
private datepickerOptions: DatePickerModel;
|
|
87
|
+
protected defaultKeyConfigs: { [key: string]: string };
|
|
88
|
+
protected mobilePopupWrapper: HTMLElement;
|
|
89
|
+
protected preventChange: boolean = false;
|
|
90
|
+
protected isIconClicked : boolean = false;
|
|
91
|
+
protected isDynamicValueChanged: boolean = false;
|
|
92
|
+
protected moduleName: string = this.getModuleName();
|
|
93
|
+
protected isFocused: boolean = false;
|
|
94
|
+
protected touchModule: Touch;
|
|
95
|
+
protected touchStart: boolean;
|
|
96
|
+
protected iconRight: boolean;
|
|
97
|
+
protected isBlur: boolean = false;
|
|
98
|
+
private isKeyAction: boolean = false;
|
|
99
|
+
protected clearButton: HTMLElement;
|
|
100
|
+
/**
|
|
101
|
+
* Specifies the width of the DatePicker component.
|
|
102
|
+
*
|
|
103
|
+
* @default null
|
|
104
|
+
*/
|
|
105
|
+
@Property(null)
|
|
106
|
+
public width: number | string;
|
|
107
|
+
/**
|
|
108
|
+
* Gets or sets the selected date of the Calendar.
|
|
109
|
+
*
|
|
110
|
+
* @default null
|
|
111
|
+
* @isGenericType true
|
|
112
|
+
* @deprecated
|
|
113
|
+
*/
|
|
114
|
+
@Property(null)
|
|
115
|
+
public value: Date;
|
|
116
|
+
/**
|
|
117
|
+
* Specifies the root CSS class of the DatePicker that allows to
|
|
118
|
+
* customize the appearance by overriding the styles.
|
|
119
|
+
*
|
|
120
|
+
* @default null
|
|
121
|
+
*/
|
|
122
|
+
@Property(null)
|
|
123
|
+
public cssClass: string;
|
|
124
|
+
/**
|
|
125
|
+
* Specifies the component to act as strict. So that, it allows to enter only a valid date value within a specified range or else it
|
|
126
|
+
* will resets to previous value. By default, strictMode is in false.
|
|
127
|
+
* it allows invalid or out-of-range date value with highlighted error class.
|
|
128
|
+
*
|
|
129
|
+
* @default false
|
|
130
|
+
* > For more details refer to
|
|
131
|
+
* [`Strict Mode`](../../datepicker/strict-mode/) documentation.
|
|
132
|
+
*/
|
|
133
|
+
@Property(false)
|
|
134
|
+
public strictMode: boolean;
|
|
135
|
+
/**
|
|
136
|
+
* Specifies the format of the value that to be displayed in component. By default, the format is based on the culture. You can set
|
|
137
|
+
* the format to "format:'dd/MM/yyyy hh:mm'" or "format:{skeleton:'medium'}" either in string or object.
|
|
138
|
+
* > To know more about the date format standards, refer to the Internationalization Date Format
|
|
139
|
+
* [`Internationalization`](../../common/internationalization/#custom-formats) section.
|
|
140
|
+
*
|
|
141
|
+
* @default null
|
|
142
|
+
* @aspType string
|
|
143
|
+
*/
|
|
144
|
+
@Property(null)
|
|
145
|
+
public format: string | FormatObject;
|
|
146
|
+
/**
|
|
147
|
+
* Specifies an array of acceptable date input formats for parsing user input.
|
|
148
|
+
*
|
|
149
|
+
* @default null
|
|
150
|
+
* @aspType string[]
|
|
151
|
+
*/
|
|
152
|
+
@Property(null)
|
|
153
|
+
public inputFormats: string[] | FormatObject[];
|
|
154
|
+
/**
|
|
155
|
+
* Specifies the component to be disabled or not.
|
|
156
|
+
*
|
|
157
|
+
* @default true
|
|
158
|
+
*/
|
|
159
|
+
@Property(true)
|
|
160
|
+
public enabled: boolean;
|
|
161
|
+
/**
|
|
162
|
+
* Specifies the component popup display full screen in mobile devices.
|
|
163
|
+
*
|
|
164
|
+
* @default false
|
|
165
|
+
*/
|
|
166
|
+
@Property(false)
|
|
167
|
+
public fullScreenMode : boolean;
|
|
168
|
+
/**
|
|
169
|
+
* You can add the additional html attributes such as disabled, value etc., to the element.
|
|
170
|
+
* If you configured both property and equivalent html attribute then the component considers the property value.
|
|
171
|
+
* {% codeBlock src='datepicker/htmlAttributes/index.md' %}{% endcodeBlock %}
|
|
172
|
+
*
|
|
173
|
+
* @default {}
|
|
174
|
+
*/
|
|
175
|
+
@Property({})
|
|
176
|
+
public htmlAttributes: { [key: string]: string };
|
|
177
|
+
/**
|
|
178
|
+
* Gets or sets multiple selected dates of the calendar.
|
|
179
|
+
*
|
|
180
|
+
* @default null
|
|
181
|
+
* @private
|
|
182
|
+
*/
|
|
183
|
+
@Property(null)
|
|
184
|
+
public values: Date[];
|
|
185
|
+
/**
|
|
186
|
+
* Specifies the option to enable the multiple dates selection of the calendar.
|
|
187
|
+
*
|
|
188
|
+
* @default false
|
|
189
|
+
* @private
|
|
190
|
+
*/
|
|
191
|
+
@Property(false)
|
|
192
|
+
public isMultiSelection: boolean;
|
|
193
|
+
/**
|
|
194
|
+
* Specifies whether to show or hide the clear icon in textbox.
|
|
195
|
+
*
|
|
196
|
+
* @default true
|
|
197
|
+
*/
|
|
198
|
+
@Property(true)
|
|
199
|
+
public showClearButton: boolean;
|
|
200
|
+
/**
|
|
201
|
+
* > Support for `allowEdit` has been provided from
|
|
202
|
+
* [`v16.2.46`](https://ej2.syncfusion.com/angular/documentation/release-notes/16.2.46/#datepicker).
|
|
203
|
+
*
|
|
204
|
+
* Specifies whether the input textbox is editable or not. Here the user can select the value from the
|
|
205
|
+
* popup and cannot edit in the input textbox.
|
|
206
|
+
*
|
|
207
|
+
* @default true
|
|
208
|
+
*/
|
|
209
|
+
@Property(true)
|
|
210
|
+
public allowEdit: boolean;
|
|
211
|
+
/**
|
|
212
|
+
* Customizes the key actions in DatePicker.
|
|
213
|
+
* For example, when using German keyboard, the key actions can be customized using these shortcuts.
|
|
214
|
+
*
|
|
215
|
+
*
|
|
216
|
+
* Input Navigation
|
|
217
|
+
* <table>
|
|
218
|
+
* <tr>
|
|
219
|
+
* <td colSpan=1 rowSpan=1>
|
|
220
|
+
* Key action<br/></td><td colSpan=1 rowSpan=1>
|
|
221
|
+
* Key<br/></td></tr>
|
|
222
|
+
* <tr>
|
|
223
|
+
* <td colSpan=1 rowSpan=1>
|
|
224
|
+
* altUpArrow<br/></td><td colSpan=1 rowSpan=1>
|
|
225
|
+
* alt+uparrow<br/></td></tr>
|
|
226
|
+
* <tr>
|
|
227
|
+
* <td colSpan=1 rowSpan=1>
|
|
228
|
+
* altDownArrow<br/></td><td colSpan=1 rowSpan=1>
|
|
229
|
+
* alt+downarrow<br/></td></tr>
|
|
230
|
+
* <tr>
|
|
231
|
+
* <td colSpan=1 rowSpan=1>
|
|
232
|
+
* escape<br/></td><td colSpan=1 rowSpan=1>
|
|
233
|
+
* escape<br/></td></tr>
|
|
234
|
+
* </table>
|
|
235
|
+
*
|
|
236
|
+
* Calendar Navigation
|
|
237
|
+
* <table>
|
|
238
|
+
* <tr>
|
|
239
|
+
* <td colSpan=1 rowSpan=1>
|
|
240
|
+
* Key action<br/></td><td colSpan=1 rowSpan=1>
|
|
241
|
+
* Key<br/></td></tr>
|
|
242
|
+
* <tr>
|
|
243
|
+
* <td colSpan=1 rowSpan=1>
|
|
244
|
+
* controlUp<br/></td><td colSpan=1 rowSpan=1>
|
|
245
|
+
* ctrl+38<br/></td></tr>
|
|
246
|
+
* <tr>
|
|
247
|
+
* <td colSpan=1 rowSpan=1>
|
|
248
|
+
* controlDown<br/></td><td colSpan=1 rowSpan=1>
|
|
249
|
+
* ctrl+40<br/></td></tr>
|
|
250
|
+
* <tr>
|
|
251
|
+
* <td colSpan=1 rowSpan=1>
|
|
252
|
+
* moveDown<br/></td><td colSpan=1 rowSpan=1>
|
|
253
|
+
* downarrow<br/></td></tr>
|
|
254
|
+
* <tr>
|
|
255
|
+
* <td colSpan=1 rowSpan=1>
|
|
256
|
+
* moveUp<br/></td><td colSpan=1 rowSpan=1>
|
|
257
|
+
* uparrow<br/></td></tr>
|
|
258
|
+
* <tr>
|
|
259
|
+
* <td colSpan=1 rowSpan=1>
|
|
260
|
+
* moveLeft<br/></td><td colSpan=1 rowSpan=1>
|
|
261
|
+
* leftarrow<br/></td></tr>
|
|
262
|
+
* <tr>
|
|
263
|
+
* <td colSpan=1 rowSpan=1>
|
|
264
|
+
* moveRight<br/></td><td colSpan=1 rowSpan=1>
|
|
265
|
+
* rightarrow<br/></td></tr>
|
|
266
|
+
* <tr>
|
|
267
|
+
* <td colSpan=1 rowSpan=1>
|
|
268
|
+
* shiftPageUp<br/></td><td colSpan=1 rowSpan=1>
|
|
269
|
+
* shift+pageup<br/></td></tr>
|
|
270
|
+
* <tr>
|
|
271
|
+
* <td colSpan=1 rowSpan=1>
|
|
272
|
+
* shiftPageDown<br/></td><td colSpan=1 rowSpan=1>
|
|
273
|
+
* shift+pagedown<br/></td></tr>
|
|
274
|
+
* <tr>
|
|
275
|
+
* <tr>
|
|
276
|
+
* <td colSpan=1 rowSpan=1>
|
|
277
|
+
* select<br/></td><td colSpan=1 rowSpan=1>
|
|
278
|
+
* enter<br/></td></tr>
|
|
279
|
+
* <tr>
|
|
280
|
+
* <td colSpan=1 rowSpan=1>
|
|
281
|
+
* home<br/></td><td colSpan=1 rowSpan=1>
|
|
282
|
+
* home<br/></td></tr>
|
|
283
|
+
* <tr>
|
|
284
|
+
* <td colSpan=1 rowSpan=1>
|
|
285
|
+
* end<br/></td><td colSpan=1 rowSpan=1>
|
|
286
|
+
* end<br/></td></tr>
|
|
287
|
+
* <tr>
|
|
288
|
+
* <td colSpan=1 rowSpan=1>
|
|
289
|
+
* pageUp<br/></td><td colSpan=1 rowSpan=1>
|
|
290
|
+
* pageup<br/></td></tr>
|
|
291
|
+
* <tr>
|
|
292
|
+
* <td colSpan=1 rowSpan=1>
|
|
293
|
+
* pageDown<br/></td><td colSpan=1 rowSpan=1>
|
|
294
|
+
* pagedown<br/></td></tr>
|
|
295
|
+
* <td colSpan=1 rowSpan=1>
|
|
296
|
+
* controlHome<br/></td><td colSpan=1 rowSpan=1>
|
|
297
|
+
* ctrl+home<br/></td></tr>
|
|
298
|
+
* <tr>
|
|
299
|
+
* <td colSpan=1 rowSpan=1>
|
|
300
|
+
* controlEnd<br/></td><td colSpan=1 rowSpan=1>
|
|
301
|
+
* ctrl+end<br/></td></tr>
|
|
302
|
+
* <tr>
|
|
303
|
+
* <td colSpan=1 rowSpan=1>
|
|
304
|
+
* altUpArrow<br/></td><td colSpan=1 rowSpan=1>
|
|
305
|
+
* alt+uparrow<br/></td></tr>
|
|
306
|
+
* <tr>
|
|
307
|
+
* <td colSpan=1 rowSpan=1>
|
|
308
|
+
* spacebar<br/></td><td colSpan=1 rowSpan=1>
|
|
309
|
+
* space<br/></td></tr>
|
|
310
|
+
* <tr>
|
|
311
|
+
* <td colSpan=1 rowSpan=1>
|
|
312
|
+
* altRightArrow<br/></td><td colSpan=1 rowSpan=1>
|
|
313
|
+
* alt+rightarrow<br/></td></tr>
|
|
314
|
+
* <tr>
|
|
315
|
+
* <td colSpan=1 rowSpan=1>
|
|
316
|
+
* altLeftArrow<br/></td><td colSpan=1 rowSpan=1>
|
|
317
|
+
* alt+leftarrow<br/></td></tr>
|
|
318
|
+
* </table>
|
|
319
|
+
*
|
|
320
|
+
* {% codeBlock src='datepicker/keyConfigs/index.md' %}{% endcodeBlock %}
|
|
321
|
+
*
|
|
322
|
+
* @default null
|
|
323
|
+
* @deprecated
|
|
324
|
+
*/
|
|
325
|
+
@Property(null)
|
|
326
|
+
public keyConfigs: { [key: string]: string };
|
|
327
|
+
/**
|
|
328
|
+
* Enable or disable persisting component's state between page reloads. If enabled, following list of states will be persisted.
|
|
329
|
+
* 1. value
|
|
330
|
+
*
|
|
331
|
+
* @default false
|
|
332
|
+
* @deprecated
|
|
333
|
+
*/
|
|
334
|
+
@Property(false)
|
|
335
|
+
public enablePersistence: boolean;
|
|
336
|
+
/**
|
|
337
|
+
* specifies the z-index value of the datePicker popup element.
|
|
338
|
+
*
|
|
339
|
+
* @default 1000
|
|
340
|
+
* @aspType int
|
|
341
|
+
*/
|
|
342
|
+
@Property(1000)
|
|
343
|
+
public zIndex: number;
|
|
344
|
+
/**
|
|
345
|
+
* Specifies the component in readonly state. When the Component is readonly it does not allow user input.
|
|
346
|
+
*
|
|
347
|
+
* @default false
|
|
348
|
+
*/
|
|
349
|
+
@Property(false)
|
|
350
|
+
public readonly: boolean;
|
|
351
|
+
/**
|
|
352
|
+
* Specifies the placeholder text that displayed in textbox.
|
|
353
|
+
*
|
|
354
|
+
* @default null
|
|
355
|
+
*/
|
|
356
|
+
@Property(null)
|
|
357
|
+
public placeholder: string;
|
|
358
|
+
/**
|
|
359
|
+
* Specifies the placeholder text to be floated.
|
|
360
|
+
* Possible values are:
|
|
361
|
+
* Never: The label will never float in the input when the placeholder is available.
|
|
362
|
+
* Always: The floating label will always float above the input.
|
|
363
|
+
* Auto: The floating label will float above the input after focusing or entering a value in the input.
|
|
364
|
+
*
|
|
365
|
+
* @default Syncfusion.EJ2.Inputs.FloatLabelType.Never
|
|
366
|
+
* @aspType Syncfusion.EJ2.Inputs.FloatLabelType
|
|
367
|
+
* @isEnumeration true
|
|
368
|
+
*/
|
|
369
|
+
@Property('Never')
|
|
370
|
+
public floatLabelType: FloatLabelType | string;
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* By default, the date value will be processed based on system time zone.
|
|
374
|
+
* If you want to process the initial date value using server time zone
|
|
375
|
+
* then specify the time zone value to `serverTimezoneOffset` property.
|
|
376
|
+
*
|
|
377
|
+
* @default null
|
|
378
|
+
* @deprecated
|
|
379
|
+
*/
|
|
380
|
+
@Property(null)
|
|
381
|
+
public serverTimezoneOffset: number;
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* By default, the popup opens while clicking on the datepicker icon.
|
|
385
|
+
* If you want to open the popup while focusing the date input then specify its value as true.
|
|
386
|
+
*
|
|
387
|
+
* @default false
|
|
388
|
+
*/
|
|
389
|
+
@Property(false)
|
|
390
|
+
public openOnFocus : boolean;
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Specifies whether it is a masked datepicker or not.
|
|
394
|
+
* By default the datepicker component render without masked input.
|
|
395
|
+
* If you need masked datepicker input then specify it as true.
|
|
396
|
+
*
|
|
397
|
+
* @default false
|
|
398
|
+
*/
|
|
399
|
+
@Property(false)
|
|
400
|
+
public enableMask: boolean;
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Specifies the mask placeholder to be displayed on masked datepicker.
|
|
404
|
+
*
|
|
405
|
+
* @default {day:'day' , month:'month', year: 'year', hour:'hour',minute:'minute',second:'second',dayOfTheWeek: 'day of the week'}
|
|
406
|
+
*/
|
|
407
|
+
@Property({day: 'day' , month: 'month', year: 'year', hour: 'hour', minute: 'minute', second: 'second', dayOfTheWeek: 'day of the week'})
|
|
408
|
+
public maskPlaceholder: MaskPlaceholderModel;
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Triggers when the popup is opened.
|
|
413
|
+
*
|
|
414
|
+
* @event open
|
|
415
|
+
*/
|
|
416
|
+
@Event()
|
|
417
|
+
public open: EmitType<PreventableEventArgs | PopupObjectArgs>;
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* Triggers when datepicker value is cleared using clear button.
|
|
421
|
+
*
|
|
422
|
+
* @event cleared
|
|
423
|
+
*/
|
|
424
|
+
@Event()
|
|
425
|
+
public cleared: EmitType<ClearedEventArgs>;
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* Triggers when the popup is closed.
|
|
429
|
+
*
|
|
430
|
+
* @event close
|
|
431
|
+
*/
|
|
432
|
+
@Event()
|
|
433
|
+
public close: EmitType<PreventableEventArgs | PopupObjectArgs>;
|
|
434
|
+
/**
|
|
435
|
+
* Triggers when the input loses the focus.
|
|
436
|
+
*
|
|
437
|
+
* @event blur
|
|
438
|
+
*/
|
|
439
|
+
@Event()
|
|
440
|
+
public blur: EmitType<BlurEventArgs>;
|
|
441
|
+
/**
|
|
442
|
+
* Triggers when the input gets focus.
|
|
443
|
+
*
|
|
444
|
+
* @event focus
|
|
445
|
+
*/
|
|
446
|
+
@Event()
|
|
447
|
+
public focus: EmitType<FocusEventArgs>;
|
|
448
|
+
/**
|
|
449
|
+
* Triggers when the component is created.
|
|
450
|
+
*
|
|
451
|
+
* @event created
|
|
452
|
+
*/
|
|
453
|
+
@Event()
|
|
454
|
+
public created: EmitType<Object>;
|
|
455
|
+
/**
|
|
456
|
+
* Triggers when the component is destroyed.
|
|
457
|
+
*
|
|
458
|
+
* @event destroyed
|
|
459
|
+
*/
|
|
460
|
+
@Event()
|
|
461
|
+
public destroyed: EmitType<Object>;
|
|
462
|
+
/**
|
|
463
|
+
* Constructor for creating the widget.
|
|
464
|
+
*
|
|
465
|
+
* @param {DatePickerModel} options - Specifies the DatePicker model.
|
|
466
|
+
* @param {string | HTMLInputElement} element - Specifies the element to render as component.
|
|
467
|
+
* @private
|
|
468
|
+
*/
|
|
469
|
+
public constructor(options?: DatePickerModel, element?: string | HTMLInputElement) {
|
|
470
|
+
super(options, element);
|
|
471
|
+
this.datepickerOptions = options;
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* To Initialize the control rendering.
|
|
475
|
+
*
|
|
476
|
+
* @returns {void}
|
|
477
|
+
* @private
|
|
478
|
+
*/
|
|
479
|
+
public render(): void {
|
|
480
|
+
this.initialize();
|
|
481
|
+
this.bindEvents();
|
|
482
|
+
if (this.floatLabelType !== 'Never') {
|
|
483
|
+
Input.calculateWidth(this.inputElement, this.inputWrapper.container);
|
|
484
|
+
}
|
|
485
|
+
if (!isNullOrUndefined(this.inputWrapper.buttons[0]) && !isNullOrUndefined(this.inputWrapper.container.getElementsByClassName('e-float-text-overflow')[0]) && this.floatLabelType !== 'Never') {
|
|
486
|
+
this.inputWrapper.container.getElementsByClassName('e-float-text-overflow')[0].classList.add('e-icon');
|
|
487
|
+
}
|
|
488
|
+
if (!isNullOrUndefined(closest(this.element, 'fieldset') as HTMLFieldSetElement) && (closest(this.element, 'fieldset') as HTMLFieldSetElement).disabled) {
|
|
489
|
+
this.enabled = false;
|
|
490
|
+
}
|
|
491
|
+
this.renderComplete();
|
|
492
|
+
this.setTimeZone(this.serverTimezoneOffset);
|
|
493
|
+
}
|
|
494
|
+
protected setTimeZone(offsetValue: number ): void {
|
|
495
|
+
if (!isNullOrUndefined(this.serverTimezoneOffset) && this.value) {
|
|
496
|
+
const clientTimeZoneDiff: number = new Date().getTimezoneOffset() / 60;
|
|
497
|
+
const serverTimezoneDiff: number = offsetValue;
|
|
498
|
+
let timeZoneDiff: number = serverTimezoneDiff + clientTimeZoneDiff;
|
|
499
|
+
timeZoneDiff = this.isDayLightSaving() ? timeZoneDiff-- : timeZoneDiff;
|
|
500
|
+
this.value = new Date((this.value).getTime() + (timeZoneDiff * 60 * 60 * 1000));
|
|
501
|
+
this.updateInput();
|
|
502
|
+
this.changeTrigger(null);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
protected isDayLightSaving(): boolean {
|
|
506
|
+
const firstOffset: number = new Date(this.value.getFullYear(), 0 , 1).getTimezoneOffset();
|
|
507
|
+
const secondOffset: number = new Date(this.value.getFullYear(), 6 , 1).getTimezoneOffset();
|
|
508
|
+
return (this.value.getTimezoneOffset() < Math.max(firstOffset, secondOffset));
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
protected setAllowEdit(): void {
|
|
512
|
+
if (this.allowEdit) {
|
|
513
|
+
if (!this.readonly) {
|
|
514
|
+
this.inputElement.removeAttribute('readonly');
|
|
515
|
+
}
|
|
516
|
+
} else {
|
|
517
|
+
attributes(this.inputElement, { 'readonly': '' });
|
|
518
|
+
}
|
|
519
|
+
this.updateIconState();
|
|
520
|
+
}
|
|
521
|
+
protected updateIconState(): void {
|
|
522
|
+
if (!this.allowEdit && this.inputWrapper && !this.readonly) {
|
|
523
|
+
if (this.inputElement.value === '') {
|
|
524
|
+
removeClass([this.inputWrapper.container], [NONEDIT]);
|
|
525
|
+
} else {
|
|
526
|
+
addClass([this.inputWrapper.container], [NONEDIT]);
|
|
527
|
+
}
|
|
528
|
+
} else if (this.inputWrapper) {
|
|
529
|
+
removeClass([this.inputWrapper.container], [NONEDIT]);
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
private initialize(): void {
|
|
533
|
+
this.checkInvalidValue(this.value);
|
|
534
|
+
if (this.enableMask) {
|
|
535
|
+
this.notify('createMask', {
|
|
536
|
+
module: 'MaskedDateTime'
|
|
537
|
+
});
|
|
538
|
+
}
|
|
539
|
+
this.createInput();
|
|
540
|
+
this.updateHtmlAttributeToWrapper();
|
|
541
|
+
this.setAllowEdit();
|
|
542
|
+
if (this.enableMask && !this.value && this.maskedDateValue && (this.floatLabelType === 'Always' || !this.floatLabelType || !this.placeholder)){
|
|
543
|
+
this.updateInput(true);
|
|
544
|
+
this.updateInputValue(this.maskedDateValue);
|
|
545
|
+
}
|
|
546
|
+
else if (!this.enableMask) {
|
|
547
|
+
this.updateInput(true);
|
|
548
|
+
}
|
|
549
|
+
this.previousElementValue = this.inputElement.value;
|
|
550
|
+
this.previousDate = !isNullOrUndefined(this.value) ? new Date(+this.value) : null;
|
|
551
|
+
this.inputElement.setAttribute('value', this.inputElement.value);
|
|
552
|
+
|
|
553
|
+
this.inputValueCopy = this.value;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
private createInput(): void {
|
|
557
|
+
const ariaAttrs: object = {
|
|
558
|
+
'aria-atomic': 'true', 'aria-expanded': 'false',
|
|
559
|
+
'role': 'combobox', 'autocomplete': 'off', 'autocorrect': 'off',
|
|
560
|
+
'autocapitalize': 'off', 'spellcheck': 'false', 'aria-invalid': 'false'
|
|
561
|
+
};
|
|
562
|
+
if (this.getModuleName() === 'datepicker') {
|
|
563
|
+
const l10nLocale: object = { placeholder: this.placeholder };
|
|
564
|
+
this.globalize = new Internationalization(this.locale);
|
|
565
|
+
this.l10n = new L10n('datepicker', l10nLocale, this.locale);
|
|
566
|
+
this.setProperties({ placeholder: this.placeholder || this.l10n.getConstant('placeholder') }, true);
|
|
567
|
+
}
|
|
568
|
+
if (this.fullScreenMode && Browser.isDevice){
|
|
569
|
+
this.cssClass += ' ' + 'e-popup-expand';
|
|
570
|
+
}
|
|
571
|
+
let updatedCssClassValues: string = this.cssClass;
|
|
572
|
+
if (!isNullOrUndefined(this.cssClass) && this.cssClass !== '') {
|
|
573
|
+
updatedCssClassValues = (this.cssClass.replace(/\s+/g, ' ')).trim();
|
|
574
|
+
}
|
|
575
|
+
const isBindClearAction: boolean = this.enableMask ? false : true;
|
|
576
|
+
this.inputWrapper = Input.createInput(
|
|
577
|
+
{
|
|
578
|
+
element: this.inputElement,
|
|
579
|
+
floatLabelType: this.floatLabelType,
|
|
580
|
+
bindClearAction: isBindClearAction,
|
|
581
|
+
properties: {
|
|
582
|
+
readonly: this.readonly,
|
|
583
|
+
placeholder: this.placeholder,
|
|
584
|
+
cssClass: updatedCssClassValues,
|
|
585
|
+
enabled: this.enabled,
|
|
586
|
+
enableRtl: this.enableRtl,
|
|
587
|
+
showClearButton: this.showClearButton
|
|
588
|
+
},
|
|
589
|
+
buttons: [INPUTWRAPPER + ' ' + DATEICON + ' ' + ICONS]
|
|
590
|
+
},
|
|
591
|
+
this.createElement
|
|
592
|
+
);
|
|
593
|
+
this.setWidth(this.width);
|
|
594
|
+
if (this.inputElement.name !== '') {
|
|
595
|
+
this.inputElement.setAttribute('name', '' + this.inputElement.getAttribute('name'));
|
|
596
|
+
} else {
|
|
597
|
+
this.inputElement.setAttribute('name', '' + this.element.id);
|
|
598
|
+
}
|
|
599
|
+
attributes(this.inputElement, <{ [key: string]: string }>ariaAttrs);
|
|
600
|
+
if (!this.inputElement.hasAttribute('aria-label')) {
|
|
601
|
+
this.inputElement.setAttribute('aria-label', this.getModuleName());
|
|
602
|
+
}
|
|
603
|
+
if (!this.enabled) {
|
|
604
|
+
this.inputElement.setAttribute('aria-disabled', 'true');
|
|
605
|
+
this.inputElement.tabIndex = -1;
|
|
606
|
+
} else {
|
|
607
|
+
this.inputElement.setAttribute('aria-disabled', 'false');
|
|
608
|
+
this.inputElement.setAttribute('tabindex', this.tabIndex);
|
|
609
|
+
}
|
|
610
|
+
Input.addAttributes({ 'aria-label': 'select', 'role': 'button' }, this.inputWrapper.buttons[0]);
|
|
611
|
+
addClass([this.inputWrapper.container], DATEWRAPPER);
|
|
612
|
+
}
|
|
613
|
+
protected updateInput(isDynamic: boolean = false, isBlur: boolean = false): void {
|
|
614
|
+
let formatOptions: DateFormatOptions;
|
|
615
|
+
if (this.value && !this.isCalendar()) {
|
|
616
|
+
this.disabledDates(isDynamic, isBlur);
|
|
617
|
+
}
|
|
618
|
+
if (isNaN(+new Date(this.checkValue(this.value)))) {
|
|
619
|
+
this.setProperties({ value: null }, true);
|
|
620
|
+
}
|
|
621
|
+
if (this.strictMode) {
|
|
622
|
+
//calls the Calendar processDate protected method to update the date value according to the strictMode true behaviour.
|
|
623
|
+
super.validateDate();
|
|
624
|
+
this.minMaxUpdates();
|
|
625
|
+
super.minMaxUpdate();
|
|
626
|
+
}
|
|
627
|
+
if (!isNullOrUndefined(this.value)) {
|
|
628
|
+
const dateValue: Date = this.value;
|
|
629
|
+
let dateString: string;
|
|
630
|
+
const tempFormat: string = !isNullOrUndefined(this.formatString) ? this.formatString : this.dateTimeFormat;
|
|
631
|
+
if (this.getModuleName() === 'datetimepicker') {
|
|
632
|
+
if (this.calendarMode === 'Gregorian') {
|
|
633
|
+
dateString = this.globalize.formatDate(this.value, {
|
|
634
|
+
format: tempFormat, type: 'dateTime', skeleton: 'yMd'
|
|
635
|
+
});
|
|
636
|
+
} else {
|
|
637
|
+
dateString = this.globalize.formatDate(this.value, {
|
|
638
|
+
format: tempFormat, type: 'dateTime', skeleton: 'yMd', calendar: 'islamic'
|
|
639
|
+
});
|
|
640
|
+
}
|
|
641
|
+
} else {
|
|
642
|
+
if (this.calendarMode === 'Gregorian') {
|
|
643
|
+
formatOptions = { format: this.formatString, type: 'dateTime', skeleton: 'yMd' };
|
|
644
|
+
} else {
|
|
645
|
+
formatOptions = { format: this.formatString, type: 'dateTime', skeleton: 'yMd', calendar: 'islamic' };
|
|
646
|
+
}
|
|
647
|
+
dateString = this.globalize.formatDate(this.value, formatOptions);
|
|
648
|
+
}
|
|
649
|
+
if ((+dateValue <= +this.max) && (+dateValue >= +this.min)) {
|
|
650
|
+
this.updateInputValue(dateString);
|
|
651
|
+
} else {
|
|
652
|
+
const value: boolean = (+dateValue >= +this.max || !+this.value) || (!+this.value || +dateValue <= +this.min);
|
|
653
|
+
if (!this.strictMode && value) {
|
|
654
|
+
this.updateInputValue(dateString);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
if (isNullOrUndefined(this.value) && this.strictMode) {
|
|
659
|
+
if (!this.enableMask)
|
|
660
|
+
{
|
|
661
|
+
this.updateInputValue('');
|
|
662
|
+
}
|
|
663
|
+
else
|
|
664
|
+
{
|
|
665
|
+
this.updateInputValue(this.maskedDateValue);
|
|
666
|
+
this.notify('createMask', {
|
|
667
|
+
module: 'MaskedDateTime'
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
if (!this.strictMode && isNullOrUndefined(this.value) && this.invalidValueString) {
|
|
672
|
+
this.updateInputValue(this.invalidValueString);
|
|
673
|
+
}
|
|
674
|
+
this.changedArgs = { value: this.value };
|
|
675
|
+
this.errorClass();
|
|
676
|
+
this.updateIconState();
|
|
677
|
+
}
|
|
678
|
+
protected minMaxUpdates(): void {
|
|
679
|
+
if (!isNullOrUndefined(this.value) && this.value < this.min && this.min <= this.max && this.strictMode) {
|
|
680
|
+
this.setProperties({ value: this.min }, true);
|
|
681
|
+
this.changedArgs = { value: this.value };
|
|
682
|
+
} else {
|
|
683
|
+
if (!isNullOrUndefined(this.value) && this.value > this.max && this.min <= this.max && this.strictMode) {
|
|
684
|
+
this.setProperties({ value: this.max }, true);
|
|
685
|
+
this.changedArgs = { value: this.value };
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
private checkStringValue(val: string): Date {
|
|
690
|
+
let returnDate: Date = null;
|
|
691
|
+
let formatOptions: object = null;
|
|
692
|
+
let formatDateTime: object = null;
|
|
693
|
+
if (this.getModuleName() === 'datetimepicker') {
|
|
694
|
+
const culture: Internationalization = new Internationalization(this.locale);
|
|
695
|
+
if (this.calendarMode === 'Gregorian') {
|
|
696
|
+
formatOptions = { format: this.dateTimeFormat, type: 'dateTime', skeleton: 'yMd' };
|
|
697
|
+
formatDateTime = { format: culture.getDatePattern({ skeleton: 'yMd' }), type: 'dateTime' };
|
|
698
|
+
} else {
|
|
699
|
+
formatOptions = { format: this.dateTimeFormat, type: 'dateTime', skeleton: 'yMd', calendar: 'islamic' };
|
|
700
|
+
formatDateTime = { format: culture.getDatePattern({ skeleton: 'yMd' }), type: 'dateTime', calendar: 'islamic' };
|
|
701
|
+
}
|
|
702
|
+
} else {
|
|
703
|
+
if (this.calendarMode === 'Gregorian') {
|
|
704
|
+
formatOptions = { format: this.formatString, type: 'dateTime', skeleton: 'yMd' };
|
|
705
|
+
} else {
|
|
706
|
+
formatOptions = { format: this.formatString, type: 'dateTime', skeleton: 'yMd', calendar: 'islamic' };
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
returnDate = this.checkDateValue(this.globalize.parseDate(this.getAmPmValue(val), formatOptions));
|
|
710
|
+
if (isNullOrUndefined(returnDate) && (this.getModuleName() === 'datetimepicker')) {
|
|
711
|
+
returnDate = this.checkDateValue(this.globalize.parseDate(this.getAmPmValue(val), formatDateTime));
|
|
712
|
+
}
|
|
713
|
+
return returnDate;
|
|
714
|
+
}
|
|
715
|
+
protected checkInvalidValue(value: Date): void {
|
|
716
|
+
if (!(value instanceof Date) && !isNullOrUndefined(value)) {
|
|
717
|
+
let valueDate: Date = null;
|
|
718
|
+
let valueString: string = <string>value;
|
|
719
|
+
if (typeof value === 'number') {
|
|
720
|
+
valueString = (value as string).toString();
|
|
721
|
+
}
|
|
722
|
+
let formatOptions: object = null;
|
|
723
|
+
let formatDateTime: object = null;
|
|
724
|
+
if (this.getModuleName() === 'datetimepicker') {
|
|
725
|
+
const culture: Internationalization = new Internationalization(this.locale);
|
|
726
|
+
if (this.calendarMode === 'Gregorian') {
|
|
727
|
+
formatOptions = { format: this.dateTimeFormat, type: 'dateTime', skeleton: 'yMd' };
|
|
728
|
+
formatDateTime = { format: culture.getDatePattern({ skeleton: 'yMd' }), type: 'dateTime' };
|
|
729
|
+
} else {
|
|
730
|
+
formatOptions = { format: this.dateTimeFormat, type: 'dateTime', skeleton: 'yMd', calendar: 'islamic' };
|
|
731
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
732
|
+
formatDateTime = { format: culture.getDatePattern({ skeleton: 'yMd' }), type: 'dateTime', calendar: 'islamic' };
|
|
733
|
+
}
|
|
734
|
+
} else {
|
|
735
|
+
if (this.calendarMode === 'Gregorian') {
|
|
736
|
+
formatOptions = { format: this.formatString, type: 'dateTime', skeleton: 'yMd' };
|
|
737
|
+
} else {
|
|
738
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
739
|
+
formatOptions = { format: this.formatString, type: 'dateTime', skeleton: 'yMd', calendar: 'islamic' };
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
let invalid: boolean = false;
|
|
743
|
+
if (typeof valueString !== 'string') {
|
|
744
|
+
valueString = null;
|
|
745
|
+
invalid = true;
|
|
746
|
+
} else {
|
|
747
|
+
if (typeof valueString === 'string') {
|
|
748
|
+
valueString = valueString.trim();
|
|
749
|
+
}
|
|
750
|
+
valueDate = this.checkStringValue(valueString);
|
|
751
|
+
if (!valueDate) {
|
|
752
|
+
let extISOString: RegExp = null;
|
|
753
|
+
let basicISOString: RegExp = null;
|
|
754
|
+
// eslint-disable-next-line
|
|
755
|
+
extISOString = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/;
|
|
756
|
+
// eslint-disable-next-line
|
|
757
|
+
basicISOString = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/;
|
|
758
|
+
if ((!extISOString.test(valueString) && !basicISOString.test(valueString))
|
|
759
|
+
|| (/^[a-zA-Z0-9- ]*$/).test(valueString) || isNaN(+new Date(this.checkValue(valueString)))) {
|
|
760
|
+
invalid = true;
|
|
761
|
+
} else {
|
|
762
|
+
valueDate = new Date(valueString);
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
if (invalid) {
|
|
767
|
+
if (!this.strictMode) {
|
|
768
|
+
this.invalidValueString = valueString;
|
|
769
|
+
}
|
|
770
|
+
this.setProperties({ value: null }, true);
|
|
771
|
+
} else {
|
|
772
|
+
this.setProperties({ value: valueDate }, true);
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
private bindInputEvent(): void {
|
|
777
|
+
if (!isNullOrUndefined(this.formatString) || this.enableMask) {
|
|
778
|
+
if (this.enableMask || this.formatString.indexOf('y') === -1) {
|
|
779
|
+
EventHandler.add(this.inputElement, 'input', this.inputHandler, this);
|
|
780
|
+
} else {
|
|
781
|
+
EventHandler.remove(this.inputElement, 'input', this.inputHandler);
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
protected bindEvents(): void {
|
|
786
|
+
EventHandler.add(this.inputWrapper.buttons[0], 'mousedown', this.dateIconHandler, this);
|
|
787
|
+
EventHandler.add(this.inputElement, 'mouseup', this.mouseUpHandler, this);
|
|
788
|
+
EventHandler.add(this.inputElement, 'focus', this.inputFocusHandler, this);
|
|
789
|
+
EventHandler.add(this.inputElement, 'blur', this.inputBlurHandler, this);
|
|
790
|
+
EventHandler.add(this.inputElement, 'keyup', this.keyupHandler, this);
|
|
791
|
+
if (this.enableMask){
|
|
792
|
+
EventHandler.add(this.inputElement, 'keydown', this.keydownHandler, this);
|
|
793
|
+
}
|
|
794
|
+
this.bindInputEvent();
|
|
795
|
+
// To prevent the twice triggering.
|
|
796
|
+
EventHandler.add(this.inputElement, 'change', this.inputChangeHandler, this);
|
|
797
|
+
if (this.showClearButton && this.inputWrapper.clearButton) {
|
|
798
|
+
EventHandler.add(this.inputWrapper.clearButton, 'mousedown touchstart', this.resetHandler, this);
|
|
799
|
+
}
|
|
800
|
+
if (this.formElement) {
|
|
801
|
+
EventHandler.add(this.formElement, 'reset', this.resetFormHandler, this);
|
|
802
|
+
}
|
|
803
|
+
this.defaultKeyConfigs = (extend(this.defaultKeyConfigs, this.keyConfigs) as { [key: string]: string });
|
|
804
|
+
this.keyboardModules = new KeyboardEvents(
|
|
805
|
+
<HTMLElement>this.inputElement,
|
|
806
|
+
{
|
|
807
|
+
eventName: 'keydown',
|
|
808
|
+
keyAction: this.inputKeyActionHandle.bind(this),
|
|
809
|
+
keyConfigs: this.defaultKeyConfigs
|
|
810
|
+
});
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
private keydownHandler(e: KeyboardEventArgs): void{
|
|
814
|
+
switch (e.code)
|
|
815
|
+
{
|
|
816
|
+
case 'ArrowLeft':
|
|
817
|
+
case 'ArrowRight' :
|
|
818
|
+
case 'ArrowUp':
|
|
819
|
+
case 'ArrowDown':
|
|
820
|
+
case 'Home':
|
|
821
|
+
case 'End':
|
|
822
|
+
case 'Backspace':
|
|
823
|
+
case 'Delete':
|
|
824
|
+
if (this.enableMask && !this.popupObj && !this.readonly)
|
|
825
|
+
{
|
|
826
|
+
if (e.code !== 'Delete' && e.code !== 'Backspace')
|
|
827
|
+
{
|
|
828
|
+
e.preventDefault();
|
|
829
|
+
}
|
|
830
|
+
this.notify('keyDownHandler', {
|
|
831
|
+
module: 'MaskedDateTime' ,
|
|
832
|
+
e: e
|
|
833
|
+
});
|
|
834
|
+
}
|
|
835
|
+
break;
|
|
836
|
+
|
|
837
|
+
default:
|
|
838
|
+
break;
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
protected unBindEvents() : void {
|
|
843
|
+
if (!isNullOrUndefined(this.inputWrapper))
|
|
844
|
+
{
|
|
845
|
+
EventHandler.remove(this.inputWrapper.buttons[0], 'mousedown', this.dateIconHandler);
|
|
846
|
+
}
|
|
847
|
+
EventHandler.remove(this.inputElement, 'mouseup', this.mouseUpHandler);
|
|
848
|
+
EventHandler.remove(this.inputElement, 'focus', this.inputFocusHandler);
|
|
849
|
+
EventHandler.remove(this.inputElement, 'blur', this.inputBlurHandler);
|
|
850
|
+
EventHandler.remove(this.inputElement, 'change', this.inputChangeHandler);
|
|
851
|
+
EventHandler.remove(this.inputElement, 'keyup', this.keyupHandler);
|
|
852
|
+
if (this.enableMask){
|
|
853
|
+
EventHandler.remove(this.inputElement, 'keydown', this.keydownHandler);
|
|
854
|
+
}
|
|
855
|
+
if (this.showClearButton && this.inputWrapper.clearButton) {
|
|
856
|
+
EventHandler.remove(this.inputWrapper.clearButton, 'mousedown touchstart', this.resetHandler);
|
|
857
|
+
}
|
|
858
|
+
if (this.formElement) {
|
|
859
|
+
EventHandler.remove(this.formElement, 'reset', this.resetFormHandler);
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
protected resetFormHandler(): void {
|
|
863
|
+
if (!this.enabled) {
|
|
864
|
+
return;
|
|
865
|
+
}
|
|
866
|
+
if (!this.inputElement.disabled) {
|
|
867
|
+
let value: string = this.inputElement.getAttribute('value');
|
|
868
|
+
if (this.element.tagName === 'EJS-DATEPICKER' || this.element.tagName === 'EJS-DATETIMEPICKER') {
|
|
869
|
+
value = '';
|
|
870
|
+
this.inputValueCopy = null;
|
|
871
|
+
this.inputElement.setAttribute('value', '');
|
|
872
|
+
}
|
|
873
|
+
this.setProperties({ value: this.inputValueCopy }, true);
|
|
874
|
+
this.restoreValue();
|
|
875
|
+
if (this.inputElement) {
|
|
876
|
+
this.updateInputValue(value);
|
|
877
|
+
this.errorClass();
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
protected restoreValue(): void {
|
|
882
|
+
this.currentDate = this.value ? this.value : new Date();
|
|
883
|
+
this.previousDate = this.value;
|
|
884
|
+
this.previousElementValue = (isNullOrUndefined(this.inputValueCopy)) ? '' :
|
|
885
|
+
this.globalize.formatDate(this.inputValueCopy, {
|
|
886
|
+
format: this.formatString, type: 'dateTime', skeleton: 'yMd'
|
|
887
|
+
});
|
|
888
|
+
}
|
|
889
|
+
private inputChangeHandler(e: MouseEvent): void {
|
|
890
|
+
if (!this.enabled) {
|
|
891
|
+
return;
|
|
892
|
+
}
|
|
893
|
+
e.stopPropagation();
|
|
894
|
+
}
|
|
895
|
+
private bindClearEvent(): void {
|
|
896
|
+
if (this.showClearButton && this.inputWrapper.clearButton) {
|
|
897
|
+
EventHandler.add(this.inputWrapper.clearButton, 'mousedown touchstart', this.resetHandler, this);
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
protected resetHandler(e?: MouseEvent): void {
|
|
901
|
+
if (!this.enabled) {
|
|
902
|
+
return;
|
|
903
|
+
}
|
|
904
|
+
e.preventDefault();
|
|
905
|
+
this.clear(e);
|
|
906
|
+
}
|
|
907
|
+
private mouseUpHandler(e? : MouseEvent): void{
|
|
908
|
+
if (this.enableMask)
|
|
909
|
+
{
|
|
910
|
+
e.preventDefault();
|
|
911
|
+
this.notify('setMaskSelection', {
|
|
912
|
+
module: 'MaskedDateTime'
|
|
913
|
+
});
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
private clear(event: MouseEvent): void {
|
|
917
|
+
this.setProperties({ value: null }, true);
|
|
918
|
+
if (!this.enableMask)
|
|
919
|
+
{
|
|
920
|
+
this.updateInputValue('');
|
|
921
|
+
}
|
|
922
|
+
const clearedArgs: ClearedEventArgs = {
|
|
923
|
+
event: event
|
|
924
|
+
};
|
|
925
|
+
this.trigger('cleared', clearedArgs);
|
|
926
|
+
this.invalidValueString = '';
|
|
927
|
+
this.updateInput();
|
|
928
|
+
this.popupUpdate();
|
|
929
|
+
this.changeEvent(event);
|
|
930
|
+
if (this.enableMask)
|
|
931
|
+
{
|
|
932
|
+
this.notify('clearHandler', {
|
|
933
|
+
module: 'MaskedDateTime'
|
|
934
|
+
});
|
|
935
|
+
}
|
|
936
|
+
if (closest(this.element, 'form')) {
|
|
937
|
+
const element: Element = this.element;
|
|
938
|
+
const keyupEvent: KeyboardEvent = document.createEvent('KeyboardEvent');
|
|
939
|
+
keyupEvent.initEvent('keyup', false, true);
|
|
940
|
+
element.dispatchEvent(keyupEvent);
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
|
|
945
|
+
private preventEventBubbling(e?: MouseEvent): void {
|
|
946
|
+
e.preventDefault();
|
|
947
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
948
|
+
(this as any).interopAdaptor.invokeMethodAsync('OnDateIconClick');
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
private updateInputValue(value?: string): void {
|
|
952
|
+
Input.setValue(value, this.inputElement, this.floatLabelType, this.showClearButton);
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
private dateIconHandler(e?: MouseEvent): void {
|
|
956
|
+
if (!this.enabled) {
|
|
957
|
+
return;
|
|
958
|
+
}
|
|
959
|
+
this.isIconClicked = true;
|
|
960
|
+
if (Browser.isDevice) {
|
|
961
|
+
this.inputElement.setAttribute('readonly', '');
|
|
962
|
+
this.inputElement.blur();
|
|
963
|
+
}
|
|
964
|
+
e.preventDefault();
|
|
965
|
+
if (!this.readonly) {
|
|
966
|
+
if (this.isCalendar()) {
|
|
967
|
+
this.hide(e);
|
|
968
|
+
} else {
|
|
969
|
+
this.isDateIconClicked = true;
|
|
970
|
+
this.show(null, e);
|
|
971
|
+
if (this.getModuleName() === 'datetimepicker') {
|
|
972
|
+
(this.inputElement as HTMLElement).focus();
|
|
973
|
+
}
|
|
974
|
+
(<HTMLElement>this.inputElement).focus();
|
|
975
|
+
addClass([this.inputWrapper.container], [INPUTFOCUS]);
|
|
976
|
+
addClass(this.inputWrapper.buttons, ACTIVE);
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
this.isIconClicked = false;
|
|
980
|
+
}
|
|
981
|
+
protected updateHtmlAttributeToWrapper(): void {
|
|
982
|
+
if (!isNullOrUndefined(this.htmlAttributes)) {
|
|
983
|
+
for (const key of Object.keys(this.htmlAttributes)) {
|
|
984
|
+
if (!isNullOrUndefined(this.htmlAttributes[`${key}`])) {
|
|
985
|
+
if (containerAttr.indexOf(key) > -1) {
|
|
986
|
+
if (key === 'class') {
|
|
987
|
+
const updatedClassValues : string = (this.htmlAttributes[`${key}`].replace(/\s+/g, ' ')).trim();
|
|
988
|
+
if (updatedClassValues !== '') {
|
|
989
|
+
addClass([this.inputWrapper.container], updatedClassValues.split(' '));
|
|
990
|
+
}
|
|
991
|
+
} else if (key === 'style') {
|
|
992
|
+
let setStyle: string = this.inputWrapper.container.getAttribute(key);
|
|
993
|
+
if (!isNullOrUndefined(setStyle)) {
|
|
994
|
+
if (setStyle.charAt(setStyle.length - 1) === ';') {
|
|
995
|
+
setStyle = setStyle + this.htmlAttributes[`${key}`];
|
|
996
|
+
} else {
|
|
997
|
+
setStyle = setStyle + ';' + this.htmlAttributes[`${key}`];
|
|
998
|
+
}
|
|
999
|
+
} else {
|
|
1000
|
+
setStyle = this.htmlAttributes[`${key}`];
|
|
1001
|
+
}
|
|
1002
|
+
this.inputWrapper.container.setAttribute(key, setStyle);
|
|
1003
|
+
} else {
|
|
1004
|
+
this.inputWrapper.container.setAttribute(key, this.htmlAttributes[`${key}`]);
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
protected updateHtmlAttributeToElement(): void {
|
|
1013
|
+
if ( !isNullOrUndefined(this.htmlAttributes)) {
|
|
1014
|
+
for (const key of Object.keys(this.htmlAttributes)) {
|
|
1015
|
+
if (containerAttr.indexOf(key) < 0 ) {
|
|
1016
|
+
this.inputElement.setAttribute(key, this.htmlAttributes[`${key}`]);
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
private updateCssClass(newCssClass : string, oldCssClass : string) : void {
|
|
1022
|
+
if (!isNullOrUndefined(oldCssClass)) {
|
|
1023
|
+
oldCssClass = (oldCssClass.replace(/\s+/g, ' ')).trim();
|
|
1024
|
+
}
|
|
1025
|
+
if (!isNullOrUndefined(newCssClass)) {
|
|
1026
|
+
newCssClass = (newCssClass.replace(/\s+/g, ' ')).trim();
|
|
1027
|
+
}
|
|
1028
|
+
Input.setCssClass(newCssClass, [this.inputWrapper.container], oldCssClass);
|
|
1029
|
+
if (this.popupWrapper) {
|
|
1030
|
+
Input.setCssClass(newCssClass, [this.popupWrapper], oldCssClass);
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
private calendarKeyActionHandle(e: KeyboardEventArgs): void {
|
|
1034
|
+
switch (e.action) {
|
|
1035
|
+
case 'escape':
|
|
1036
|
+
if (this.isCalendar()) {
|
|
1037
|
+
this.hide(e);
|
|
1038
|
+
} else {
|
|
1039
|
+
(this.inputWrapper.container.children[this.index] as HTMLElement).blur();
|
|
1040
|
+
}
|
|
1041
|
+
break;
|
|
1042
|
+
case 'enter':
|
|
1043
|
+
if (!this.isCalendar()) {
|
|
1044
|
+
this.show(null, e);
|
|
1045
|
+
} else {
|
|
1046
|
+
if (+this.value !== +this.currentDate && !this.isCalendar()) {
|
|
1047
|
+
(this.inputWrapper.container.children[this.index] as HTMLElement).focus();
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
if (this.getModuleName() === 'datetimepicker') {
|
|
1051
|
+
this.inputElement.focus();
|
|
1052
|
+
}
|
|
1053
|
+
break;
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
private inputFocusHandler(): void {
|
|
1057
|
+
this.isFocused = true;
|
|
1058
|
+
if (!this.enabled) {
|
|
1059
|
+
return;
|
|
1060
|
+
}
|
|
1061
|
+
if (this.enableMask && !this.inputElement.value && this.placeholder)
|
|
1062
|
+
{
|
|
1063
|
+
if (this.maskedDateValue && !this.value && (this.floatLabelType === 'Auto' || this.floatLabelType === 'Never' || this.placeholder))
|
|
1064
|
+
{
|
|
1065
|
+
this.updateInputValue(this.maskedDateValue);
|
|
1066
|
+
this.inputElement.selectionStart = 0;
|
|
1067
|
+
this.inputElement.selectionEnd = this.inputElement.value.length;
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
if (this.enableMask && this.showClearButton && this.inputElement && this.inputElement.value === this.maskedDateValue && this.inputWrapper && this.inputWrapper.clearButton && !this.inputWrapper.clearButton.classList.contains('e-clear-icon-hide')) {
|
|
1071
|
+
this.inputWrapper.clearButton.classList.add('e-clear-icon-hide');
|
|
1072
|
+
}
|
|
1073
|
+
const focusArguments: BlurEventArgs = {
|
|
1074
|
+
model: this
|
|
1075
|
+
};
|
|
1076
|
+
this.isDateIconClicked = false;
|
|
1077
|
+
this.trigger('focus', focusArguments);
|
|
1078
|
+
this.updateIconState();
|
|
1079
|
+
if (this.openOnFocus && !this.isIconClicked) {
|
|
1080
|
+
this.show();
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
private inputHandler(e?: any): void {
|
|
1084
|
+
this.isPopupClicked = false;
|
|
1085
|
+
if (this.enableMask)
|
|
1086
|
+
{
|
|
1087
|
+
if (!isNullOrUndefined(e) && !isNullOrUndefined(e.inputType) && e.inputType === 'insertFromPaste') {
|
|
1088
|
+
this.notify('maskPasteInputHandler', {
|
|
1089
|
+
module: 'MaskedDateTime'
|
|
1090
|
+
});
|
|
1091
|
+
}
|
|
1092
|
+
else {
|
|
1093
|
+
this.notify('inputHandler', {
|
|
1094
|
+
module: 'MaskedDateTime'
|
|
1095
|
+
});
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
private inputBlurHandler(e: MouseEvent): void {
|
|
1100
|
+
if (!this.enabled) {
|
|
1101
|
+
return;
|
|
1102
|
+
}
|
|
1103
|
+
this.strictModeUpdate();
|
|
1104
|
+
if (this.inputElement.value === '' && isNullOrUndefined(this.value)) {
|
|
1105
|
+
this.invalidValueString = null;
|
|
1106
|
+
this.updateInputValue('');
|
|
1107
|
+
}
|
|
1108
|
+
this.isBlur = true;
|
|
1109
|
+
this.updateInput(false, true);
|
|
1110
|
+
this.isBlur = false;
|
|
1111
|
+
this.popupUpdate();
|
|
1112
|
+
this.changeTrigger(e);
|
|
1113
|
+
if (this.enableMask && this.maskedDateValue && this.placeholder && this.floatLabelType !== 'Always' )
|
|
1114
|
+
{
|
|
1115
|
+
if (this.inputElement.value === this.maskedDateValue && !this.value && (this.floatLabelType === 'Auto' || this.floatLabelType === 'Never' || this.placeholder))
|
|
1116
|
+
{
|
|
1117
|
+
this.updateInputValue('');
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
this.errorClass();
|
|
1121
|
+
if (this.isCalendar() && document.activeElement === this.inputElement) {
|
|
1122
|
+
this.hide(e);
|
|
1123
|
+
}
|
|
1124
|
+
if (this.getModuleName() === 'datepicker') {
|
|
1125
|
+
const blurArguments: BlurEventArgs = {
|
|
1126
|
+
model: this
|
|
1127
|
+
};
|
|
1128
|
+
this.trigger('blur', blurArguments);
|
|
1129
|
+
}
|
|
1130
|
+
if (this.isCalendar()) {
|
|
1131
|
+
this.defaultKeyConfigs = (extend(this.defaultKeyConfigs, this.keyConfigs) as { [key: string]: string });
|
|
1132
|
+
this.calendarKeyboardModules = new KeyboardEvents(<HTMLElement>this.calendarElement.children[1].firstElementChild, {
|
|
1133
|
+
eventName: 'keydown',
|
|
1134
|
+
keyAction: this.calendarKeyActionHandle.bind(this),
|
|
1135
|
+
keyConfigs: this.defaultKeyConfigs
|
|
1136
|
+
});
|
|
1137
|
+
}
|
|
1138
|
+
this.isPopupClicked = false;
|
|
1139
|
+
}
|
|
1140
|
+
private documentHandler(e: MouseEvent): void {
|
|
1141
|
+
if ((!isNullOrUndefined(this.popupObj) && !isNullOrUndefined(this.inputWrapper) && (this.inputWrapper.container.contains(<HTMLElement>e.target) && e.type !== 'mousedown' ||
|
|
1142
|
+
(this.popupObj.element && this.popupObj.element.contains(<HTMLElement>e.target)))) && e.type !== 'touchstart') {
|
|
1143
|
+
e.preventDefault();
|
|
1144
|
+
}
|
|
1145
|
+
const target: HTMLElement = <HTMLElement>e.target;
|
|
1146
|
+
if (!(closest(target, '.e-datepicker.e-popup-wrapper')) && !isNullOrUndefined(this.inputWrapper)
|
|
1147
|
+
&& !(closest(target, '.' + INPUTCONTAINER) === this.inputWrapper.container)
|
|
1148
|
+
&& (!target.classList.contains('e-day'))) {
|
|
1149
|
+
this.hide(e);
|
|
1150
|
+
if (target.classList.contains('e-dlg-overlay')) {
|
|
1151
|
+
e.preventDefault();
|
|
1152
|
+
} else {
|
|
1153
|
+
this.focusOut();
|
|
1154
|
+
}
|
|
1155
|
+
} else if (closest(target, '.e-datepicker.e-popup-wrapper')) {
|
|
1156
|
+
// Fix for close the popup when select the previously selected value.
|
|
1157
|
+
if ( target.classList.contains('e-day')
|
|
1158
|
+
&& !isNullOrUndefined((e.target as HTMLElement).parentElement)
|
|
1159
|
+
&& (e.target as HTMLElement).parentElement.classList.contains('e-selected')
|
|
1160
|
+
&& closest(target, '.e-content')
|
|
1161
|
+
&& closest(target, '.e-content').classList.contains('e-' + this.depth.toLowerCase())) {
|
|
1162
|
+
this.hide(e);
|
|
1163
|
+
} else if (closest(target, '.e-footer-container')
|
|
1164
|
+
&& target.classList.contains('e-today')
|
|
1165
|
+
&& target.classList.contains('e-btn')
|
|
1166
|
+
&& (+new Date(+this.value) === +super.generateTodayVal(this.value))) {
|
|
1167
|
+
this.hide(e);
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
protected inputKeyActionHandle(e: KeyboardEventArgs): void {
|
|
1173
|
+
const clickedView: string = this.currentView();
|
|
1174
|
+
switch (e.action) {
|
|
1175
|
+
case 'altUpArrow':
|
|
1176
|
+
this.isAltKeyPressed = false;
|
|
1177
|
+
this.hide(e);
|
|
1178
|
+
this.inputElement.focus();
|
|
1179
|
+
break;
|
|
1180
|
+
case 'altDownArrow':
|
|
1181
|
+
this.isAltKeyPressed = true;
|
|
1182
|
+
this.strictModeUpdate();
|
|
1183
|
+
this.updateInput();
|
|
1184
|
+
this.changeTrigger(e);
|
|
1185
|
+
if (this.getModuleName() === 'datepicker') {
|
|
1186
|
+
this.show(null, e);
|
|
1187
|
+
}
|
|
1188
|
+
break;
|
|
1189
|
+
case 'escape':
|
|
1190
|
+
this.hide(e);
|
|
1191
|
+
break;
|
|
1192
|
+
case 'enter':
|
|
1193
|
+
this.strictModeUpdate();
|
|
1194
|
+
this.updateInput();
|
|
1195
|
+
this.popupUpdate();
|
|
1196
|
+
this.changeTrigger(e);
|
|
1197
|
+
this.errorClass();
|
|
1198
|
+
if (!this.isCalendar() && document.activeElement === this.inputElement) {
|
|
1199
|
+
this.hide(e);
|
|
1200
|
+
}
|
|
1201
|
+
if (this.isCalendar()) {
|
|
1202
|
+
e.preventDefault();
|
|
1203
|
+
e.stopPropagation();
|
|
1204
|
+
}
|
|
1205
|
+
break;
|
|
1206
|
+
case 'tab':
|
|
1207
|
+
case 'shiftTab':
|
|
1208
|
+
{
|
|
1209
|
+
let start: number = this.inputElement.selectionStart;
|
|
1210
|
+
let end: number = this.inputElement.selectionEnd;
|
|
1211
|
+
if (this.enableMask && !this.popupObj && !this.readonly)
|
|
1212
|
+
{
|
|
1213
|
+
const length: number = this.inputElement.value.length;
|
|
1214
|
+
if ((start === 0 && end === length) || (end !== length && e.action === 'tab') || (start !== 0 && e.action === 'shiftTab'))
|
|
1215
|
+
{
|
|
1216
|
+
e.preventDefault();
|
|
1217
|
+
}
|
|
1218
|
+
this.notify('keyDownHandler', {
|
|
1219
|
+
module: 'MaskedDateTime' ,
|
|
1220
|
+
e: e
|
|
1221
|
+
});
|
|
1222
|
+
start = this.inputElement.selectionStart;
|
|
1223
|
+
end = this.inputElement.selectionEnd;
|
|
1224
|
+
}
|
|
1225
|
+
this.strictModeUpdate();
|
|
1226
|
+
this.updateInput();
|
|
1227
|
+
this.popupUpdate();
|
|
1228
|
+
this.changeTrigger(e);
|
|
1229
|
+
this.errorClass();
|
|
1230
|
+
if (this.enableMask)
|
|
1231
|
+
{
|
|
1232
|
+
this.inputElement.selectionStart = start ;
|
|
1233
|
+
this.inputElement.selectionEnd = end;
|
|
1234
|
+
}
|
|
1235
|
+
if (e.action === 'tab' && e.target === this.inputElement && this.isCalendar() && document.activeElement === this.inputElement) {
|
|
1236
|
+
e.preventDefault();
|
|
1237
|
+
this.headerTitleElement.focus();
|
|
1238
|
+
}
|
|
1239
|
+
if (e.action === 'shiftTab' && e.target === this.inputElement && this.isCalendar() && document.activeElement === this.inputElement) {
|
|
1240
|
+
this.hide(e);
|
|
1241
|
+
}
|
|
1242
|
+
break;
|
|
1243
|
+
}
|
|
1244
|
+
default:
|
|
1245
|
+
this.defaultAction(e);
|
|
1246
|
+
// Fix for close the popup when select the previously selected value.
|
|
1247
|
+
if (e.action === 'select' && clickedView === this.depth) {
|
|
1248
|
+
this.hide(e);
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
protected defaultAction(e: KeyboardEventArgs): void {
|
|
1253
|
+
this.previousDate = ((!isNullOrUndefined(this.value) && new Date(+this.value)) || null);
|
|
1254
|
+
if (this.isCalendar()) {
|
|
1255
|
+
super.keyActionHandle(e);
|
|
1256
|
+
if (this.isCalendar()) {
|
|
1257
|
+
attributes(this.inputElement, {
|
|
1258
|
+
'aria-activedescendant': '' + this.setActiveDescendant()
|
|
1259
|
+
});
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
protected popupUpdate(): void {
|
|
1264
|
+
if ((isNullOrUndefined(this.value)) && (!isNullOrUndefined(this.previousDate)) ||
|
|
1265
|
+
(((this.getModuleName() !== 'datetimepicker') && (+this.value !== +this.previousDate)) || ((this.getModuleName() === 'datetimepicker') && (+this.value !== +this.previousDateTime)))) {
|
|
1266
|
+
if (this.popupObj) {
|
|
1267
|
+
if (this.popupObj.element.querySelectorAll('.' + SELECTED).length > 0) {
|
|
1268
|
+
removeClass(this.popupObj.element.querySelectorAll('.' + SELECTED), [SELECTED]);
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
if (!isNullOrUndefined(this.value)) {
|
|
1272
|
+
if ((+this.value >= +this.min) && (+this.value <= +this.max)) {
|
|
1273
|
+
const targetdate: Date = new Date(this.checkValue(this.value));
|
|
1274
|
+
super.navigateTo('Month', targetdate);
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
protected strictModeUpdate(): void {
|
|
1280
|
+
let format: string;
|
|
1281
|
+
const pattern: RegExp = /^y/ ;
|
|
1282
|
+
const charPattern: RegExp = /[^a-zA-Z]/;
|
|
1283
|
+
let formatOptions: DateFormatOptions;
|
|
1284
|
+
if (this.getModuleName() === 'datetimepicker') {
|
|
1285
|
+
format = !isNullOrUndefined(this.formatString) ? this.formatString : this.dateTimeFormat;
|
|
1286
|
+
} else if (!pattern.test(this.formatString) || charPattern.test(this.formatString)) {
|
|
1287
|
+
format = isNullOrUndefined(this.formatString) ? this.formatString : this.formatString.replace('dd', 'd');
|
|
1288
|
+
}
|
|
1289
|
+
if (!isNullOrUndefined(format)) {
|
|
1290
|
+
const len: number = format.split('M').length - 1;
|
|
1291
|
+
if (len < 3) {
|
|
1292
|
+
format = format.replace('MM', 'M');
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
else {
|
|
1296
|
+
format = this.formatString;
|
|
1297
|
+
}
|
|
1298
|
+
let dateOptions: object;
|
|
1299
|
+
if (this.getModuleName() === 'datetimepicker') {
|
|
1300
|
+
if (this.calendarMode === 'Gregorian') {
|
|
1301
|
+
dateOptions = {
|
|
1302
|
+
format: !isNullOrUndefined(this.formatString) ? this.formatString : this.dateTimeFormat,
|
|
1303
|
+
type: 'dateTime', skeleton: 'yMd'
|
|
1304
|
+
};
|
|
1305
|
+
} else {
|
|
1306
|
+
dateOptions = {
|
|
1307
|
+
format: !isNullOrUndefined(this.formatString) ? this.formatString : this.dateTimeFormat,
|
|
1308
|
+
type: 'dateTime', skeleton: 'yMd', calendar: 'islamic'
|
|
1309
|
+
};
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1312
|
+
} else {
|
|
1313
|
+
if (this.calendarMode === 'Gregorian') {
|
|
1314
|
+
formatOptions = { format: format, type: 'dateTime', skeleton: 'yMd' };
|
|
1315
|
+
} else {
|
|
1316
|
+
formatOptions = { format: format, type: 'dateTime', skeleton: 'yMd', calendar: 'islamic' };
|
|
1317
|
+
}
|
|
1318
|
+
dateOptions = formatOptions;
|
|
1319
|
+
}
|
|
1320
|
+
let date: Date;
|
|
1321
|
+
if (typeof this.inputElement.value === 'string') {
|
|
1322
|
+
this.inputElement.value = this.inputElement.value.trim();
|
|
1323
|
+
}
|
|
1324
|
+
if ((this.getModuleName() === 'datetimepicker')) {
|
|
1325
|
+
if (this.checkDateValue(this.globalize.parseDate(this.getAmPmValue(this.inputElement.value), dateOptions))) {
|
|
1326
|
+
date = this.globalize.parseDate(this.getAmPmValue(this.inputElement.value), dateOptions);
|
|
1327
|
+
} else {
|
|
1328
|
+
if (this.calendarMode === 'Gregorian') {
|
|
1329
|
+
formatOptions = { format: format, type: 'dateTime', skeleton: 'yMd' };
|
|
1330
|
+
} else {
|
|
1331
|
+
formatOptions = { format: format, type: 'dateTime', skeleton: 'yMd', calendar: 'islamic' };
|
|
1332
|
+
}
|
|
1333
|
+
date = this.globalize.parseDate(this.getAmPmValue(this.inputElement.value), formatOptions);
|
|
1334
|
+
}
|
|
1335
|
+
if ((isNullOrUndefined(date) || (typeof (date) === 'object' && isNaN(date.getTime())))
|
|
1336
|
+
&& !isNullOrUndefined(this.inputFormatsString)) {
|
|
1337
|
+
for (const format of this.inputFormatsString) {
|
|
1338
|
+
let inputFormatOptions: DateFormatOptions;
|
|
1339
|
+
if (this.calendarMode === 'Gregorian') {
|
|
1340
|
+
inputFormatOptions = { format: format, type: 'dateTime', skeleton: 'yMd' };
|
|
1341
|
+
} else {
|
|
1342
|
+
inputFormatOptions = { format: format, type: 'dateTime', skeleton: 'yMd', calendar: 'islamic' };
|
|
1343
|
+
}
|
|
1344
|
+
date = this.globalize.parseDate(this.getAmPmValue(this.inputElement.value), inputFormatOptions);
|
|
1345
|
+
if (!isNullOrUndefined(date) && date instanceof Date && !isNaN(date.getTime())) {
|
|
1346
|
+
break;
|
|
1347
|
+
}
|
|
1348
|
+
}
|
|
1349
|
+
}
|
|
1350
|
+
} else {
|
|
1351
|
+
date = this.globalize.parseDate(this.getAmPmValue(this.inputElement.value), dateOptions);
|
|
1352
|
+
if ((isNullOrUndefined(date) || (typeof (date) === 'object' && isNaN(date.getTime())))
|
|
1353
|
+
&& !isNullOrUndefined(this.inputFormatsString)) {
|
|
1354
|
+
for (const format of this.inputFormatsString) {
|
|
1355
|
+
let inputFormatOptions: DateFormatOptions;
|
|
1356
|
+
if (this.calendarMode === 'Gregorian') {
|
|
1357
|
+
inputFormatOptions = { format: format, type: 'dateTime', skeleton: 'yMd' };
|
|
1358
|
+
} else {
|
|
1359
|
+
inputFormatOptions = { format: format, type: 'dateTime', skeleton: 'yMd', calendar: 'islamic' };
|
|
1360
|
+
}
|
|
1361
|
+
date = this.globalize.parseDate(this.getAmPmValue(this.inputElement.value), inputFormatOptions);
|
|
1362
|
+
if (!isNullOrUndefined(date) && date instanceof Date && !isNaN(date.getTime())) {
|
|
1363
|
+
break;
|
|
1364
|
+
}
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
date = (!isNullOrUndefined(date) && isNaN(+date)) ? null : date;
|
|
1368
|
+
if (!isNullOrUndefined(this.formatString) && this.inputElement.value !== '' && this.strictMode) {
|
|
1369
|
+
if ((this.isPopupClicked || (!this.isPopupClicked && this.inputElement.value === this.previousElementValue))
|
|
1370
|
+
&& this.formatString.indexOf('y') === -1) {
|
|
1371
|
+
date.setFullYear(this.value.getFullYear());
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1375
|
+
// EJ2-35061 - To prevent change event from triggering twice when using strictmode and format property
|
|
1376
|
+
if ((this.getModuleName() === 'datepicker') && (this.value && !isNaN(+this.value)) && date) {
|
|
1377
|
+
date.setHours(this.value.getHours(), this.value.getMinutes(), this.value.getSeconds(), this.value.getMilliseconds());
|
|
1378
|
+
}
|
|
1379
|
+
if (this.strictMode && date) {
|
|
1380
|
+
this.updateInputValue(this.globalize.formatDate(date, dateOptions));
|
|
1381
|
+
if (this.inputElement.value !== this.previousElementValue) {
|
|
1382
|
+
this.setProperties({ value: date }, true);
|
|
1383
|
+
}
|
|
1384
|
+
} else if (!this.strictMode) {
|
|
1385
|
+
if (this.inputElement.value !== this.previousElementValue) {
|
|
1386
|
+
this.setProperties({ value: date }, true);
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
if (this.strictMode && !date && this.inputElement.value === (this.enableMask ? this.maskedDateValue : '')) {
|
|
1390
|
+
this.setProperties({ value: null }, true);
|
|
1391
|
+
}
|
|
1392
|
+
if (isNaN(+this.value)) {
|
|
1393
|
+
this.setProperties({ value: null }, true);
|
|
1394
|
+
}
|
|
1395
|
+
if (isNullOrUndefined(this.value)) {
|
|
1396
|
+
this.currentDate = new Date(new Date().setHours(0, 0, 0, 0));
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
private createCalendar(): void {
|
|
1400
|
+
this.popupWrapper = this.createElement('div', { className: '' + ROOT + ' ' + POPUPWRAPPER, id: this.inputElement.id + '_options' });
|
|
1401
|
+
this.popupWrapper.setAttribute( 'aria-label', this.element.id );
|
|
1402
|
+
this.popupWrapper.setAttribute( 'role', 'dialog' );
|
|
1403
|
+
if (!isNullOrUndefined(this.cssClass)) {
|
|
1404
|
+
this.popupWrapper.className += ' ' + this.cssClass;
|
|
1405
|
+
}
|
|
1406
|
+
if (Browser.isDevice) {
|
|
1407
|
+
this.modelHeader();
|
|
1408
|
+
this.modal = this.createElement('div');
|
|
1409
|
+
this.modal.className = '' + ROOT + ' e-date-modal';
|
|
1410
|
+
document.body.className += ' ' + OVERFLOW;
|
|
1411
|
+
this.modal.style.display = 'block';
|
|
1412
|
+
document.body.appendChild(this.modal);
|
|
1413
|
+
}
|
|
1414
|
+
//this.calendarElement represent the Calendar object from the Calendar class.
|
|
1415
|
+
this.calendarElement.querySelector('table tbody').className = '';
|
|
1416
|
+
this.popupObj = new Popup(this.popupWrapper as HTMLElement, {
|
|
1417
|
+
content: this.calendarElement,
|
|
1418
|
+
relateTo: Browser.isDevice ? document.body : this.inputWrapper.container,
|
|
1419
|
+
position: Browser.isDevice ? { X: 'center', Y: 'center' } : (this.enableRtl ? { X: 'right', Y: 'bottom' } : { X: 'left', Y: 'bottom' }),
|
|
1420
|
+
offsetY: OFFSETVALUE,
|
|
1421
|
+
targetType: 'container',
|
|
1422
|
+
enableRtl: this.enableRtl,
|
|
1423
|
+
zIndex: this.zIndex,
|
|
1424
|
+
collision: Browser.isDevice ? { X: 'fit', Y: 'fit' } : (this.enableRtl ? { X: 'fit', Y: 'flip' } : { X: 'flip', Y: 'flip' }),
|
|
1425
|
+
open: () => {
|
|
1426
|
+
if (Browser.isDevice && this.fullScreenMode) {
|
|
1427
|
+
this.iconRight = parseInt(window.getComputedStyle(this.calendarElement.querySelector('.e-header.e-month .e-prev')).marginRight, 10) > 16 ? true : false;
|
|
1428
|
+
this.touchModule = new Touch(<HTMLElement>this.calendarElement.querySelector('.e-content.e-month'), {
|
|
1429
|
+
swipe: this.CalendarSwipeHandler.bind(this)
|
|
1430
|
+
});
|
|
1431
|
+
EventHandler.add(<HTMLElement>this.calendarElement.querySelector('.e-content.e-month'), 'touchstart', this.TouchStartHandler, this);
|
|
1432
|
+
}
|
|
1433
|
+
if (this.getModuleName() !== 'datetimepicker') {
|
|
1434
|
+
if (document.activeElement !== this.inputElement) {
|
|
1435
|
+
this.defaultKeyConfigs = (extend(this.defaultKeyConfigs, this.keyConfigs) as { [key: string]: string });
|
|
1436
|
+
(<HTMLElement>this.calendarElement.children[1].firstElementChild).focus();
|
|
1437
|
+
this.calendarKeyboardModules = new KeyboardEvents(
|
|
1438
|
+
<HTMLElement>this.calendarElement.children[1].firstElementChild,
|
|
1439
|
+
{
|
|
1440
|
+
eventName: 'keydown',
|
|
1441
|
+
keyAction: this.calendarKeyActionHandle.bind(this),
|
|
1442
|
+
keyConfigs: this.defaultKeyConfigs
|
|
1443
|
+
});
|
|
1444
|
+
this.calendarKeyboardModules = new KeyboardEvents(
|
|
1445
|
+
<HTMLElement>this.inputWrapper.container.children[this.index],
|
|
1446
|
+
{
|
|
1447
|
+
eventName: 'keydown',
|
|
1448
|
+
keyAction: this.calendarKeyActionHandle.bind(this),
|
|
1449
|
+
keyConfigs: this.defaultKeyConfigs
|
|
1450
|
+
});
|
|
1451
|
+
}
|
|
1452
|
+
}
|
|
1453
|
+
}, close: () => {
|
|
1454
|
+
if (this.isDateIconClicked) {
|
|
1455
|
+
(this.inputWrapper.container.children[this.index] as HTMLElement).focus();
|
|
1456
|
+
}
|
|
1457
|
+
if (this.value) {
|
|
1458
|
+
this.disabledDates();
|
|
1459
|
+
}
|
|
1460
|
+
if (this.popupObj) {
|
|
1461
|
+
this.popupObj.destroy();
|
|
1462
|
+
}
|
|
1463
|
+
this.resetCalendar();
|
|
1464
|
+
detach(this.popupWrapper);
|
|
1465
|
+
this.popupObj = this.popupWrapper = null;
|
|
1466
|
+
this.preventArgs = null;
|
|
1467
|
+
this.calendarKeyboardModules = null;
|
|
1468
|
+
this.setAriaAttributes();
|
|
1469
|
+
}, targetExitViewport: () => {
|
|
1470
|
+
if (!Browser.isDevice) {
|
|
1471
|
+
this.hide();
|
|
1472
|
+
}
|
|
1473
|
+
}
|
|
1474
|
+
});
|
|
1475
|
+
this.popupObj.element.className += ' ' + this.cssClass;
|
|
1476
|
+
this.setAriaAttributes();
|
|
1477
|
+
}
|
|
1478
|
+
|
|
1479
|
+
protected getAmPmValue(date: string | null | undefined): string {
|
|
1480
|
+
try {
|
|
1481
|
+
if (typeof date === 'string' && date.trim() !== '') {
|
|
1482
|
+
// Replace am/pm variants with uppercase AM/PM
|
|
1483
|
+
return date.replace(/(am|pm|Am|aM|pM|Pm)/g, (match: string) => match.toLocaleUpperCase());
|
|
1484
|
+
}
|
|
1485
|
+
// If date is null, undefined, or an empty string, return a default value or empty string
|
|
1486
|
+
return '';
|
|
1487
|
+
} catch (error) {
|
|
1488
|
+
console.error('Error occurred while processing date:', error);
|
|
1489
|
+
return ''; // Return a default value in case of an error
|
|
1490
|
+
}
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1493
|
+
private CalendarSwipeHandler(e: SwipeEventArgs): void {
|
|
1494
|
+
let direction: number = 0;
|
|
1495
|
+
if (this.iconRight) {
|
|
1496
|
+
switch (e.swipeDirection) {
|
|
1497
|
+
case 'Left':
|
|
1498
|
+
direction = 1;
|
|
1499
|
+
break;
|
|
1500
|
+
case 'Right':
|
|
1501
|
+
direction = -1;
|
|
1502
|
+
break;
|
|
1503
|
+
default:
|
|
1504
|
+
break;
|
|
1505
|
+
}
|
|
1506
|
+
} else {
|
|
1507
|
+
switch (e.swipeDirection) {
|
|
1508
|
+
case 'Up':
|
|
1509
|
+
direction = 1;
|
|
1510
|
+
break;
|
|
1511
|
+
case 'Down':
|
|
1512
|
+
direction = -1;
|
|
1513
|
+
break;
|
|
1514
|
+
default:
|
|
1515
|
+
break;
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1518
|
+
if (this.touchStart) {
|
|
1519
|
+
if (direction === 1) {
|
|
1520
|
+
this.navigateNext(e);
|
|
1521
|
+
} else if (direction === -1) {
|
|
1522
|
+
this.navigatePrevious(e);
|
|
1523
|
+
}
|
|
1524
|
+
this.touchStart = false;
|
|
1525
|
+
}
|
|
1526
|
+
}
|
|
1527
|
+
|
|
1528
|
+
private TouchStartHandler(e: MouseEvent): void {
|
|
1529
|
+
this.touchStart = true;
|
|
1530
|
+
}
|
|
1531
|
+
|
|
1532
|
+
private setAriaDisabled(): void {
|
|
1533
|
+
if (!this.enabled) {
|
|
1534
|
+
this.inputElement.setAttribute('aria-disabled', 'true');
|
|
1535
|
+
this.inputElement.tabIndex = -1;
|
|
1536
|
+
} else {
|
|
1537
|
+
this.inputElement.setAttribute('aria-disabled', 'false');
|
|
1538
|
+
this.inputElement.setAttribute('tabindex', this.tabIndex);
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1541
|
+
private modelHeader(): void {
|
|
1542
|
+
let dateOptions: DateFormatOptions;
|
|
1543
|
+
const modelHeader: HTMLElement = this.createElement('div', { className: 'e-model-header' });
|
|
1544
|
+
const yearHeading: HTMLElement = this.createElement('h1', { className: 'e-model-year' });
|
|
1545
|
+
const h2: HTMLElement = this.createElement('div');
|
|
1546
|
+
const daySpan: HTMLElement = this.createElement('span', { className: 'e-model-day' });
|
|
1547
|
+
const monthSpan: HTMLElement = this.createElement('span', { className: 'e-model-month' });
|
|
1548
|
+
if (this.calendarMode === 'Gregorian') {
|
|
1549
|
+
dateOptions = { format: 'y', skeleton: 'dateTime' };
|
|
1550
|
+
} else {
|
|
1551
|
+
dateOptions = { format: 'y', skeleton: 'dateTime', calendar: 'islamic' };
|
|
1552
|
+
}
|
|
1553
|
+
yearHeading.textContent = '' + this.globalize.formatDate(this.value || new Date(), dateOptions);
|
|
1554
|
+
if (this.calendarMode === 'Gregorian') {
|
|
1555
|
+
dateOptions = { format: 'E', skeleton: 'dateTime' };
|
|
1556
|
+
} else {
|
|
1557
|
+
dateOptions = { format: 'E', skeleton: 'dateTime', calendar: 'islamic' };
|
|
1558
|
+
}
|
|
1559
|
+
daySpan.textContent = '' + this.globalize.formatDate(this.value || new Date(), dateOptions) + ', ';
|
|
1560
|
+
if (this.calendarMode === 'Gregorian') {
|
|
1561
|
+
dateOptions = { format: 'MMM d', skeleton: 'dateTime' };
|
|
1562
|
+
} else {
|
|
1563
|
+
dateOptions = { format: 'MMM d', skeleton: 'dateTime', calendar: 'islamic' };
|
|
1564
|
+
}
|
|
1565
|
+
monthSpan.textContent = '' + this.globalize.formatDate(this.value || new Date(), dateOptions);
|
|
1566
|
+
if (this.fullScreenMode) {
|
|
1567
|
+
const modelCloseIcon: any = this.createElement('span', { className: 'e-popup-close' });
|
|
1568
|
+
EventHandler.add(modelCloseIcon, 'mousedown touchstart', this.modelCloseHandler, this);
|
|
1569
|
+
const modelTodayButton: Element = this.calendarElement.querySelector('button.e-today');
|
|
1570
|
+
h2.classList.add('e-day-wrapper');
|
|
1571
|
+
modelTodayButton.classList.add('e-outline');
|
|
1572
|
+
modelHeader.appendChild(modelCloseIcon);
|
|
1573
|
+
modelHeader.appendChild(modelTodayButton);
|
|
1574
|
+
}
|
|
1575
|
+
if (!this.fullScreenMode)
|
|
1576
|
+
{modelHeader.appendChild(yearHeading); }
|
|
1577
|
+
h2.appendChild(daySpan);
|
|
1578
|
+
h2.appendChild(monthSpan);
|
|
1579
|
+
modelHeader.appendChild(h2);
|
|
1580
|
+
this.calendarElement.insertBefore(modelHeader, this.calendarElement.firstElementChild);
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
private modelCloseHandler(e: MouseEvent| TouchEvent): void {
|
|
1584
|
+
this.hide();
|
|
1585
|
+
}
|
|
1586
|
+
|
|
1587
|
+
protected changeTrigger(event?: MouseEvent | KeyboardEvent): void {
|
|
1588
|
+
if (this.inputElement.value !== this.previousElementValue) {
|
|
1589
|
+
if (((this.previousDate && this.previousDate.valueOf()) !== (this.value && this.value.valueOf()))) {
|
|
1590
|
+
if (this.isDynamicValueChanged && this.isCalendar()) {
|
|
1591
|
+
this.popupUpdate();
|
|
1592
|
+
}
|
|
1593
|
+
this.changedArgs.value = this.value;
|
|
1594
|
+
this.changedArgs.event = event || null;
|
|
1595
|
+
this.changedArgs.element = this.element;
|
|
1596
|
+
this.changedArgs.isInteracted = !isNullOrUndefined(event);
|
|
1597
|
+
if (this.isAngular && this.preventChange) {
|
|
1598
|
+
this.preventChange = false;
|
|
1599
|
+
} else {
|
|
1600
|
+
this.trigger('change', this.changedArgs);
|
|
1601
|
+
}
|
|
1602
|
+
this.previousElementValue = this.inputElement.value;
|
|
1603
|
+
this.previousDate = !isNaN(+new Date(this.checkValue(this.value))) ? new Date(this.checkValue(this.value)) : null;
|
|
1604
|
+
this.isInteracted = true;
|
|
1605
|
+
}
|
|
1606
|
+
}
|
|
1607
|
+
this.isKeyAction = false;
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1610
|
+
protected navigatedEvent(eve: MouseEvent | KeyboardEvent| SwipeEventArgs): void {
|
|
1611
|
+
extend(this.navigatedArgs, { name: 'navigated', event: eve });
|
|
1612
|
+
this.trigger('navigated', this.navigatedArgs);
|
|
1613
|
+
}
|
|
1614
|
+
protected keyupHandler(e: KeyboardEventArgs): void {
|
|
1615
|
+
this.isKeyAction = (this.inputElement.value !== this.previousElementValue) ? true : false;
|
|
1616
|
+
if (this.enableMask && this.showClearButton && this.inputElement && this.inputElement.value === this.maskedDateValue && this.inputWrapper && this.inputWrapper.clearButton && !this.inputWrapper.clearButton.classList.contains('e-clear-icon-hide')) {
|
|
1617
|
+
this.inputWrapper.clearButton.classList.add('e-clear-icon-hide');
|
|
1618
|
+
}
|
|
1619
|
+
}
|
|
1620
|
+
protected changeEvent(event?: MouseEvent | KeyboardEvent | Event): void {
|
|
1621
|
+
if (!this.isIconClicked && !(this.isBlur || this.isKeyAction)) {
|
|
1622
|
+
this.selectCalendar(event);
|
|
1623
|
+
}
|
|
1624
|
+
if (((this.previousDate && this.previousDate.valueOf()) !== (this.value && this.value.valueOf()))) {
|
|
1625
|
+
this.changedArgs.event = event ? event : null;
|
|
1626
|
+
this.changedArgs.element = this.element;
|
|
1627
|
+
this.changedArgs.isInteracted = this.isInteracted;
|
|
1628
|
+
if (!this.isDynamicValueChanged) {
|
|
1629
|
+
if (this.isAngular) {
|
|
1630
|
+
this.previousDate = this.value && new Date(+this.value);
|
|
1631
|
+
}
|
|
1632
|
+
this.trigger('change', this.changedArgs);
|
|
1633
|
+
}
|
|
1634
|
+
this.previousDate = this.value && new Date(+this.value);
|
|
1635
|
+
if (!this.isDynamicValueChanged) {
|
|
1636
|
+
this.hide(event);
|
|
1637
|
+
}
|
|
1638
|
+
this.previousElementValue = this.inputElement.value;
|
|
1639
|
+
this.errorClass();
|
|
1640
|
+
}
|
|
1641
|
+
else if (event) {
|
|
1642
|
+
this.hide(event);
|
|
1643
|
+
}
|
|
1644
|
+
this.isKeyAction = false;
|
|
1645
|
+
}
|
|
1646
|
+
|
|
1647
|
+
public requiredModules(): ModuleDeclaration[] {
|
|
1648
|
+
const modules: ModuleDeclaration[] = [];
|
|
1649
|
+
if (this.calendarMode === 'Islamic') {
|
|
1650
|
+
modules.push({ args: [this], member: 'islamic', name: 'Islamic' });
|
|
1651
|
+
}
|
|
1652
|
+
if (this.enableMask)
|
|
1653
|
+
{
|
|
1654
|
+
modules.push({args: [this], member: 'MaskedDateTime'});
|
|
1655
|
+
}
|
|
1656
|
+
return modules;
|
|
1657
|
+
}
|
|
1658
|
+
|
|
1659
|
+
protected selectCalendar(e?: MouseEvent | KeyboardEvent | Event): void {
|
|
1660
|
+
let date: string;
|
|
1661
|
+
let tempFormat: string;
|
|
1662
|
+
let formatOptions: DateFormatOptions;
|
|
1663
|
+
if (this.getModuleName() === 'datetimepicker') {
|
|
1664
|
+
tempFormat = !isNullOrUndefined(this.formatString) ? this.formatString : this.dateTimeFormat;
|
|
1665
|
+
} else {
|
|
1666
|
+
tempFormat = this.formatString;
|
|
1667
|
+
}
|
|
1668
|
+
if (this.value) {
|
|
1669
|
+
if (this.getModuleName() === 'datetimepicker') {
|
|
1670
|
+
if (this.calendarMode === 'Gregorian') {
|
|
1671
|
+
formatOptions = { format: tempFormat, type: 'dateTime', skeleton: 'yMd' };
|
|
1672
|
+
} else {
|
|
1673
|
+
formatOptions = { format: tempFormat, type: 'dateTime', skeleton: 'yMd', calendar: 'islamic' };
|
|
1674
|
+
}
|
|
1675
|
+
date = this.globalize.formatDate(this.changedArgs.value, formatOptions);
|
|
1676
|
+
} else {
|
|
1677
|
+
if (this.calendarMode === 'Gregorian') {
|
|
1678
|
+
formatOptions = { format: this.formatString, type: 'dateTime', skeleton: 'yMd' };
|
|
1679
|
+
} else {
|
|
1680
|
+
formatOptions = { format: this.formatString, type: 'dateTime', skeleton: 'yMd', calendar: 'islamic' };
|
|
1681
|
+
}
|
|
1682
|
+
date = this.globalize.formatDate(this.changedArgs.value, formatOptions);
|
|
1683
|
+
}
|
|
1684
|
+
if (this.enableMask) {
|
|
1685
|
+
this.notify('createMask', {
|
|
1686
|
+
module: 'MaskedDateTime'
|
|
1687
|
+
});
|
|
1688
|
+
}
|
|
1689
|
+
}
|
|
1690
|
+
if (!isNullOrUndefined(date)) {
|
|
1691
|
+
this.updateInputValue(date);
|
|
1692
|
+
if (this.enableMask)
|
|
1693
|
+
{
|
|
1694
|
+
this.notify('setMaskSelection', {
|
|
1695
|
+
module: 'MaskedDateTime'
|
|
1696
|
+
});
|
|
1697
|
+
}
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
protected isCalendar(): boolean {
|
|
1701
|
+
if (this.popupWrapper && this.popupWrapper.classList.contains('' + POPUPWRAPPER)) {
|
|
1702
|
+
return true;
|
|
1703
|
+
}
|
|
1704
|
+
return false;
|
|
1705
|
+
}
|
|
1706
|
+
protected setWidth(width: number | string): void {
|
|
1707
|
+
if (typeof width === 'number') {
|
|
1708
|
+
this.inputWrapper.container.style.width = formatUnit(this.width);
|
|
1709
|
+
} else if (typeof width === 'string') {
|
|
1710
|
+
this.inputWrapper.container.style.width = (width.match(/px|%|em/)) ? <string>(this.width) : <string>(formatUnit(this.width));
|
|
1711
|
+
} else {
|
|
1712
|
+
this.inputWrapper.container.style.width = '100%';
|
|
1713
|
+
}
|
|
1714
|
+
}
|
|
1715
|
+
/* eslint-disable valid-jsdoc, jsdoc/require-param */
|
|
1716
|
+
/**
|
|
1717
|
+
* Shows the Calendar.
|
|
1718
|
+
*
|
|
1719
|
+
* @returns {void}
|
|
1720
|
+
* @deprecated
|
|
1721
|
+
*/
|
|
1722
|
+
public show(type?: null | string, e?: MouseEvent | KeyboardEvent | KeyboardEventArgs): void {
|
|
1723
|
+
if ((this.enabled && this.readonly) || !this.enabled || this.popupObj) {
|
|
1724
|
+
return;
|
|
1725
|
+
} else {
|
|
1726
|
+
let prevent: boolean = true;
|
|
1727
|
+
let outOfRange: Date;
|
|
1728
|
+
if (!isNullOrUndefined(this.value) && !(+this.value >= +new Date(this.checkValue(this.min))
|
|
1729
|
+
&& +this.value <= +new Date(this.checkValue(this.max)))) {
|
|
1730
|
+
outOfRange = new Date(this.checkValue(this.value));
|
|
1731
|
+
this.setProperties({ 'value': null }, true);
|
|
1732
|
+
} else {
|
|
1733
|
+
outOfRange = this.value || null;
|
|
1734
|
+
}
|
|
1735
|
+
if (!this.isCalendar()) {
|
|
1736
|
+
super.render();
|
|
1737
|
+
this.setProperties({ 'value': outOfRange || null }, true);
|
|
1738
|
+
this.previousDate = outOfRange;
|
|
1739
|
+
this.createCalendar();
|
|
1740
|
+
}
|
|
1741
|
+
if (Browser.isDevice) {
|
|
1742
|
+
this.mobilePopupWrapper = this.createElement('div', { className: 'e-datepick-mob-popup-wrap'});
|
|
1743
|
+
document.body.appendChild(this.mobilePopupWrapper);
|
|
1744
|
+
}
|
|
1745
|
+
this.preventArgs = {
|
|
1746
|
+
preventDefault: (): void => {
|
|
1747
|
+
prevent = false;
|
|
1748
|
+
},
|
|
1749
|
+
popup: this.popupObj,
|
|
1750
|
+
event: e || null,
|
|
1751
|
+
cancel: false,
|
|
1752
|
+
appendTo: Browser.isDevice ? this.mobilePopupWrapper : document.body
|
|
1753
|
+
};
|
|
1754
|
+
const eventArgs: PopupObjectArgs = this.preventArgs;
|
|
1755
|
+
this.trigger('open', eventArgs, (eventArgs: PopupObjectArgs) => {
|
|
1756
|
+
this.preventArgs = eventArgs;
|
|
1757
|
+
if (prevent && !this.preventArgs.cancel) {
|
|
1758
|
+
addClass(this.inputWrapper.buttons, ACTIVE);
|
|
1759
|
+
this.preventArgs.appendTo.appendChild(this.popupWrapper);
|
|
1760
|
+
this.popupObj.refreshPosition(this.inputElement);
|
|
1761
|
+
const openAnimation: object = {
|
|
1762
|
+
name: 'FadeIn',
|
|
1763
|
+
duration: Browser.isDevice ? 0 : OPENDURATION
|
|
1764
|
+
};
|
|
1765
|
+
if (this.zIndex === 1000) {
|
|
1766
|
+
this.popupObj.show(new Animation(openAnimation), this.element);
|
|
1767
|
+
} else {
|
|
1768
|
+
this.popupObj.show(new Animation(openAnimation), null);
|
|
1769
|
+
}
|
|
1770
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1771
|
+
super.setOverlayIndex(this.mobilePopupWrapper, this.popupObj.element, this.modal, Browser.isDevice as any);
|
|
1772
|
+
this.setAriaAttributes();
|
|
1773
|
+
if (Browser.isDevice) {
|
|
1774
|
+
const dlgOverlay: any = this.createElement('div', { className: 'e-dlg-overlay'});
|
|
1775
|
+
dlgOverlay.style.zIndex = (this.zIndex - 1).toString();
|
|
1776
|
+
this.mobilePopupWrapper.appendChild(dlgOverlay);
|
|
1777
|
+
}
|
|
1778
|
+
} else {
|
|
1779
|
+
this.popupObj.destroy();
|
|
1780
|
+
this.popupWrapper = this.popupObj = null;
|
|
1781
|
+
}
|
|
1782
|
+
if (!isNullOrUndefined(this.inputElement) && this.inputElement.value === '') {
|
|
1783
|
+
if (!isNullOrUndefined(this.tableBodyElement) && this.tableBodyElement.querySelectorAll('td.e-selected').length > 0) {
|
|
1784
|
+
addClass([this.tableBodyElement.querySelector('td.e-selected')], FOCUSEDDATE);
|
|
1785
|
+
removeClass(this.tableBodyElement.querySelectorAll('td.e-selected'), SELECTED);
|
|
1786
|
+
}
|
|
1787
|
+
}
|
|
1788
|
+
EventHandler.add(document, 'mousedown touchstart', this.documentHandler, this);
|
|
1789
|
+
});
|
|
1790
|
+
}
|
|
1791
|
+
}
|
|
1792
|
+
/**
|
|
1793
|
+
* Hide the Calendar.
|
|
1794
|
+
*
|
|
1795
|
+
* @returns {void}
|
|
1796
|
+
* @deprecated
|
|
1797
|
+
*/
|
|
1798
|
+
public hide(event?: MouseEvent | KeyboardEvent | Event): void {
|
|
1799
|
+
if (!isNullOrUndefined(this.popupWrapper)) {
|
|
1800
|
+
let prevent: boolean = true;
|
|
1801
|
+
this.preventArgs = {
|
|
1802
|
+
preventDefault: (): void => {
|
|
1803
|
+
prevent = false;
|
|
1804
|
+
},
|
|
1805
|
+
popup: this.popupObj,
|
|
1806
|
+
event: event || null,
|
|
1807
|
+
cancel: false
|
|
1808
|
+
};
|
|
1809
|
+
removeClass(this.inputWrapper.buttons, ACTIVE);
|
|
1810
|
+
removeClass([document.body], OVERFLOW);
|
|
1811
|
+
const eventArgs: PopupObjectArgs = this.preventArgs;
|
|
1812
|
+
if (this.isCalendar()) {
|
|
1813
|
+
this.trigger('close', eventArgs, (eventArgs: PopupObjectArgs) => {
|
|
1814
|
+
this.closeEventCallback(prevent, eventArgs);
|
|
1815
|
+
});
|
|
1816
|
+
} else {
|
|
1817
|
+
this.closeEventCallback(prevent, eventArgs);
|
|
1818
|
+
}
|
|
1819
|
+
} else {
|
|
1820
|
+
if (Browser.isDevice && this.allowEdit && !this.readonly) {
|
|
1821
|
+
this.inputElement.removeAttribute('readonly');
|
|
1822
|
+
}
|
|
1823
|
+
this.setAllowEdit();
|
|
1824
|
+
}
|
|
1825
|
+
}
|
|
1826
|
+
/* eslint-enable valid-jsdoc, jsdoc/require-param */
|
|
1827
|
+
private closeEventCallback(prevent: boolean, eventArgs: PopupObjectArgs): void {
|
|
1828
|
+
this.preventArgs = eventArgs;
|
|
1829
|
+
if (this.isCalendar() && (prevent && !this.preventArgs.cancel)) {
|
|
1830
|
+
this.popupObj.hide();
|
|
1831
|
+
this.isAltKeyPressed = false;
|
|
1832
|
+
this.keyboardModule.destroy();
|
|
1833
|
+
removeClass(this.inputWrapper.buttons, ACTIVE);
|
|
1834
|
+
}
|
|
1835
|
+
this.setAriaAttributes();
|
|
1836
|
+
if (Browser.isDevice && this.modal) {
|
|
1837
|
+
this.modal.style.display = 'none';
|
|
1838
|
+
this.modal.outerHTML = '';
|
|
1839
|
+
this.modal = null;
|
|
1840
|
+
}
|
|
1841
|
+
if (Browser.isDevice) {
|
|
1842
|
+
if (!isNullOrUndefined(this.mobilePopupWrapper) &&
|
|
1843
|
+
(prevent && (isNullOrUndefined(this.preventArgs) || !this.preventArgs.cancel))) {
|
|
1844
|
+
this.mobilePopupWrapper.remove();
|
|
1845
|
+
this.mobilePopupWrapper = null;
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
EventHandler.remove(document, 'mousedown touchstart', this.documentHandler);
|
|
1849
|
+
if (Browser.isDevice && this.allowEdit && !this.readonly) {
|
|
1850
|
+
this.inputElement.removeAttribute('readonly');
|
|
1851
|
+
}
|
|
1852
|
+
this.setAllowEdit();
|
|
1853
|
+
}
|
|
1854
|
+
/* eslint-disable jsdoc/require-param */
|
|
1855
|
+
/**
|
|
1856
|
+
* Sets the focus to widget for interaction.
|
|
1857
|
+
*
|
|
1858
|
+
* @returns {void}
|
|
1859
|
+
*/
|
|
1860
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1861
|
+
public focusIn(triggerEvent?: boolean): void {
|
|
1862
|
+
if (document.activeElement !== this.inputElement && this.enabled) {
|
|
1863
|
+
(<HTMLElement>this.inputElement).focus();
|
|
1864
|
+
addClass([this.inputWrapper.container], [INPUTFOCUS]);
|
|
1865
|
+
}
|
|
1866
|
+
}
|
|
1867
|
+
/* eslint-enable jsdoc/require-param */
|
|
1868
|
+
/**
|
|
1869
|
+
* Remove the focus from widget, if the widget is in focus state.
|
|
1870
|
+
*
|
|
1871
|
+
* @returns {void}
|
|
1872
|
+
*/
|
|
1873
|
+
public focusOut(): void {
|
|
1874
|
+
if (document.activeElement === this.inputElement) {
|
|
1875
|
+
removeClass([this.inputWrapper.container], [INPUTFOCUS]);
|
|
1876
|
+
this.inputElement.blur();
|
|
1877
|
+
}
|
|
1878
|
+
}
|
|
1879
|
+
/* eslint-disable valid-jsdoc, jsdoc/require-returns-description */
|
|
1880
|
+
/**
|
|
1881
|
+
* Gets the current view of the DatePicker.
|
|
1882
|
+
*
|
|
1883
|
+
* @returns {string}
|
|
1884
|
+
* @deprecated
|
|
1885
|
+
*/
|
|
1886
|
+
public currentView(): string {
|
|
1887
|
+
let currentView: string;
|
|
1888
|
+
if (this.calendarElement) {
|
|
1889
|
+
// calls the Calendar currentView public method
|
|
1890
|
+
currentView = super.currentView();
|
|
1891
|
+
}
|
|
1892
|
+
return currentView;
|
|
1893
|
+
}
|
|
1894
|
+
/* eslint-enable valid-jsdoc, jsdoc/require-returns-description */
|
|
1895
|
+
/**
|
|
1896
|
+
* Navigates to specified month or year or decade view of the DatePicker.
|
|
1897
|
+
*
|
|
1898
|
+
* @param {string} view - Specifies the view of the calendar.
|
|
1899
|
+
* @param {Date} date - Specifies the focused date in a view.
|
|
1900
|
+
* @returns {void}
|
|
1901
|
+
* @deprecated
|
|
1902
|
+
*/
|
|
1903
|
+
public navigateTo(view: CalendarView, date: Date): void {
|
|
1904
|
+
if (this.calendarElement) {
|
|
1905
|
+
// calls the Calendar navigateTo public method
|
|
1906
|
+
super.navigateTo(view, date);
|
|
1907
|
+
}
|
|
1908
|
+
}
|
|
1909
|
+
/**
|
|
1910
|
+
* To destroy the widget.
|
|
1911
|
+
*
|
|
1912
|
+
* @returns {void}
|
|
1913
|
+
*/
|
|
1914
|
+
public destroy(): void {
|
|
1915
|
+
this.unBindEvents();
|
|
1916
|
+
if (this.showClearButton) {
|
|
1917
|
+
this.clearButton = document.getElementsByClassName('e-clear-icon')[0] as HTMLElement;
|
|
1918
|
+
}
|
|
1919
|
+
super.destroy();
|
|
1920
|
+
Input.destroy({
|
|
1921
|
+
element: this.inputElement,
|
|
1922
|
+
floatLabelType: this.floatLabelType,
|
|
1923
|
+
properties: this.properties
|
|
1924
|
+
}, this.clearButton);
|
|
1925
|
+
if (!isNullOrUndefined(this.keyboardModules))
|
|
1926
|
+
{
|
|
1927
|
+
this.keyboardModules.destroy();
|
|
1928
|
+
}
|
|
1929
|
+
if (this.popupObj && this.popupObj.element.classList.contains(POPUP)) {
|
|
1930
|
+
super.destroy();
|
|
1931
|
+
}
|
|
1932
|
+
const ariaAttrs: object = {
|
|
1933
|
+
'aria-atomic': 'true', 'aria-disabled': 'true',
|
|
1934
|
+
'aria-expanded': 'false', 'role': 'combobox', 'autocomplete': 'off',
|
|
1935
|
+
'autocorrect': 'off', 'autocapitalize': 'off', 'spellcheck': 'false'
|
|
1936
|
+
};
|
|
1937
|
+
if (this.inputElement.hasAttribute('aria-label')) {
|
|
1938
|
+
this.inputElement.removeAttribute('aria-label');
|
|
1939
|
+
}
|
|
1940
|
+
if (this.inputElement) {
|
|
1941
|
+
Input.removeAttributes(<{ [key: string]: string }>ariaAttrs, this.inputElement);
|
|
1942
|
+
if (!isNullOrUndefined(this.inputElementCopy.getAttribute('tabindex'))) {
|
|
1943
|
+
this.inputElement.setAttribute('tabindex', this.tabIndex);
|
|
1944
|
+
} else {
|
|
1945
|
+
this.inputElement.removeAttribute('tabindex');
|
|
1946
|
+
}
|
|
1947
|
+
EventHandler.remove(this.inputElement, 'blur', this.inputBlurHandler);
|
|
1948
|
+
EventHandler.remove(this.inputElement, 'focus', this.inputFocusHandler);
|
|
1949
|
+
this.ensureInputAttribute();
|
|
1950
|
+
}
|
|
1951
|
+
if (this.isCalendar()) {
|
|
1952
|
+
if (this.popupWrapper) {
|
|
1953
|
+
detach(this.popupWrapper);
|
|
1954
|
+
}
|
|
1955
|
+
this.popupObj = this.popupWrapper = null;
|
|
1956
|
+
this.keyboardModule.destroy();
|
|
1957
|
+
}
|
|
1958
|
+
if (this.ngTag === null) {
|
|
1959
|
+
if (this.inputElement) {
|
|
1960
|
+
if (!isNullOrUndefined(this.inputWrapper))
|
|
1961
|
+
{
|
|
1962
|
+
this.inputWrapper.container.insertAdjacentElement('afterend', this.inputElement);
|
|
1963
|
+
}
|
|
1964
|
+
removeClass([this.inputElement], [INPUTROOT]);
|
|
1965
|
+
}
|
|
1966
|
+
removeClass([this.element], [ROOT]);
|
|
1967
|
+
if (!isNullOrUndefined(this.inputWrapper))
|
|
1968
|
+
{
|
|
1969
|
+
detach(this.inputWrapper.container);
|
|
1970
|
+
}
|
|
1971
|
+
}
|
|
1972
|
+
if (this.formElement) {
|
|
1973
|
+
EventHandler.remove(this.formElement, 'reset', this.resetFormHandler);
|
|
1974
|
+
}
|
|
1975
|
+
this.inputWrapper = null;
|
|
1976
|
+
this.keyboardModules = null;
|
|
1977
|
+
}
|
|
1978
|
+
|
|
1979
|
+
protected ensureInputAttribute(): void {
|
|
1980
|
+
const prop: string[] = [];
|
|
1981
|
+
for (let i: number = 0; i < this.inputElement.attributes.length; i++) {
|
|
1982
|
+
prop[i as number] = this.inputElement.attributes[i as number].name;
|
|
1983
|
+
}
|
|
1984
|
+
for (let i: number = 0; i < prop.length; i++) {
|
|
1985
|
+
if (isNullOrUndefined(this.inputElementCopy.getAttribute(prop[i as number]))) {
|
|
1986
|
+
if (prop[i as number].toLowerCase() === 'value') {
|
|
1987
|
+
this.inputElement.value = '';
|
|
1988
|
+
}
|
|
1989
|
+
this.inputElement.removeAttribute(prop[i as number]);
|
|
1990
|
+
} else {
|
|
1991
|
+
if (prop[i as number].toLowerCase() === 'value') {
|
|
1992
|
+
this.inputElement.value = this.inputElementCopy.getAttribute(prop[i as number]);
|
|
1993
|
+
}
|
|
1994
|
+
this.inputElement.setAttribute(prop[i as number], this.inputElementCopy.getAttribute(prop[i as number]));
|
|
1995
|
+
}
|
|
1996
|
+
}
|
|
1997
|
+
}
|
|
1998
|
+
/**
|
|
1999
|
+
* Initialize the event handler
|
|
2000
|
+
*
|
|
2001
|
+
* @returns {void}
|
|
2002
|
+
* @private
|
|
2003
|
+
*/
|
|
2004
|
+
protected preRender(): void {
|
|
2005
|
+
this.inputElementCopy = <HTMLElement>this.element.cloneNode(true);
|
|
2006
|
+
removeClass([this.inputElementCopy], [ROOT, CONTROL, LIBRARY]);
|
|
2007
|
+
this.inputElement = <HTMLInputElement>this.element;
|
|
2008
|
+
this.formElement = <HTMLFormElement>closest(this.inputElement, 'form');
|
|
2009
|
+
this.index = this.showClearButton ? 2 : 1;
|
|
2010
|
+
this.ngTag = null;
|
|
2011
|
+
if (this.element.tagName === 'EJS-DATEPICKER' || this.element.tagName === 'EJS-DATETIMEPICKER') {
|
|
2012
|
+
this.ngTag = this.element.tagName;
|
|
2013
|
+
this.inputElement = <HTMLInputElement>this.createElement('input');
|
|
2014
|
+
this.element.appendChild(this.inputElement);
|
|
2015
|
+
}
|
|
2016
|
+
if (this.element.getAttribute('id')) {
|
|
2017
|
+
if (this.ngTag !== null) {
|
|
2018
|
+
this.inputElement.id = this.element.getAttribute('id') + '_input';
|
|
2019
|
+
}
|
|
2020
|
+
} else {
|
|
2021
|
+
if (this.getModuleName() === 'datetimepicker') {
|
|
2022
|
+
this.element.id = getUniqueID('ej2-datetimepicker');
|
|
2023
|
+
if (this.ngTag !== null) {
|
|
2024
|
+
attributes(this.inputElement, { 'id': this.element.id + '_input' });
|
|
2025
|
+
}
|
|
2026
|
+
} else {
|
|
2027
|
+
this.element.id = getUniqueID('ej2-datepicker');
|
|
2028
|
+
if (this.ngTag !== null) {
|
|
2029
|
+
attributes(this.inputElement, { 'id': this.element.id + '_input' });
|
|
2030
|
+
}
|
|
2031
|
+
}
|
|
2032
|
+
}
|
|
2033
|
+
if (this.ngTag !== null) {
|
|
2034
|
+
this.validationAttribute(this.element, this.inputElement);
|
|
2035
|
+
}
|
|
2036
|
+
this.updateHtmlAttributeToElement();
|
|
2037
|
+
this.defaultKeyConfigs = this.getDefaultKeyConfig();
|
|
2038
|
+
this.checkHtmlAttributes(false);
|
|
2039
|
+
if (this.inputFormats) {
|
|
2040
|
+
this.checkInputFormats();
|
|
2041
|
+
}
|
|
2042
|
+
this.tabIndex = this.element.hasAttribute('tabindex') ? this.element.getAttribute('tabindex') : '0';
|
|
2043
|
+
this.element.removeAttribute('tabindex');
|
|
2044
|
+
super.preRender();
|
|
2045
|
+
}
|
|
2046
|
+
protected getDefaultKeyConfig(): { [key: string]: string } {
|
|
2047
|
+
this.defaultKeyConfigs = {
|
|
2048
|
+
altUpArrow: 'alt+uparrow',
|
|
2049
|
+
altDownArrow: 'alt+downarrow',
|
|
2050
|
+
escape: 'escape',
|
|
2051
|
+
enter: 'enter',
|
|
2052
|
+
controlUp: 'ctrl+38',
|
|
2053
|
+
controlDown: 'ctrl+40',
|
|
2054
|
+
moveDown: 'downarrow',
|
|
2055
|
+
moveUp: 'uparrow',
|
|
2056
|
+
moveLeft: 'leftarrow',
|
|
2057
|
+
moveRight: 'rightarrow',
|
|
2058
|
+
select: 'enter',
|
|
2059
|
+
home: 'home',
|
|
2060
|
+
end: 'end',
|
|
2061
|
+
pageUp: 'pageup',
|
|
2062
|
+
pageDown: 'pagedown',
|
|
2063
|
+
shiftPageUp: 'shift+pageup',
|
|
2064
|
+
shiftPageDown: 'shift+pagedown',
|
|
2065
|
+
controlHome: 'ctrl+home',
|
|
2066
|
+
controlEnd: 'ctrl+end',
|
|
2067
|
+
shiftTab: 'shift+tab',
|
|
2068
|
+
tab: 'tab'
|
|
2069
|
+
};
|
|
2070
|
+
return this.defaultKeyConfigs;
|
|
2071
|
+
}
|
|
2072
|
+
protected validationAttribute(target: HTMLElement, inputElement: Element): void {
|
|
2073
|
+
const nameAttribute: string = target.getAttribute('name') ? target.getAttribute('name') : target.getAttribute('id');
|
|
2074
|
+
inputElement.setAttribute('name', nameAttribute);
|
|
2075
|
+
target.removeAttribute('name');
|
|
2076
|
+
const attribute: string[] = ['required', 'aria-required', 'form'];
|
|
2077
|
+
for (let i: number = 0; i < attribute.length; i++) {
|
|
2078
|
+
if (isNullOrUndefined(target.getAttribute(attribute[i as number]))) {
|
|
2079
|
+
continue;
|
|
2080
|
+
}
|
|
2081
|
+
const attr: string = target.getAttribute(attribute[i as number]);
|
|
2082
|
+
inputElement.setAttribute(attribute[i as number], attr);
|
|
2083
|
+
target.removeAttribute(attribute[i as number]);
|
|
2084
|
+
}
|
|
2085
|
+
}
|
|
2086
|
+
protected checkFormat(): void {
|
|
2087
|
+
const culture: Internationalization = new Internationalization(this.locale);
|
|
2088
|
+
if (this.format) {
|
|
2089
|
+
if (typeof this.format === 'string') {
|
|
2090
|
+
this.formatString = this.format;
|
|
2091
|
+
} else if (this.format.skeleton !== '' && !isNullOrUndefined(this.format.skeleton)) {
|
|
2092
|
+
const skeletonString: string = this.format.skeleton;
|
|
2093
|
+
if (this.getModuleName() === 'datetimepicker') {
|
|
2094
|
+
this.formatString = culture.getDatePattern({ skeleton: skeletonString, type: 'dateTime' });
|
|
2095
|
+
} else {
|
|
2096
|
+
this.formatString = culture.getDatePattern({ skeleton: skeletonString, type: 'date' });
|
|
2097
|
+
}
|
|
2098
|
+
} else {
|
|
2099
|
+
if (this.getModuleName() === 'datetimepicker') {
|
|
2100
|
+
this.formatString = this.dateTimeFormat;
|
|
2101
|
+
} else {
|
|
2102
|
+
this.formatString = null;
|
|
2103
|
+
}
|
|
2104
|
+
}
|
|
2105
|
+
} else {
|
|
2106
|
+
this.formatString = null;
|
|
2107
|
+
}
|
|
2108
|
+
}
|
|
2109
|
+
protected checkInputFormats(): void {
|
|
2110
|
+
const culture: Internationalization = new Internationalization(this.locale);
|
|
2111
|
+
this.inputFormatsString = [];
|
|
2112
|
+
if (this.inputFormats) {
|
|
2113
|
+
for (const format of this.inputFormats) {
|
|
2114
|
+
let formatString: string = '';
|
|
2115
|
+
if (typeof format === 'string') {
|
|
2116
|
+
formatString = format;
|
|
2117
|
+
} else if (format.skeleton !== '' && !isNullOrUndefined(format.skeleton)) {
|
|
2118
|
+
const skeletonString: string = format.skeleton;
|
|
2119
|
+
if (this.getModuleName() === 'datetimepicker') {
|
|
2120
|
+
formatString = culture.getDatePattern({ skeleton: skeletonString, type: 'dateTime' });
|
|
2121
|
+
} else {
|
|
2122
|
+
formatString = culture.getDatePattern({ skeleton: skeletonString, type: 'date' });
|
|
2123
|
+
}
|
|
2124
|
+
}
|
|
2125
|
+
if (formatString) {
|
|
2126
|
+
this.inputFormatsString.push(formatString);
|
|
2127
|
+
}
|
|
2128
|
+
}
|
|
2129
|
+
if (this.inputFormatsString.length === 0) {
|
|
2130
|
+
this.inputFormatsString = null;
|
|
2131
|
+
}
|
|
2132
|
+
} else {
|
|
2133
|
+
this.inputFormatsString = null;
|
|
2134
|
+
}
|
|
2135
|
+
}
|
|
2136
|
+
private checkHtmlAttributes(dynamic: boolean): void {
|
|
2137
|
+
this.globalize = new Internationalization(this.locale);
|
|
2138
|
+
this.checkFormat();
|
|
2139
|
+
this.checkView();
|
|
2140
|
+
const attributes: string[] = dynamic ? isNullOrUndefined(this.htmlAttributes) ? [] : Object.keys(this.htmlAttributes) :
|
|
2141
|
+
['value', 'min', 'max', 'disabled', 'readonly', 'style', 'name', 'placeholder', 'type'];
|
|
2142
|
+
let options: object;
|
|
2143
|
+
if (this.getModuleName() === 'datetimepicker') {
|
|
2144
|
+
if (this.calendarMode === 'Gregorian') {
|
|
2145
|
+
options = {
|
|
2146
|
+
format: !isNullOrUndefined(this.formatString) ? this.formatString : this.dateTimeFormat,
|
|
2147
|
+
type: 'dateTime', skeleton: 'yMd'
|
|
2148
|
+
};
|
|
2149
|
+
} else {
|
|
2150
|
+
options = {
|
|
2151
|
+
format: !isNullOrUndefined(this.formatString) ? this.formatString : this.dateTimeFormat,
|
|
2152
|
+
type: 'dateTime', skeleton: 'yMd', calendar: 'islamic'
|
|
2153
|
+
};
|
|
2154
|
+
}
|
|
2155
|
+
|
|
2156
|
+
} else {
|
|
2157
|
+
if (this.calendarMode === 'Gregorian') {
|
|
2158
|
+
options = { format: this.formatString, type: 'dateTime', skeleton: 'yMd' };
|
|
2159
|
+
} else {
|
|
2160
|
+
options = { format: this.formatString, type: 'dateTime', skeleton: 'yMd', calendar: 'islamic' };
|
|
2161
|
+
}
|
|
2162
|
+
}
|
|
2163
|
+
for (const prop of attributes) {
|
|
2164
|
+
if (!isNullOrUndefined(this.inputElement.getAttribute(prop))) {
|
|
2165
|
+
switch (prop) {
|
|
2166
|
+
case 'disabled':
|
|
2167
|
+
if (((isNullOrUndefined(this.datepickerOptions) || (this.datepickerOptions['enabled'] === undefined)) || dynamic)) {
|
|
2168
|
+
const enabled: boolean = this.inputElement.getAttribute(prop) === 'disabled' ||
|
|
2169
|
+
this.inputElement.getAttribute(prop) === '' ||
|
|
2170
|
+
this.inputElement.getAttribute(prop) === 'true' ? false : true;
|
|
2171
|
+
this.setProperties({ enabled: enabled }, !dynamic);
|
|
2172
|
+
}
|
|
2173
|
+
break;
|
|
2174
|
+
case 'readonly':
|
|
2175
|
+
if (((isNullOrUndefined(this.datepickerOptions) || (this.datepickerOptions['readonly'] === undefined)) || dynamic)) {
|
|
2176
|
+
const readonly: boolean = this.inputElement.getAttribute(prop) === 'readonly' ||
|
|
2177
|
+
this.inputElement.getAttribute(prop) === '' || this.inputElement.getAttribute(prop) === 'true' ? true : false;
|
|
2178
|
+
this.setProperties({ readonly: readonly }, !dynamic);
|
|
2179
|
+
}
|
|
2180
|
+
break;
|
|
2181
|
+
case 'placeholder':
|
|
2182
|
+
if (((isNullOrUndefined(this.datepickerOptions) || (this.datepickerOptions['placeholder'] === undefined)) || dynamic)) {
|
|
2183
|
+
this.setProperties({ placeholder: this.inputElement.getAttribute(prop) }, !dynamic);
|
|
2184
|
+
}
|
|
2185
|
+
break;
|
|
2186
|
+
case 'style':
|
|
2187
|
+
this.inputElement.setAttribute('style', '' + this.inputElement.getAttribute(prop));
|
|
2188
|
+
break;
|
|
2189
|
+
case 'name':
|
|
2190
|
+
this.inputElement.setAttribute('name', '' + this.inputElement.getAttribute(prop));
|
|
2191
|
+
break;
|
|
2192
|
+
case 'value':
|
|
2193
|
+
if (((isNullOrUndefined(this.datepickerOptions) || (this.datepickerOptions['value'] === undefined)) || dynamic)) {
|
|
2194
|
+
const value: string = this.inputElement.getAttribute(prop);
|
|
2195
|
+
this.setProperties(setValue(prop, this.globalize.parseDate(this.getAmPmValue(value), options), {}), !dynamic);
|
|
2196
|
+
}
|
|
2197
|
+
break;
|
|
2198
|
+
case 'min':
|
|
2199
|
+
if ((+this.min === +new Date(1900, 0, 1)) || dynamic) {
|
|
2200
|
+
const min: string = this.inputElement.getAttribute(prop);
|
|
2201
|
+
this.setProperties(setValue(prop, this.globalize.parseDate(this.getAmPmValue(min), options), {}), !dynamic);
|
|
2202
|
+
}
|
|
2203
|
+
break;
|
|
2204
|
+
case 'max':
|
|
2205
|
+
if ((+this.max === +new Date(2099, 11, 31)) || dynamic) {
|
|
2206
|
+
const max: string = this.inputElement.getAttribute(prop);
|
|
2207
|
+
this.setProperties(setValue(prop, this.globalize.parseDate(this.getAmPmValue(max), options), {}), !dynamic);
|
|
2208
|
+
}
|
|
2209
|
+
break;
|
|
2210
|
+
case 'type':
|
|
2211
|
+
if (this.inputElement.getAttribute(prop) !== 'text') {
|
|
2212
|
+
this.inputElement.setAttribute('type', 'text');
|
|
2213
|
+
}
|
|
2214
|
+
break;
|
|
2215
|
+
}
|
|
2216
|
+
}
|
|
2217
|
+
}
|
|
2218
|
+
}
|
|
2219
|
+
/**
|
|
2220
|
+
* To get component name.
|
|
2221
|
+
*
|
|
2222
|
+
* @returns {string} Returns the component name.
|
|
2223
|
+
* @private
|
|
2224
|
+
*/
|
|
2225
|
+
protected getModuleName(): string {
|
|
2226
|
+
return 'datepicker';
|
|
2227
|
+
}
|
|
2228
|
+
private disabledDates(isDynamic: boolean = false, isBlur: boolean = false): void {
|
|
2229
|
+
let formatOptions: DateFormatOptions;
|
|
2230
|
+
let globalize: string;
|
|
2231
|
+
const valueCopy: Date = this.checkDateValue(this.value) ? new Date(+this.value) : new Date(this.checkValue(this.value));
|
|
2232
|
+
const previousValCopy: Date = this.previousDate;
|
|
2233
|
+
//calls the Calendar render method to check the disabled dates through renderDayCell event and update the input value accordingly.
|
|
2234
|
+
this.minMaxUpdates();
|
|
2235
|
+
if (!isDynamic || (isDynamic && !isNullOrUndefined(this.renderDayCell))) {
|
|
2236
|
+
super.render(); }
|
|
2237
|
+
this.previousDate = previousValCopy;
|
|
2238
|
+
const date: number = valueCopy && +(valueCopy);
|
|
2239
|
+
const dateIdString: string = '*[id^="/id"]'.replace('/id', '' + date);
|
|
2240
|
+
if (!this.strictMode) {
|
|
2241
|
+
if (typeof this.value === 'string' || ((typeof this.value === 'object') && (+this.value) !== (+valueCopy))) {
|
|
2242
|
+
this.setProperties({ value: valueCopy }, true);
|
|
2243
|
+
}
|
|
2244
|
+
}
|
|
2245
|
+
if (!isNullOrUndefined(this.calendarElement) && !isNullOrUndefined(this.calendarElement.querySelectorAll(dateIdString)[0])) {
|
|
2246
|
+
if (this.calendarElement.querySelectorAll(dateIdString)[0].classList.contains('e-disabled')) {
|
|
2247
|
+
if (!this.strictMode) {
|
|
2248
|
+
this.currentDate = new Date(new Date().setHours(0, 0, 0, 0));
|
|
2249
|
+
}
|
|
2250
|
+
}
|
|
2251
|
+
}
|
|
2252
|
+
let inputVal: string;
|
|
2253
|
+
if (this.getModuleName() === 'datetimepicker') {
|
|
2254
|
+
if (this.calendarMode === 'Gregorian') {
|
|
2255
|
+
globalize = this.globalize.formatDate(valueCopy, {
|
|
2256
|
+
format: !isNullOrUndefined(this.formatString) ? this.formatString : this.dateTimeFormat,
|
|
2257
|
+
type: 'dateTime', skeleton: 'yMd'
|
|
2258
|
+
});
|
|
2259
|
+
} else {
|
|
2260
|
+
globalize = this.globalize.formatDate(valueCopy, {
|
|
2261
|
+
format: !isNullOrUndefined(this.formatString) ? this.formatString : this.dateTimeFormat,
|
|
2262
|
+
type: 'dateTime', skeleton: 'yMd', calendar: 'islamic'
|
|
2263
|
+
});
|
|
2264
|
+
}
|
|
2265
|
+
inputVal = globalize;
|
|
2266
|
+
} else {
|
|
2267
|
+
if (this.calendarMode === 'Gregorian') {
|
|
2268
|
+
formatOptions = { format: this.formatString, type: 'dateTime', skeleton: 'yMd' };
|
|
2269
|
+
} else {
|
|
2270
|
+
formatOptions = { format: this.formatString, type: 'dateTime', skeleton: 'yMd', calendar: 'islamic' };
|
|
2271
|
+
}
|
|
2272
|
+
inputVal = this.globalize.formatDate(valueCopy, formatOptions);
|
|
2273
|
+
}
|
|
2274
|
+
if (!this.popupObj) {
|
|
2275
|
+
this.updateInputValue(inputVal);
|
|
2276
|
+
if (this.enableMask)
|
|
2277
|
+
{
|
|
2278
|
+
this.updateInputValue(this.maskedDateValue);
|
|
2279
|
+
this.notify('createMask', {
|
|
2280
|
+
module: 'MaskedDateTime', isBlur: isBlur
|
|
2281
|
+
});
|
|
2282
|
+
}
|
|
2283
|
+
}
|
|
2284
|
+
}
|
|
2285
|
+
private setAriaAttributes(): void {
|
|
2286
|
+
if (this.isCalendar()) {
|
|
2287
|
+
Input.addAttributes({ 'aria-expanded': 'true' }, this.inputElement);
|
|
2288
|
+
attributes(this.inputElement, { 'aria-owns': this.inputElement.id + '_options'});
|
|
2289
|
+
attributes(this.inputElement, { 'aria-controls': this.inputElement.id });
|
|
2290
|
+
if (this.value)
|
|
2291
|
+
{
|
|
2292
|
+
attributes(this.inputElement, { 'aria-activedescendant': '' + this.setActiveDescendant() });
|
|
2293
|
+
}
|
|
2294
|
+
} else {
|
|
2295
|
+
Input.addAttributes({ 'aria-expanded': 'false' }, this.inputElement);
|
|
2296
|
+
this.inputElement.removeAttribute('aria-owns');
|
|
2297
|
+
this.inputElement.removeAttribute('aria-controls');
|
|
2298
|
+
this.inputElement.removeAttribute( 'aria-activedescendant');
|
|
2299
|
+
}
|
|
2300
|
+
}
|
|
2301
|
+
protected errorClass(): void {
|
|
2302
|
+
const dateIdString: string = '*[id^="/id"]'.replace('/id', '' + (+this.value));
|
|
2303
|
+
const isDisabledDate: boolean = this.calendarElement &&
|
|
2304
|
+
this.calendarElement.querySelectorAll(dateIdString)[0] &&
|
|
2305
|
+
this.calendarElement.querySelectorAll(dateIdString)[0].classList.contains('e-disabled');
|
|
2306
|
+
if ((!isNullOrUndefined(this.value) && !isNullOrUndefined(this.min) &&
|
|
2307
|
+
!isNullOrUndefined(this.max) && !(new Date(this.value as Date).setMilliseconds(0) >=
|
|
2308
|
+
new Date(this.min as Date).setMilliseconds(0)
|
|
2309
|
+
&& new Date(this.value as any).setMilliseconds(0) <= new Date(this.max as Date).setMilliseconds(0)))
|
|
2310
|
+
|| (!this.strictMode && this.inputElement.value !== '' && this.inputElement.value !== this.maskedDateValue &&
|
|
2311
|
+
isNullOrUndefined(this.value) || isDisabledDate) || !this.isValidTime(this.value)) {
|
|
2312
|
+
addClass([this.inputWrapper.container], ERROR);
|
|
2313
|
+
attributes(this.inputElement, { 'aria-invalid': 'true' });
|
|
2314
|
+
} else if (!isNullOrUndefined(this.inputWrapper)) {
|
|
2315
|
+
removeClass([this.inputWrapper.container], ERROR);
|
|
2316
|
+
attributes(this.inputElement, { 'aria-invalid': 'false' });
|
|
2317
|
+
}
|
|
2318
|
+
}
|
|
2319
|
+
|
|
2320
|
+
protected isValidTime(value: Date): boolean {
|
|
2321
|
+
return true;
|
|
2322
|
+
}
|
|
2323
|
+
/**
|
|
2324
|
+
* Called internally if any of the property value changed.
|
|
2325
|
+
*
|
|
2326
|
+
* @param {DatePickerModel} newProp - Returns the dynamic property value of the component.
|
|
2327
|
+
* @param {DatePickerModel} oldProp - Returns the previous property value of the component.
|
|
2328
|
+
* @returns {void}
|
|
2329
|
+
* @private
|
|
2330
|
+
*/
|
|
2331
|
+
public onPropertyChanged(newProp: DatePickerModel, oldProp: DatePickerModel): void {
|
|
2332
|
+
for (const prop of Object.keys(newProp)) {
|
|
2333
|
+
const openPopup: string[] = ['blur', 'change', 'cleared', 'close', 'created', 'destroyed', 'focus', 'navigated', 'open', 'renderDayCell'];
|
|
2334
|
+
if (openPopup.indexOf(prop) > 0 && this.isReact) {
|
|
2335
|
+
this.isDynamicValueChanged = true;
|
|
2336
|
+
}
|
|
2337
|
+
switch (prop) {
|
|
2338
|
+
case 'value':
|
|
2339
|
+
this.isDynamicValueChanged = true;
|
|
2340
|
+
this.isInteracted = false;
|
|
2341
|
+
this.invalidValueString = null;
|
|
2342
|
+
this.checkInvalidValue(newProp.value);
|
|
2343
|
+
newProp.value = this.value;
|
|
2344
|
+
this.previousElementValue = this.inputElement.value;
|
|
2345
|
+
if (isNullOrUndefined(this.value)) {
|
|
2346
|
+
if (this.enableMask) {
|
|
2347
|
+
this.updateInputValue(this.maskedDateValue);
|
|
2348
|
+
}
|
|
2349
|
+
else {
|
|
2350
|
+
this.updateInputValue('');
|
|
2351
|
+
}
|
|
2352
|
+
this.currentDate = new Date(new Date().setHours(0, 0, 0, 0));
|
|
2353
|
+
}
|
|
2354
|
+
this.updateInput(true);
|
|
2355
|
+
if (+this.previousDate !== +this.value) {
|
|
2356
|
+
this.changeTrigger(null);
|
|
2357
|
+
}
|
|
2358
|
+
this.isInteracted = true;
|
|
2359
|
+
this.preventChange = this.isAngular && this.preventChange ? !this.preventChange : this.preventChange;
|
|
2360
|
+
if (this.enableMask) {
|
|
2361
|
+
this.notify('createMask', {
|
|
2362
|
+
module: 'MaskedDateTime'
|
|
2363
|
+
});
|
|
2364
|
+
}
|
|
2365
|
+
break;
|
|
2366
|
+
case 'format':
|
|
2367
|
+
this.checkFormat();
|
|
2368
|
+
this.bindInputEvent();
|
|
2369
|
+
this.updateInput();
|
|
2370
|
+
if (this.enableMask) {
|
|
2371
|
+
this.notify('createMask', {
|
|
2372
|
+
module: 'MaskedDateTime'
|
|
2373
|
+
});
|
|
2374
|
+
if (!this.value)
|
|
2375
|
+
{
|
|
2376
|
+
this.updateInputValue(this.maskedDateValue);
|
|
2377
|
+
}
|
|
2378
|
+
}
|
|
2379
|
+
break;
|
|
2380
|
+
case 'inputFormats':
|
|
2381
|
+
this.checkInputFormats();
|
|
2382
|
+
break;
|
|
2383
|
+
case 'allowEdit':
|
|
2384
|
+
this.setAllowEdit();
|
|
2385
|
+
break;
|
|
2386
|
+
case 'placeholder':
|
|
2387
|
+
Input.setPlaceholder(this.placeholder, this.inputElement);
|
|
2388
|
+
break;
|
|
2389
|
+
case 'readonly':
|
|
2390
|
+
Input.setReadonly(this.readonly, this.inputElement);
|
|
2391
|
+
break;
|
|
2392
|
+
case 'enabled':
|
|
2393
|
+
Input.setEnabled(this.enabled, this.inputElement);
|
|
2394
|
+
this.setAriaDisabled();
|
|
2395
|
+
break;
|
|
2396
|
+
case 'htmlAttributes':
|
|
2397
|
+
this.updateHtmlAttributeToElement();
|
|
2398
|
+
this.updateHtmlAttributeToWrapper();
|
|
2399
|
+
this.checkHtmlAttributes(true);
|
|
2400
|
+
break;
|
|
2401
|
+
case 'locale':
|
|
2402
|
+
this.globalize = new Internationalization(this.locale);
|
|
2403
|
+
this.l10n.setLocale(this.locale);
|
|
2404
|
+
if (this.datepickerOptions && this.datepickerOptions.placeholder == null) {
|
|
2405
|
+
this.setProperties({ placeholder: this.l10n.getConstant('placeholder') }, true);
|
|
2406
|
+
Input.setPlaceholder(this.placeholder, this.inputElement);
|
|
2407
|
+
}
|
|
2408
|
+
this.updateInput();
|
|
2409
|
+
if (this.enableMask) {
|
|
2410
|
+
this.notify('createMask', {
|
|
2411
|
+
module: 'MaskedDateTime'
|
|
2412
|
+
});
|
|
2413
|
+
}
|
|
2414
|
+
break;
|
|
2415
|
+
case 'enableRtl':
|
|
2416
|
+
Input.setEnableRtl(this.enableRtl, [this.inputWrapper.container]);
|
|
2417
|
+
break;
|
|
2418
|
+
case 'start':
|
|
2419
|
+
case 'depth':
|
|
2420
|
+
this.checkView();
|
|
2421
|
+
if (this.calendarElement) {
|
|
2422
|
+
super.onPropertyChanged(newProp, oldProp);
|
|
2423
|
+
}
|
|
2424
|
+
break;
|
|
2425
|
+
case 'zIndex':
|
|
2426
|
+
this.setProperties({ zIndex: newProp.zIndex }, true);
|
|
2427
|
+
break;
|
|
2428
|
+
case 'cssClass':
|
|
2429
|
+
this.updateCssClass(newProp.cssClass, oldProp.cssClass);
|
|
2430
|
+
break;
|
|
2431
|
+
case 'showClearButton':
|
|
2432
|
+
Input.setClearButton(this.showClearButton, this.inputElement, this.inputWrapper);
|
|
2433
|
+
this.bindClearEvent();
|
|
2434
|
+
this.index = this.showClearButton ? 2 : 1;
|
|
2435
|
+
break;
|
|
2436
|
+
case 'strictMode':
|
|
2437
|
+
this.invalidValueString = null;
|
|
2438
|
+
this.updateInput();
|
|
2439
|
+
break;
|
|
2440
|
+
case 'width':
|
|
2441
|
+
this.setWidth(newProp.width);
|
|
2442
|
+
Input.calculateWidth(this.inputElement, this.inputWrapper.container);
|
|
2443
|
+
if (!isNullOrUndefined(this.inputWrapper.buttons[0]) && !isNullOrUndefined(this.inputWrapper.container.getElementsByClassName('e-float-text-overflow')[0]) && this.floatLabelType !== 'Never') {
|
|
2444
|
+
this.inputWrapper.container.getElementsByClassName('e-float-text-overflow')[0].classList.add('e-icon');
|
|
2445
|
+
}
|
|
2446
|
+
break;
|
|
2447
|
+
case 'floatLabelType':
|
|
2448
|
+
this.floatLabelType = newProp.floatLabelType;
|
|
2449
|
+
Input.removeFloating(this.inputWrapper);
|
|
2450
|
+
Input.addFloating(this.inputElement, this.floatLabelType, this.placeholder);
|
|
2451
|
+
if (!isNullOrUndefined(this.inputWrapper.buttons[0]) && !isNullOrUndefined(this.inputWrapper.container.getElementsByClassName('e-float-text-overflow')[0]) && this.floatLabelType !== 'Never') {
|
|
2452
|
+
this.inputWrapper.container.getElementsByClassName('e-float-text-overflow')[0].classList.add('e-icon');
|
|
2453
|
+
}
|
|
2454
|
+
break;
|
|
2455
|
+
case 'enableMask':
|
|
2456
|
+
if (this.enableMask) {
|
|
2457
|
+
this.notify('createMask', {
|
|
2458
|
+
module: 'MaskedDateTime'
|
|
2459
|
+
});
|
|
2460
|
+
this.updateInputValue(this.maskedDateValue);
|
|
2461
|
+
this.bindInputEvent();
|
|
2462
|
+
}
|
|
2463
|
+
else
|
|
2464
|
+
{
|
|
2465
|
+
if (this.inputElement.value === this.maskedDateValue)
|
|
2466
|
+
{
|
|
2467
|
+
this.updateInputValue('');
|
|
2468
|
+
}
|
|
2469
|
+
}
|
|
2470
|
+
break;
|
|
2471
|
+
default:
|
|
2472
|
+
if (this.calendarElement && this.isCalendar()) {
|
|
2473
|
+
super.onPropertyChanged(newProp, oldProp);
|
|
2474
|
+
}
|
|
2475
|
+
if (prop === 'min' && isNullOrUndefined(this.min)) {
|
|
2476
|
+
this.min = new Date(1900, 0, 1);
|
|
2477
|
+
}
|
|
2478
|
+
if (prop === 'max' && isNullOrUndefined(this.max)) {
|
|
2479
|
+
this.max = new Date(2099, 11, 31);
|
|
2480
|
+
}
|
|
2481
|
+
break;
|
|
2482
|
+
}
|
|
2483
|
+
if (!this.isDynamicValueChanged) {
|
|
2484
|
+
this.hide(null);
|
|
2485
|
+
}
|
|
2486
|
+
this.isDynamicValueChanged = false;
|
|
2487
|
+
}
|
|
2488
|
+
}
|
|
2489
|
+
/**
|
|
2490
|
+
* @private
|
|
2491
|
+
* @param {Date | Date[]} dates - Specifies the date or dates to be added to the values property of the Calendar.
|
|
2492
|
+
* @returns {void}
|
|
2493
|
+
*/
|
|
2494
|
+
public addDate(dates: Date | Date[]): void {
|
|
2495
|
+
// no code
|
|
2496
|
+
}
|
|
2497
|
+
}
|
|
2498
|
+
|
|
2499
|
+
export interface PopupObjectArgs {
|
|
2500
|
+
/** Prevents the default action */
|
|
2501
|
+
preventDefault?: Function
|
|
2502
|
+
/**
|
|
2503
|
+
* Defines the DatePicker popup element.
|
|
2504
|
+
*
|
|
2505
|
+
* @deprecated
|
|
2506
|
+
*/
|
|
2507
|
+
popup?: Popup
|
|
2508
|
+
/**
|
|
2509
|
+
* Illustrates whether the current action needs to be prevented or not.
|
|
2510
|
+
*/
|
|
2511
|
+
|
|
2512
|
+
cancel?: boolean
|
|
2513
|
+
/**
|
|
2514
|
+
* Specifies the original event arguments.
|
|
2515
|
+
*/
|
|
2516
|
+
|
|
2517
|
+
event?: MouseEvent | KeyboardEvent | Event
|
|
2518
|
+
/**
|
|
2519
|
+
* Specifies the node to which the popup element to be appended.
|
|
2520
|
+
*/
|
|
2521
|
+
appendTo?: HTMLElement
|
|
2522
|
+
}
|
|
2523
|
+
|
|
2524
|
+
export interface PreventableEventArgs {
|
|
2525
|
+
/** Prevents the default action */
|
|
2526
|
+
preventDefault?: Function
|
|
2527
|
+
|
|
2528
|
+
}
|