@syncfusion/ej2-schedule 31.1.17 → 31.1.21

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.
Files changed (168) hide show
  1. package/dist/ej2-schedule.min.js +2 -2
  2. package/dist/ej2-schedule.umd.min.js +2 -2
  3. package/dist/ej2-schedule.umd.min.js.map +1 -1
  4. package/dist/es6/ej2-schedule.es2015.js +7 -3
  5. package/dist/es6/ej2-schedule.es2015.js.map +1 -1
  6. package/dist/es6/ej2-schedule.es5.js +6 -2
  7. package/dist/es6/ej2-schedule.es5.js.map +1 -1
  8. package/dist/global/ej2-schedule.min.js +2 -2
  9. package/dist/global/ej2-schedule.min.js.map +1 -1
  10. package/dist/global/index.d.ts +1 -1
  11. package/package.json +18 -53
  12. package/src/schedule/actions/virtual-scroll.js +5 -1
  13. package/src/schedule/event-renderer/event-base.js +1 -1
  14. package/styles/bootstrap4-lite.css +8 -0
  15. package/styles/bootstrap4.css +8 -0
  16. package/styles/recurrence-editor/bootstrap4.css +8 -0
  17. package/styles/schedule/bootstrap4.css +8 -0
  18. package/dist/ts/common/calendar-util.d.ts +0 -92
  19. package/dist/ts/common/calendar-util.ts +0 -261
  20. package/dist/ts/common/index.d.ts +0 -4
  21. package/dist/ts/common/index.ts +0 -4
  22. package/dist/ts/components.d.ts +0 -5
  23. package/dist/ts/components.ts +0 -5
  24. package/dist/ts/index.d.ts +0 -6
  25. package/dist/ts/index.ts +0 -7
  26. package/dist/ts/recurrence-editor/date-generator.d.ts +0 -76
  27. package/dist/ts/recurrence-editor/date-generator.ts +0 -1699
  28. package/dist/ts/recurrence-editor/index.d.ts +0 -6
  29. package/dist/ts/recurrence-editor/index.ts +0 -6
  30. package/dist/ts/recurrence-editor/recurrence-editor-model.d.ts +0 -112
  31. package/dist/ts/recurrence-editor/recurrence-editor.d.ts +0 -245
  32. package/dist/ts/recurrence-editor/recurrence-editor.ts +0 -1257
  33. package/dist/ts/schedule/actions/action-base.d.ts +0 -44
  34. package/dist/ts/schedule/actions/action-base.ts +0 -493
  35. package/dist/ts/schedule/actions/crud.d.ts +0 -41
  36. package/dist/ts/schedule/actions/crud.ts +0 -784
  37. package/dist/ts/schedule/actions/data.d.ts +0 -63
  38. package/dist/ts/schedule/actions/data.ts +0 -128
  39. package/dist/ts/schedule/actions/drag.d.ts +0 -75
  40. package/dist/ts/schedule/actions/drag.ts +0 -1401
  41. package/dist/ts/schedule/actions/keyboard.d.ts +0 -100
  42. package/dist/ts/schedule/actions/keyboard.ts +0 -1435
  43. package/dist/ts/schedule/actions/resize.d.ts +0 -27
  44. package/dist/ts/schedule/actions/resize.ts +0 -602
  45. package/dist/ts/schedule/actions/scroll.d.ts +0 -69
  46. package/dist/ts/schedule/actions/scroll.ts +0 -105
  47. package/dist/ts/schedule/actions/touch.d.ts +0 -32
  48. package/dist/ts/schedule/actions/touch.ts +0 -314
  49. package/dist/ts/schedule/actions/virtual-scroll.d.ts +0 -55
  50. package/dist/ts/schedule/actions/virtual-scroll.ts +0 -596
  51. package/dist/ts/schedule/actions/work-cells.d.ts +0 -14
  52. package/dist/ts/schedule/actions/work-cells.ts +0 -151
  53. package/dist/ts/schedule/base/constant.d.ts +0 -102
  54. package/dist/ts/schedule/base/constant.ts +0 -103
  55. package/dist/ts/schedule/base/css-constant.d.ts +0 -475
  56. package/dist/ts/schedule/base/css-constant.ts +0 -475
  57. package/dist/ts/schedule/base/interface.d.ts +0 -673
  58. package/dist/ts/schedule/base/interface.ts +0 -738
  59. package/dist/ts/schedule/base/resource.d.ts +0 -59
  60. package/dist/ts/schedule/base/resource.ts +0 -1091
  61. package/dist/ts/schedule/base/schedule-model.d.ts +0 -930
  62. package/dist/ts/schedule/base/schedule.d.ts +0 -1967
  63. package/dist/ts/schedule/base/schedule.ts +0 -4221
  64. package/dist/ts/schedule/base/type.d.ts +0 -134
  65. package/dist/ts/schedule/base/type.ts +0 -142
  66. package/dist/ts/schedule/base/util.d.ts +0 -266
  67. package/dist/ts/schedule/base/util.ts +0 -492
  68. package/dist/ts/schedule/event-renderer/agenda-base.d.ts +0 -15
  69. package/dist/ts/schedule/event-renderer/agenda-base.ts +0 -423
  70. package/dist/ts/schedule/event-renderer/event-base.d.ts +0 -101
  71. package/dist/ts/schedule/event-renderer/event-base.ts +0 -1501
  72. package/dist/ts/schedule/event-renderer/inline-edit.d.ts +0 -23
  73. package/dist/ts/schedule/event-renderer/inline-edit.ts +0 -287
  74. package/dist/ts/schedule/event-renderer/month.d.ts +0 -60
  75. package/dist/ts/schedule/event-renderer/month.ts +0 -760
  76. package/dist/ts/schedule/event-renderer/timeline-view.d.ts +0 -51
  77. package/dist/ts/schedule/event-renderer/timeline-view.ts +0 -606
  78. package/dist/ts/schedule/event-renderer/vertical-view.d.ts +0 -57
  79. package/dist/ts/schedule/event-renderer/vertical-view.ts +0 -898
  80. package/dist/ts/schedule/event-renderer/year.d.ts +0 -27
  81. package/dist/ts/schedule/event-renderer/year.ts +0 -623
  82. package/dist/ts/schedule/exports/calendar-export.d.ts +0 -16
  83. package/dist/ts/schedule/exports/calendar-export.ts +0 -160
  84. package/dist/ts/schedule/exports/calendar-import.d.ts +0 -18
  85. package/dist/ts/schedule/exports/calendar-import.ts +0 -277
  86. package/dist/ts/schedule/exports/excel-export.d.ts +0 -14
  87. package/dist/ts/schedule/exports/excel-export.ts +0 -89
  88. package/dist/ts/schedule/exports/index.d.ts +0 -7
  89. package/dist/ts/schedule/exports/index.ts +0 -7
  90. package/dist/ts/schedule/exports/print.d.ts +0 -20
  91. package/dist/ts/schedule/exports/print.ts +0 -233
  92. package/dist/ts/schedule/index.d.ts +0 -26
  93. package/dist/ts/schedule/index.ts +0 -26
  94. package/dist/ts/schedule/models/event-settings-model.d.ts +0 -165
  95. package/dist/ts/schedule/models/event-settings.d.ts +0 -149
  96. package/dist/ts/schedule/models/event-settings.ts +0 -187
  97. package/dist/ts/schedule/models/field-options-model.d.ts +0 -37
  98. package/dist/ts/schedule/models/field-options.d.ts +0 -31
  99. package/dist/ts/schedule/models/field-options.ts +0 -41
  100. package/dist/ts/schedule/models/fields-model.d.ts +0 -129
  101. package/dist/ts/schedule/models/fields.d.ts +0 -117
  102. package/dist/ts/schedule/models/fields.ts +0 -149
  103. package/dist/ts/schedule/models/group-model.d.ts +0 -69
  104. package/dist/ts/schedule/models/group.d.ts +0 -60
  105. package/dist/ts/schedule/models/group.ts +0 -75
  106. package/dist/ts/schedule/models/header-rows-model.d.ts +0 -33
  107. package/dist/ts/schedule/models/header-rows.d.ts +0 -30
  108. package/dist/ts/schedule/models/header-rows.ts +0 -35
  109. package/dist/ts/schedule/models/models.d.ts +0 -14
  110. package/dist/ts/schedule/models/models.ts +0 -15
  111. package/dist/ts/schedule/models/quick-info-templates-model.d.ts +0 -52
  112. package/dist/ts/schedule/models/quick-info-templates.d.ts +0 -47
  113. package/dist/ts/schedule/models/quick-info-templates.ts +0 -56
  114. package/dist/ts/schedule/models/resources-model.d.ts +0 -122
  115. package/dist/ts/schedule/models/resources.d.ts +0 -106
  116. package/dist/ts/schedule/models/resources.ts +0 -138
  117. package/dist/ts/schedule/models/time-scale-model.d.ts +0 -57
  118. package/dist/ts/schedule/models/time-scale.d.ts +0 -50
  119. package/dist/ts/schedule/models/time-scale.ts +0 -61
  120. package/dist/ts/schedule/models/toolbar-model.d.ts +0 -196
  121. package/dist/ts/schedule/models/toolbar.d.ts +0 -176
  122. package/dist/ts/schedule/models/toolbar.ts +0 -196
  123. package/dist/ts/schedule/models/views-model.d.ts +0 -370
  124. package/dist/ts/schedule/models/views.d.ts +0 -335
  125. package/dist/ts/schedule/models/views.ts +0 -408
  126. package/dist/ts/schedule/models/work-hours-model.d.ts +0 -29
  127. package/dist/ts/schedule/models/work-hours.d.ts +0 -24
  128. package/dist/ts/schedule/models/work-hours.ts +0 -31
  129. package/dist/ts/schedule/popups/event-tooltip.d.ts +0 -16
  130. package/dist/ts/schedule/popups/event-tooltip.ts +0 -203
  131. package/dist/ts/schedule/popups/event-window.d.ts +0 -118
  132. package/dist/ts/schedule/popups/event-window.ts +0 -2055
  133. package/dist/ts/schedule/popups/form-validator.d.ts +0 -16
  134. package/dist/ts/schedule/popups/form-validator.ts +0 -110
  135. package/dist/ts/schedule/popups/quick-popups.d.ts +0 -78
  136. package/dist/ts/schedule/popups/quick-popups.ts +0 -1470
  137. package/dist/ts/schedule/renderer/agenda.d.ts +0 -45
  138. package/dist/ts/schedule/renderer/agenda.ts +0 -497
  139. package/dist/ts/schedule/renderer/day.d.ts +0 -20
  140. package/dist/ts/schedule/renderer/day.ts +0 -28
  141. package/dist/ts/schedule/renderer/header-renderer.d.ts +0 -48
  142. package/dist/ts/schedule/renderer/header-renderer.ts +0 -736
  143. package/dist/ts/schedule/renderer/month-agenda.d.ts +0 -29
  144. package/dist/ts/schedule/renderer/month-agenda.ts +0 -184
  145. package/dist/ts/schedule/renderer/month.d.ts +0 -61
  146. package/dist/ts/schedule/renderer/month.ts +0 -766
  147. package/dist/ts/schedule/renderer/renderer.d.ts +0 -13
  148. package/dist/ts/schedule/renderer/renderer.ts +0 -165
  149. package/dist/ts/schedule/renderer/timeline-header-row.d.ts +0 -15
  150. package/dist/ts/schedule/renderer/timeline-header-row.ts +0 -132
  151. package/dist/ts/schedule/renderer/timeline-month.d.ts +0 -29
  152. package/dist/ts/schedule/renderer/timeline-month.ts +0 -184
  153. package/dist/ts/schedule/renderer/timeline-view.d.ts +0 -31
  154. package/dist/ts/schedule/renderer/timeline-view.ts +0 -308
  155. package/dist/ts/schedule/renderer/timeline-year.d.ts +0 -22
  156. package/dist/ts/schedule/renderer/timeline-year.ts +0 -450
  157. package/dist/ts/schedule/renderer/vertical-view.d.ts +0 -63
  158. package/dist/ts/schedule/renderer/vertical-view.ts +0 -911
  159. package/dist/ts/schedule/renderer/view-base.d.ts +0 -83
  160. package/dist/ts/schedule/renderer/view-base.ts +0 -709
  161. package/dist/ts/schedule/renderer/week.d.ts +0 -22
  162. package/dist/ts/schedule/renderer/week.ts +0 -35
  163. package/dist/ts/schedule/renderer/work-week.d.ts +0 -22
  164. package/dist/ts/schedule/renderer/work-week.ts +0 -36
  165. package/dist/ts/schedule/renderer/year.d.ts +0 -46
  166. package/dist/ts/schedule/renderer/year.ts +0 -470
  167. package/dist/ts/schedule/timezone/timezone.d.ts +0 -16
  168. package/dist/ts/schedule/timezone/timezone.ts +0 -313
@@ -1,2055 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import { createElement, L10n, isNullOrUndefined, addClass, remove, EventHandler, extend, append, EmitType, detach } from '@syncfusion/ej2-base';
3
- import { cldrData, removeClass, getValue, getDefaultDateObject, closest, KeyboardEventArgs, SanitizeHtmlHelper, initializeCSPTemplate } from '@syncfusion/ej2-base';
4
- import { Query, Deferred } from '@syncfusion/ej2-data';
5
- import { CheckBox, ChangeEventArgs, Button } from '@syncfusion/ej2-buttons';
6
- import { Dialog, DialogModel, BeforeOpenEventArgs, BeforeCloseEventArgs } from '@syncfusion/ej2-popups';
7
- import { DropDownList, FilteringEventArgs, MultiSelect, ChangeEventArgs as ddlChangeEventArgs, MultiSelectChangeEventArgs, PopupEventArgs } from '@syncfusion/ej2-dropdowns';
8
- import { Input, FormValidator, NumericTextBox } from '@syncfusion/ej2-inputs';
9
- import { DatePicker, DateTimePicker, ChangedEventArgs } from '@syncfusion/ej2-calendars';
10
- import { Schedule } from '../base/schedule';
11
- import { EJ2Instance, EventFieldsMapping, PopupOpenEventArgs, TdData, CellClickEventArgs, PopupCloseEventArgs, CallbackFunction } from '../base/interface';
12
- import { CurrentAction } from '../base/type';
13
- import { FieldValidator } from './form-validator';
14
- import { RecurrenceEditor } from '../../recurrence-editor/recurrence-editor';
15
- import { ResourcesModel } from '../models/resources-model';
16
- import * as cls from '../base/css-constant';
17
- import * as event from '../base/constant';
18
- import * as util from '../base/util';
19
-
20
- const EVENT_FIELD: string = 'e-field';
21
- const REPEAT_CONTAINER_CLASS: string = 'e-recurrence-container';
22
- const REPEAT_BUTTON_ICON_CLASS: string = 'e-recurrence-edit';
23
- const REPEAT_BUTTON_CLASS: string = 'e-recurrence-edit-button';
24
- const REPEAT_DIALOG_CLASS: string = 'e-recurrence-dialog';
25
- const HIDE_STYLE_CLASS: string = 'e-hide';
26
-
27
- /**
28
- * Event editor window
29
- */
30
- export class EventWindow {
31
- private parent: Schedule;
32
- public dialogObject: Dialog;
33
- private element: HTMLElement;
34
- private fields: EventFieldsMapping;
35
- private l10n: L10n;
36
- private eventData: Record<string, any>;
37
- private eventCrudData: Record<string, any>;
38
- private fieldValidator: FieldValidator;
39
- private recurrenceEditor: RecurrenceEditor;
40
- private repeatDialogObject: Dialog;
41
- private repeatTempRule: string;
42
- private repeatRule: string;
43
- private repeatStatus: CheckBox;
44
- private buttonObj: Button;
45
- private repeatStartDate: Date;
46
- private cellClickAction: boolean;
47
- private duration: number;
48
- private isCrudAction: boolean;
49
- private eventWindowTime: Record<string, Date>;
50
- private isEnterKey: boolean;
51
- private dialogEvent: Event;
52
-
53
- constructor(parent: Schedule) {
54
- this.parent = parent;
55
- this.l10n = this.parent.localeObj;
56
- this.fields = this.parent.eventFields;
57
- this.eventWindowTime = { startTime: new Date(), endTime: new Date() };
58
- this.renderEventWindow();
59
- }
60
-
61
- private renderEventWindow(): void {
62
- this.element = createElement('div', { id: this.parent.element.id + '_dialog_wrapper' });
63
- this.parent.element.appendChild(this.element);
64
- const dialogModel: DialogModel = {
65
- animationSettings: { effect: 'Zoom' },
66
- content: this.getEventWindowContent(),
67
- cssClass: cls.EVENT_WINDOW_DIALOG_CLASS,
68
- enableRtl: this.parent.enableRtl,
69
- enableHtmlSanitizer: this.parent.enableHtmlSanitizer,
70
- height: this.parent.isAdaptive ? '100%' : 'auto',
71
- minHeight: '300px',
72
- isModal: true,
73
- showCloseIcon: this.parent.isAdaptive ? false : true,
74
- target: document.body,
75
- visible: false,
76
- width: '500px',
77
- beforeOpen: this.onBeforeOpen.bind(this),
78
- beforeClose: this.onBeforeClose.bind(this)
79
- };
80
- if (this.parent.isAdaptive) {
81
- dialogModel.cssClass = cls.EVENT_WINDOW_DIALOG_CLASS + ' ' + cls.DEVICE_CLASS;
82
- if (!this.parent.editorHeaderTemplate) {
83
- dialogModel.header = '<div class="e-title-header"><div class="e-back-icon e-icons"></div><div class="e-title-text">' +
84
- this.l10n.getConstant('newEvent') + '</div><div class="e-save-icon e-icons"></div></div>';
85
- }
86
- } else {
87
- if (!this.parent.editorFooterTemplate) {
88
- this.renderDialogButtons(dialogModel);
89
- }
90
- if (!this.parent.editorHeaderTemplate) {
91
- dialogModel.header = '<div class="e-title-text">' + this.l10n.getConstant('newEvent') + '</div>';
92
- }
93
- }
94
- this.dialogObject = new Dialog(dialogModel, this.element);
95
- if (this.dialogObject.element.querySelector('.e-dlg-closeicon-btn')) {
96
- this.dialogObject.element.querySelector('.e-dlg-closeicon-btn').setAttribute('title', this.l10n.getConstant('close'));
97
- }
98
- this.addEventHandlers();
99
- addClass([this.element.parentElement], cls.EVENT_WINDOW_DIALOG_CLASS + '-container');
100
- EventHandler.add(this.dialogObject.element, 'keydown', this.preventEventSave, this);
101
- this.applyFormValidation();
102
- }
103
-
104
- private renderDialogButtons(dialogButton: DialogModel | Dialog): void {
105
- dialogButton.buttons = [{
106
- buttonModel: {
107
- content: this.l10n.getConstant('deleteButton'), cssClass: cls.DELETE_EVENT_CLASS,
108
- disabled: !this.parent.eventSettings.allowDeleting || this.parent.readonly
109
- },
110
- click: this.eventDelete.bind(this)
111
- }, {
112
- buttonModel: {
113
- content: this.l10n.getConstant('saveButton'), cssClass: 'e-primary ' + cls.EVENT_WINDOW_SAVE_BUTTON_CLASS,
114
- isPrimary: true, disabled: !this.parent.eventSettings.allowAdding || this.parent.readonly
115
- },
116
- click: this.eventSave.bind(this)
117
- }, {
118
- buttonModel: { cssClass: cls.EVENT_WINDOW_CANCEL_BUTTON_CLASS, content: this.l10n.getConstant('cancelButton') },
119
- click: this.dialogClose.bind(this)
120
- }];
121
- }
122
-
123
- private addEventHandlers(): void {
124
- const backIcon: Element = this.element.querySelector('.' + cls.EVENT_WINDOW_BACK_ICON_CLASS);
125
- const saveIcon: Element = this.element.querySelector('.' + cls.EVENT_WINDOW_SAVE_ICON_CLASS);
126
- if (this.parent.isAdaptive && !isNullOrUndefined(backIcon) && !isNullOrUndefined(saveIcon)) {
127
- EventHandler.add(backIcon, 'click', this.dialogClose, this);
128
- EventHandler.add(saveIcon, 'click', this.eventSave, this);
129
- }
130
- }
131
-
132
- public refresh(): void {
133
- this.destroy(true);
134
- this.renderEventWindow();
135
- }
136
-
137
- public refreshRecurrenceEditor(): void {
138
- if (this.recurrenceEditor) {
139
- const recurrenceEditor: HTMLElement = this.recurrenceEditor.element;
140
- this.recurrenceEditor.destroy();
141
- this.createRecurrenceEditor(recurrenceEditor);
142
- }
143
- }
144
-
145
- public setRecurrenceEditor(recurrenceEditor: RecurrenceEditor): void {
146
- if (this.parent.editorTemplate) {
147
- this.recurrenceEditor = recurrenceEditor;
148
- }
149
- }
150
-
151
- public openEditor(data: Record<string, any>, type: CurrentAction, isEventData?: boolean, repeatType?: number): void {
152
- this.parent.currentAction = type;
153
- this.parent.removeNewEventElement();
154
- if (this.parent.quickPopup) {
155
- this.parent.quickPopup.quickPopupHide(true);
156
- }
157
- this.parent.inlineModule.removeInlineAppointmentElement();
158
- if (type === 'Add') {
159
- let eventObj: Record<string, any> = {};
160
- this.cellClickAction = !isEventData;
161
- this.parent.activeCellsData = data as unknown as CellClickEventArgs;
162
- const event: Record<string, any> = data;
163
- if (this.cellClickAction) {
164
- this.convertToEventData(event, eventObj);
165
- } else {
166
- this.parent.activeCellsData = {
167
- startTime: <Date>(event.startTime || event[this.fields.startTime]),
168
- endTime: <Date>(event.endTime || event[this.fields.endTime]),
169
- isAllDay: <boolean>(event.isAllDay || event[this.fields.isAllDay]),
170
- element: <HTMLElement>event.element,
171
- groupIndex: <number>event.groupIndex
172
- };
173
- eventObj = event;
174
- }
175
- data = eventObj;
176
- }
177
- if (!isNullOrUndefined(this.parent.editorHeaderTemplate)) {
178
- this.parent.resetTemplates(['editorHeaderTemplate']);
179
- if (this.parent.isAdaptive && !this.parent.editorFooterTemplate) {
180
- this.dialogObject.header = this.createAdaptiveHeaderElement(data);
181
- } else {
182
- this.dialogObject.header = this.getDialogHeader(data);
183
- }
184
- }
185
- if (!isNullOrUndefined(this.parent.editorFooterTemplate)) {
186
- this.parent.resetTemplates(['editorFooterTemplate']);
187
- this.dialogObject.footerTemplate = this.getDialogFooter(data);
188
- }
189
- if (!isNullOrUndefined(this.parent.editorHeaderTemplate) || !isNullOrUndefined(this.parent.editorFooterTemplate)) {
190
- this.dialogObject.dataBind();
191
- this.addEventHandlers();
192
- }
193
- if (!isNullOrUndefined(this.parent.editorTemplate)) {
194
- this.renderFormElements(this.element.querySelector('.e-schedule-form'), data, type, repeatType);
195
- } else {
196
- this.setEditorContent(data, type, repeatType);
197
- }
198
- }
199
-
200
- private setEditorContent(data: Record<string, any>, type: CurrentAction, repeatType: number): void {
201
- if (!this.parent.isAdaptive && isNullOrUndefined(this.parent.editorTemplate)) {
202
- removeClass([this.dialogObject.element.querySelector('.e-recurrenceeditor')], cls.DISABLE_CLASS);
203
- }
204
- if (this.recurrenceEditor) {
205
- this.recurrenceEditor.firstDayOfWeek = this.parent.activeViewOptions.firstDayOfWeek;
206
- }
207
- switch (type) {
208
- case 'Add':
209
- this.onCellDetailsUpdate(data, repeatType);
210
- break;
211
- case 'Save':
212
- case 'EditOccurrence':
213
- case 'EditSeries':
214
- case 'EditFollowingEvents':
215
- if (type === 'EditOccurrence' && !this.parent.isAdaptive && isNullOrUndefined(this.parent.editorTemplate)) {
216
- addClass([this.dialogObject.element.querySelector('.e-recurrenceeditor')], cls.DISABLE_CLASS);
217
- }
218
- this.cellClickAction = false;
219
- this.onEventDetailsUpdate(data);
220
- break;
221
- }
222
- }
223
-
224
- public setDialogContent(): void {
225
- this.dialogObject.content = this.getEventWindowContent();
226
- this.dialogObject.dataBind();
227
- this.applyFormValidation();
228
- }
229
- public setDialogHeader(): void {
230
- if (!isNullOrUndefined(this.parent.editorHeaderTemplate)) {
231
- this.parent.resetTemplates(['editorHeaderTemplate']);
232
- if (this.parent.isAdaptive && !this.parent.editorFooterTemplate) {
233
- this.dialogObject.header = this.createAdaptiveHeaderElement();
234
- }
235
- else {
236
- this.dialogObject.header = this.getDialogHeader();
237
- }
238
- } else if (this.parent.isAdaptive) {
239
- this.dialogObject.header = '<div class="e-title-header"><div class="e-back-icon e-icons"></div><div class="e-title-text">' +
240
- this.l10n.getConstant('newEvent') + '</div><div class="e-save-icon e-icons"></div></div>';
241
- } else {
242
- this.dialogObject.header = '<div class="e-title-text">' + this.l10n.getConstant('newEvent') + '</div>';
243
- }
244
- this.dialogObject.dataBind();
245
- this.addEventHandlers();
246
- }
247
- public setDialogFooter(): void {
248
- if (!isNullOrUndefined(this.parent.editorFooterTemplate)) {
249
- this.parent.resetTemplates(['editorFooterTemplate']);
250
- this.dialogObject.footerTemplate = this.getDialogFooter();
251
- } else if (!this.parent.isAdaptive && isNullOrUndefined(this.parent.editorFooterTemplate)) {
252
- this.renderDialogButtons(this.dialogObject);
253
- } else if (this.parent.isAdaptive && isNullOrUndefined(this.parent.editorFooterTemplate)) {
254
- this.dialogObject.footerTemplate = null;
255
- }
256
- this.dialogObject.dataBind();
257
- }
258
-
259
- private createAdaptiveHeaderElement(data?: Record<string, any>): HTMLElement {
260
- const header: HTMLElement = createElement('div', { className: 'e-title-header' });
261
- const headerBackIcon: HTMLElement = createElement('div', { className: 'e-back-icon e-icons' });
262
- header.appendChild(headerBackIcon);
263
- const headerTemplate: HTMLElement = this.getDialogHeader(data);
264
- header.appendChild(headerTemplate);
265
- const headerSaveIcon: HTMLElement = createElement('div', { className: 'e-save-icon e-icons' });
266
- header.appendChild(headerSaveIcon);
267
- return header;
268
- }
269
- private getDialogHeader(args?: Record<string, any>): HTMLElement {
270
- let headerTemplate: Element[] = [];
271
- const headerTemplateId: string = this.parent.element.id + '_editorHeaderTemplate';
272
- const temHeaderDiv: HTMLElement = document.createElement('div');
273
- headerTemplate = [].slice.call(this.parent.getEditorHeaderTemplate()(args || {}, this.parent, 'editorHeaderTemplate', headerTemplateId, false));
274
- append(headerTemplate, temHeaderDiv);
275
- return temHeaderDiv;
276
- }
277
-
278
- private getDialogFooter(args?: Record<string, any>): HTMLElement {
279
- let footerTemplate: Element[] = [];
280
- const footerTemplateId: string = this.parent.element.id + '_editorFooterTemplate';
281
- const temFooterDiv: HTMLElement = document.createElement('div');
282
- footerTemplate = [].slice.call(this.parent.getEditorFooterTemplate()(args || {}, this.parent, 'editorFooterTemplate', footerTemplateId, false));
283
- append(footerTemplate, temFooterDiv);
284
- return temFooterDiv;
285
- }
286
-
287
- private preventEventSave(e: KeyboardEventArgs): void {
288
- if (this.parent && !this.parent.allowKeyboardInteraction && (e as KeyboardEventArgs).code === 'Enter') {
289
- this.isEnterKey = true;
290
- }
291
- }
292
-
293
- private onBeforeOpen(args: BeforeOpenEventArgs): Deferred {
294
- const endTime: number = this.eventData[this.fields.endTime].getTime();
295
- const eventProp: PopupOpenEventArgs = {
296
- type: 'Editor',
297
- data: this.eventData,
298
- cancel: false,
299
- element: this.element,
300
- target: (this.cellClickAction ? this.parent.activeCellsData.element : this.parent.activeEventData.element) as HTMLElement
301
- };
302
- if (this.cellClickAction) {
303
- eventProp.duration = this.getSlotDuration();
304
- }
305
- const saveObj: Button = this.getInstance(cls.EVENT_WINDOW_SAVE_BUTTON_CLASS) as unknown as Button;
306
- if (saveObj) {
307
- saveObj.disabled = !(this.cellClickAction ? this.parent.eventSettings.allowAdding : this.parent.eventSettings.allowEditing);
308
- saveObj.dataBind();
309
- }
310
- const deleteObj: Button = this.getInstance(cls.DELETE_EVENT_CLASS) as unknown as Button;
311
- if (deleteObj) {
312
- deleteObj.disabled = !this.parent.eventSettings.allowDeleting;
313
- deleteObj.dataBind();
314
- }
315
- const callBackPromise: Deferred = new Deferred();
316
- this.parent.trigger(event.popupOpen, eventProp, (popupArgs: PopupOpenEventArgs) => {
317
- args.cancel = popupArgs.cancel;
318
- args.maxHeight = this.parent.isAdaptive ? 'max-content' : args.maxHeight;
319
- this.duration = this.cellClickAction ? popupArgs.duration : null;
320
- if (this.eventData[this.fields.endTime].getTime() === endTime && !this.cellClickAction &&
321
- (<Date>this.eventData[this.fields.endTime]).getHours() === 0 &&
322
- (<Date>this.eventData[this.fields.endTime]).getMinutes() === 0) {
323
- this.eventData = <Record<string, any>>extend({}, this.eventData, null, true);
324
- this.trimAllDay(this.eventData);
325
- }
326
- this.refreshDateTimePicker(this.duration);
327
- if (this.cellClickAction && popupArgs.duration !== this.getSlotDuration() && isNullOrUndefined(this.parent.editorTemplate)) {
328
- const startObj: DateTimePicker = this.getInstance(cls.EVENT_WINDOW_START_CLASS) as unknown as DateTimePicker;
329
- const endObj: DateTimePicker = this.getInstance(cls.EVENT_WINDOW_END_CLASS) as unknown as DateTimePicker;
330
- endObj.value = new Date(startObj.value.getTime() + (util.MS_PER_MINUTE * popupArgs.duration));
331
- endObj.dataBind();
332
- }
333
- if (this.parent.editorTemplate && this.element.querySelector('.e-recurrenceeditor') && !this.recurrenceEditor) {
334
- this.recurrenceEditor = this.getInstance('e-recurrenceeditor') as unknown as RecurrenceEditor;
335
- }
336
- callBackPromise.resolve(args);
337
- });
338
- return callBackPromise;
339
- }
340
-
341
- private onBeforeClose(args: BeforeCloseEventArgs): Deferred {
342
- if (args.isInteracted) {
343
- this.isCrudAction = false;
344
- }
345
- const eventProp: PopupCloseEventArgs = {
346
- type: 'Editor',
347
- event: args.event || this.dialogEvent,
348
- data: this.eventCrudData,
349
- cancel: false,
350
- element: this.element,
351
- target: (this.cellClickAction ? this.parent.activeCellsData.element : this.parent.activeEventData.element) as HTMLElement
352
- };
353
- const callBackPromise: Deferred = new Deferred();
354
- this.parent.trigger(event.popupClose, eventProp, (popupArgs: PopupCloseEventArgs) => {
355
- args.cancel = popupArgs.cancel;
356
- if (!popupArgs.cancel) {
357
- if (this.isCrudAction) {
358
- args.cancel = this.processCrudActions(popupArgs.data);
359
- this.isCrudAction = args.cancel;
360
- }
361
- if (!this.isCrudAction) {
362
- this.resetForm();
363
- this.parent.eventBase.focusElement(true);
364
- this.eventCrudData = null;
365
- }
366
- }
367
- callBackPromise.resolve(args);
368
- });
369
- return callBackPromise;
370
- }
371
-
372
- private getEventWindowContent(): HTMLElement {
373
- const container: HTMLElement = createElement('div', { className: cls.FORM_CONTAINER_CLASS });
374
- const form: HTMLFormElement = createElement('form', {
375
- id: this.parent.element.id + 'EditForm',
376
- className: cls.FORM_CLASS
377
- }) as HTMLFormElement;
378
- form.onsubmit = () => { return false; };
379
- this.renderFormElements(form);
380
- container.appendChild(form);
381
- return container;
382
- }
383
-
384
- private renderFormElements(form: HTMLFormElement, args?: Record<string, any>, type?: CurrentAction, repeatType?: number): void {
385
- if (!isNullOrUndefined(this.parent.editorTemplate)) {
386
- if (args) {
387
- if (this.fieldValidator) {
388
- this.fieldValidator.destroy();
389
- this.fieldValidator = null;
390
- }
391
- if (this.recurrenceEditor) {
392
- this.recurrenceEditor.destroy();
393
- this.recurrenceEditor = null;
394
- }
395
- this.destroyComponents();
396
- this.parent.resetTemplates(['editorTemplate']);
397
- EventHandler.clearEvents(form);
398
- if (!this.parent.isReact) {
399
- const formElements: HTMLElement[] = [].slice.call(form.children);
400
- for (const element of formElements) {
401
- remove(element);
402
- }
403
- }
404
- }
405
- const templateId: string = this.parent.element.id + '_editorTemplate';
406
- const tempEle: HTMLElement[] =
407
- [].slice.call(this.parent.getEditorTemplate()(args || {}, this.parent, 'editorTemplate', templateId, false));
408
- append(tempEle, form);
409
- this.parent.renderTemplates(() => {
410
- if (this.element) {
411
- this.applyFormValidation();
412
- if (args) {
413
- this.setEditorContent(args, type, repeatType);
414
- }
415
- }
416
- });
417
- } else {
418
- form.appendChild(this.getDefaultEventWindowContent());
419
- if (args) {
420
- this.setEditorContent(args, type, repeatType);
421
- }
422
- }
423
- }
424
-
425
- private getDefaultEventWindowContent(): HTMLElement {
426
- const parentDiv: HTMLElement = this.createDivElement(cls.EVENT_WINDOW_DIALOG_PARENT_CLASS);
427
- const titleLocationDiv: HTMLElement = this.createDivElement(cls.EVENT_WINDOW_TITLE_LOCATION_DIV_CLASS);
428
- parentDiv.appendChild(titleLocationDiv);
429
- titleLocationDiv.appendChild(this.renderTextBox(cls.SUBJECT_CLASS));
430
- titleLocationDiv.appendChild(this.renderTextBox(cls.LOCATION_CLASS));
431
- const startEndDateTimeDiv: HTMLElement = this.createDivElement(cls.EVENT_WINDOW_START_END_DIV_CLASS);
432
- parentDiv.appendChild(startEndDateTimeDiv);
433
- startEndDateTimeDiv.appendChild(this.renderDateTimePicker(cls.EVENT_WINDOW_START_CLASS, this.onTimeChange.bind(this)));
434
- startEndDateTimeDiv.appendChild(this.renderDateTimePicker(cls.EVENT_WINDOW_END_CLASS));
435
- const allDayTimezoneDiv: HTMLElement = this.createDivElement(cls.EVENT_WINDOW_ALLDAY_TZ_DIV_CLASS);
436
- parentDiv.appendChild(allDayTimezoneDiv);
437
- allDayTimezoneDiv.appendChild(this.renderCheckBox(cls.EVENT_WINDOW_ALL_DAY_CLASS));
438
- allDayTimezoneDiv.appendChild(this.renderCheckBox(cls.TIME_ZONE_CLASS));
439
- const timezoneParentDiv: HTMLElement = this.createDivElement(cls.EVENT_WINDOW_TIME_ZONE_DIV_CLASS);
440
- parentDiv.appendChild(timezoneParentDiv);
441
- timezoneParentDiv.appendChild(this.renderDropDown(cls.EVENT_WINDOW_START_TZ_CLASS));
442
- timezoneParentDiv.appendChild(this.renderDropDown(cls.EVENT_WINDOW_END_TZ_CLASS));
443
- const repeatParentDiv: HTMLElement = this.createDivElement(cls.EVENT_WINDOW_REPEAT_DIV_CLASS);
444
- parentDiv.appendChild(repeatParentDiv);
445
- const repeatDiv: HTMLElement = this.renderCheckBox(cls.EVENT_WINDOW_REPEAT_CLASS);
446
- const repeatEditContainer: HTMLElement = createElement('span', { className: REPEAT_CONTAINER_CLASS });
447
- const button: HTMLElement = createElement('button', {
448
- className: REPEAT_BUTTON_CLASS,
449
- attrs: { type: 'button', 'title': this.l10n.getConstant('editRecurrence') }
450
- });
451
- this.buttonObj = new Button({ iconCss: REPEAT_BUTTON_ICON_CLASS + ' e-icons', cssClass: 'e-medium ' + this.parent.cssClass });
452
- repeatEditContainer.appendChild(button);
453
- this.buttonObj.appendTo(button);
454
- repeatDiv.appendChild(repeatEditContainer);
455
- repeatParentDiv.appendChild(repeatDiv);
456
- if (this.parent.isAdaptive) {
457
- EventHandler.add(button, 'click', this.loadRecurrenceEditor, this);
458
- } else {
459
- this.createRecurrenceEditor(parentDiv);
460
- }
461
- if (this.parent.resourceCollection.length > 0) {
462
- const resourceParentDiv: HTMLElement = this.createDivElement(cls.EVENT_WINDOW_RESOURCES_DIV_CLASS);
463
- for (const resource of this.parent.resourceBase.resourceCollection) {
464
- resourceParentDiv.appendChild(this.renderResourceDetails(resource));
465
- }
466
- parentDiv.appendChild(resourceParentDiv);
467
- }
468
- const description: HTMLElement = this.createDivElement(cls.DESCRIPTION_CLASS + '-row');
469
- description.appendChild(this.renderTextBox(cls.DESCRIPTION_CLASS));
470
- parentDiv.appendChild(description);
471
- const submit: HTMLElement = createElement('button', { attrs: { type: 'hidden', title: 'submit' } });
472
- submit.style.display = 'none';
473
- parentDiv.appendChild(submit);
474
- return parentDiv;
475
- }
476
-
477
- private createRecurrenceEditor(parentDiv: HTMLElement): void {
478
- const recurrenceEditor: HTMLElement = createElement('div', { id: this.parent.element.id + '_recurrence_editor' });
479
- parentDiv.appendChild(recurrenceEditor);
480
- this.recurrenceEditor = this.renderRecurrenceEditor();
481
- this.recurrenceEditor.appendTo(recurrenceEditor);
482
- this.updateMinMaxDateToEditor();
483
- }
484
-
485
- private createDivElement(className?: string): HTMLElement {
486
- return createElement('div', { className: className });
487
- }
488
-
489
- private createInputElement(className: string, fieldName: string, type?: string): HTMLElement {
490
- return createElement(type || 'input', {
491
- className: className, attrs: {
492
- type: 'text', name: fieldName, value: '', id: fieldName
493
- }
494
- });
495
- }
496
-
497
- private getSlotDuration(): number {
498
- return this.parent.activeViewOptions.timeScale.interval / this.parent.activeViewOptions.timeScale.slotCount;
499
- }
500
-
501
- private renderDateTimePicker(value: string, changeEvent?: EmitType<ChangedEventArgs>): HTMLElement {
502
- const dateTimeDiv: HTMLElement = this.createDivElement(value + '-container');
503
- const fieldName: string = this.getFieldName(value);
504
- const dateTimeInput: HTMLElement = this.createInputElement(value + ' ' + EVENT_FIELD, fieldName);
505
- dateTimeDiv.appendChild(dateTimeInput);
506
- const dateTimePicker: DateTimePicker = new DateTimePicker({
507
- change: changeEvent,
508
- firstDayOfWeek: this.parent.activeViewOptions.firstDayOfWeek,
509
- calendarMode: this.parent.calendarMode,
510
- min: this.parent.minDate,
511
- max: new Date(new Date(+this.parent.maxDate).setHours(23, 59, 59)),
512
- cssClass: this.parent.cssClass,
513
- enableRtl: this.parent.enableRtl,
514
- locale: this.parent.locale,
515
- floatLabelType: 'Always',
516
- strictMode: true,
517
- timeFormat: this.parent.activeViewOptions.timeFormat,
518
- format: (isNullOrUndefined(this.parent.dateFormat) ?
519
- this.getFormat('dateFormats') : this.parent.dateFormat) + ' ' + this.parent.activeViewOptions.timeFormat,
520
- placeholder: this.getFieldLabel(value),
521
- step: this.getSlotDuration(),
522
- width: '100%'
523
- });
524
- dateTimePicker.appendTo(dateTimeInput);
525
- return dateTimeDiv;
526
- }
527
-
528
- public refreshDateTimePicker(duration?: number): void {
529
- const elementSelector: string = '.' + cls.EVENT_WINDOW_START_CLASS + ',.' + cls.EVENT_WINDOW_END_CLASS;
530
- const startEndElement: HTMLElement[] = [].slice.call(this.element.querySelectorAll(elementSelector));
531
- for (const element of startEndElement) {
532
- const instance: DateTimePicker = ((<HTMLElement>element) as EJ2Instance).ej2_instances[0] as DateTimePicker;
533
- instance.firstDayOfWeek = this.parent.activeViewOptions.firstDayOfWeek;
534
- instance.timeFormat = this.parent.activeViewOptions.timeFormat;
535
- instance.step = duration || this.getSlotDuration();
536
- instance.dataBind();
537
- }
538
- }
539
-
540
- private onTimeChange(): void {
541
- const startObj: DateTimePicker = this.getInstance(cls.EVENT_WINDOW_START_CLASS) as unknown as DateTimePicker;
542
- if (startObj.element.parentElement.classList.contains('e-input-focus')) {
543
- const endObj: DateTimePicker = this.getInstance(cls.EVENT_WINDOW_END_CLASS) as unknown as DateTimePicker;
544
- let duration: number = 0;
545
- if (this.cellClickAction) {
546
- duration = util.MS_PER_MINUTE * this.duration;
547
- this.eventWindowTime.startTime = startObj.value;
548
- } else {
549
- duration = (<Date>this.eventData[this.fields.endTime]).getTime() - (<Date>this.eventData[this.fields.startTime]).getTime();
550
- }
551
- const endDate: Date = (isNullOrUndefined(startObj.value)) ? null : new Date(startObj.value.getTime() + duration);
552
- if (this.cellClickAction) {
553
- this.eventWindowTime.endTime = endDate;
554
- }
555
- endObj.value = endDate;
556
- endObj.dataBind();
557
- }
558
- if (this.recurrenceEditor) {
559
- this.recurrenceEditor.updateRuleUntilDate(this.eventWindowTime.startTime);
560
- }
561
- }
562
-
563
- private renderResourceDetails(resourceData: ResourcesModel): HTMLElement {
564
- const fieldName: string = resourceData.field;
565
- const value: string = 'e-' + fieldName;
566
- const labelValue: string = resourceData.title;
567
- const resourceDiv: HTMLElement = this.createDivElement(value + '-container' + ' ' + 'e-resources');
568
- const resourceInput: HTMLElement = this.createInputElement(value + ' ' + EVENT_FIELD, fieldName);
569
- resourceDiv.appendChild(resourceInput);
570
- const resourceTemplate: Function = function(data: any): string {
571
- return SanitizeHtmlHelper.sanitize(`<div class="e-resource-template">
572
- <div class="e-resource-color" data-resource-color="${data[resourceData.colorField]}"></div>
573
- <div class="e-resource-text">${data[resourceData.textField]}</div></div>`);
574
- };
575
- initializeCSPTemplate(resourceTemplate, resourceData);
576
- if (resourceData.allowMultiple) {
577
- const listObj: MultiSelect = new MultiSelect({
578
- enableRtl: this.parent.enableRtl,
579
- enableHtmlSanitizer: this.parent.enableHtmlSanitizer,
580
- cssClass: this.parent.cssClass || '',
581
- dataSource: resourceData.dataSource as Record<string, any>[],
582
- change: this.onMultiselectResourceChange.bind(this),
583
- itemTemplate: resourceTemplate as any,
584
- fields: {
585
- text: resourceData.textField,
586
- value: resourceData.idField
587
- },
588
- htmlAttributes: {'name': fieldName },
589
- floatLabelType: 'Always',
590
- placeholder: labelValue,
591
- popupHeight: '230px',
592
- popupWidth: '447px',
593
- mode: 'Box',
594
- open: (args: PopupEventArgs) => {
595
- Promise.resolve().then(() => {
596
- this.applyStylesAfterRender(args);
597
- });
598
- }
599
- });
600
- listObj.appendTo(resourceInput);
601
- } else {
602
- const dropDownList: DropDownList = new DropDownList({
603
- cssClass: this.parent.cssClass || '',
604
- change: this.onDropdownResourceChange.bind(this),
605
- dataSource: resourceData.dataSource as Record<string, any>[],
606
- enableRtl: this.parent.enableRtl,
607
- fields: {
608
- text: resourceData.textField,
609
- value: resourceData.idField
610
- },
611
- htmlAttributes: { 'name': fieldName },
612
- floatLabelType: 'Always',
613
- placeholder: labelValue,
614
- popupHeight: '230px',
615
- popupWidth: '447px',
616
- itemTemplate: resourceTemplate as any,
617
- open: (args: PopupEventArgs) => {
618
- Promise.resolve().then(() => {
619
- this.applyStylesAfterRender(args);
620
- });
621
- }
622
- });
623
- dropDownList.appendTo(resourceInput);
624
- }
625
- return resourceDiv;
626
- }
627
-
628
- private applyStylesAfterRender(args: PopupEventArgs): void {
629
- if (!args.popup || !args.popup.element) { return; }
630
- const resourceColors: NodeListOf<Element> = args.popup.element.querySelectorAll('.e-resource-color[data-resource-color]');
631
- resourceColors.forEach((element: Element) => {
632
- const color: string = element.getAttribute('data-resource-color');
633
- if (color) {
634
- (element as HTMLElement).style.backgroundColor = color;
635
- }
636
- });
637
- }
638
-
639
- private renderDropDown(value: string): HTMLElement {
640
- const fieldName: string = this.getFieldName(value);
641
- const timezoneDiv: HTMLElement = this.createDivElement(value + '-container');
642
- const timezoneInput: HTMLElement = this.createInputElement(value + ' ' + EVENT_FIELD, fieldName);
643
- timezoneDiv.appendChild(timezoneInput);
644
- const dropDownList: DropDownList = new DropDownList({
645
- allowFiltering: true,
646
- change: this.onTimezoneChange.bind(this),
647
- cssClass: this.parent.cssClass || '',
648
- dataSource: this.parent.timezoneDataSource as any[],
649
- enableRtl: this.parent.enableRtl,
650
- fields: { text: 'Text', value: 'Value' },
651
- filterBarPlaceholder: this.parent.localeObj.getConstant('searchTimezone'),
652
- noRecordsTemplate: this.parent.localeObj.getConstant('noRecords'),
653
- filtering: (e: FilteringEventArgs) => {
654
- let query: Query = new Query();
655
- query = (e.text !== '') ? query.where('Text', 'contains', e.text, true) : query;
656
- e.updateData(this.parent.timezoneDataSource as any[], query);
657
- },
658
- htmlAttributes: { 'title': this.getFieldLabel(value), 'name': fieldName },
659
- floatLabelType: 'Always',
660
- placeholder: this.getFieldLabel(value),
661
- popupHeight: '230px'
662
- });
663
- dropDownList.appendTo(timezoneInput);
664
- return timezoneDiv;
665
- }
666
-
667
- private onMultiselectResourceChange(args: MultiSelectChangeEventArgs): void {
668
- if (!args.value || !this.parent.activeViewOptions.group.byGroupID || this.parent.resourceCollection.length <= 1) {
669
- return;
670
- }
671
- const resourceCollection: ResourcesModel[] = this.parent.resourceBase.resourceCollection;
672
- const fieldName: string = args.element.getAttribute('name') || this.getColumnName(args.element as HTMLInputElement);
673
- for (let i: number = 0; i < resourceCollection.length; i++) {
674
- if (resourceCollection[parseInt(i.toString(), 10)].field === fieldName && i < resourceCollection.length - 1) {
675
- const resObject: MultiSelect | DropDownList = this.createInstance(i);
676
- let datasource: Record<string, any>[] = [];
677
- for (let j: number = 0; j < args.value.length; j++) {
678
- const resourceModel: ResourcesModel = resourceCollection[i + 1];
679
- // eslint-disable-next-line max-len
680
- const filter: Record<string, any> = (resourceModel.dataSource as Record<string, any>[]).filter((data: Record<string, any>) =>
681
- data[resourceModel.groupIDField] === args.value[parseInt(j.toString(), 10)])[0];
682
- const groupId: number = (!isNullOrUndefined(filter)) ?
683
- filter[resourceCollection[i + 1].groupIDField] as number : null;
684
- const filterRes: Record<string, any>[] = this.filterDatasource(i, groupId);
685
- datasource = datasource.concat(filterRes);
686
- }
687
- resObject.dataSource = datasource;
688
- resObject.dataBind();
689
- }
690
- }
691
- }
692
-
693
- private createInstance(index: number): MultiSelect | DropDownList {
694
- const resourceData: Record<string, any> = this.parent.resourceBase.resourceCollection[index + 1] as Record<string, any>;
695
- const resObject: MultiSelect | DropDownList = (this.element.querySelector('.e-' + resourceData.field) as EJ2Instance).
696
- ej2_instances[0] as MultiSelect | DropDownList;
697
- resObject.clear();
698
- return resObject;
699
- }
700
-
701
- private onDropdownResourceChange(args: ddlChangeEventArgs): void {
702
- if (!args.value || this.parent.resourceCollection.length <= 1 || !this.parent.activeViewOptions.group.byGroupID) {
703
- return;
704
- }
705
- const fieldName: string = args.element.getAttribute('name') || this.getColumnName(args.element as HTMLInputElement);
706
- const resourceCollection: ResourcesModel[] = this.parent.resourceBase.resourceCollection;
707
- for (let i: number = 0; i < resourceCollection.length; i++) {
708
- if ((i < resourceCollection.length - 1) && resourceCollection[parseInt(i.toString(), 10)].field === fieldName) {
709
- const resObj: MultiSelect | DropDownList = this.createInstance(i);
710
- const groupId: number =
711
- (args.itemData as Record<string, any>)[resourceCollection[parseInt(i.toString(), 10)].idField] as number;
712
- resObj.dataSource = this.filterDatasource(i, groupId);
713
- resObj.dataBind();
714
- const resValue: string = (resObj.dataSource.length > 0) ?
715
- resObj.dataSource[0][resourceCollection[i + 1].idField] as string : null;
716
- resObj.value = (resourceCollection[i + 1].allowMultiple) ? [resValue] : resValue;
717
- resObj.dataBind();
718
- }
719
- }
720
- }
721
-
722
- private filterDatasource(index: number, groupId: number | string): Record<string, any>[] {
723
- const resourceData: ResourcesModel = this.parent.resourceBase.resourceCollection[index + 1];
724
- return (resourceData.dataSource as Record<string, any>[]).filter((data: Record<string, any>) =>
725
- data[resourceData.groupIDField] === groupId);
726
- }
727
-
728
- private onTimezoneChange(args: ddlChangeEventArgs): void {
729
- const fieldName: string = args.element.getAttribute('name') || this.getColumnName(args.element as HTMLInputElement);
730
- if (fieldName === this.parent.eventFields.startTimezone) {
731
- const startTimezoneObj: DropDownList = this.getInstance(cls.EVENT_WINDOW_START_TZ_CLASS) as unknown as DropDownList;
732
- const endTimezoneObj: DropDownList = this.getInstance(cls.EVENT_WINDOW_END_TZ_CLASS) as unknown as DropDownList;
733
- endTimezoneObj.value = startTimezoneObj.value;
734
- endTimezoneObj.dataBind();
735
- }
736
- }
737
-
738
- private renderCheckBox(value: string): HTMLElement {
739
- const checkBoxDiv: HTMLElement = this.createDivElement(value + '-container');
740
- const fieldName: string = this.getFieldName(value);
741
- const checkBoxInput: HTMLElement = this.createInputElement(value + ' ' + EVENT_FIELD, fieldName);
742
- checkBoxDiv.appendChild(checkBoxInput);
743
- const checkBox: CheckBox = new CheckBox({
744
- change: this.onChange.bind(this),
745
- cssClass: value + ' ' + this.parent.cssClass,
746
- enableRtl: this.parent.enableRtl,
747
- enableHtmlSanitizer: this.parent.enableHtmlSanitizer,
748
- label: this.getFieldLabel(value)
749
- });
750
- checkBox.appendTo(checkBoxInput);
751
- checkBoxInput.setAttribute('name', fieldName);
752
- if (fieldName === 'Repeat') {
753
- this.repeatStatus = checkBox;
754
- }
755
- return checkBoxDiv;
756
- }
757
-
758
- private renderTextBox(value: string): HTMLElement {
759
- const textBoxDiv: HTMLElement = this.createDivElement(value + '-container');
760
- const fieldName: string = this.getFieldName(value);
761
- const elementType: string = (value === cls.DESCRIPTION_CLASS) ? 'textarea' : 'input';
762
- const textBoxInput: HTMLElement = this.createInputElement(value + ' ' + EVENT_FIELD, fieldName, elementType);
763
- textBoxDiv.appendChild(textBoxInput);
764
- Input.createInput({
765
- element: textBoxInput as HTMLInputElement,
766
- floatLabelType: 'Always',
767
- properties: {
768
- enableRtl: this.parent.enableRtl,
769
- placeholder: this.getFieldLabel(value)
770
- }
771
- });
772
- return textBoxDiv;
773
- }
774
-
775
- private getFieldName(name: string): string {
776
- let fieldName: string = '';
777
- switch (name) {
778
- case cls.SUBJECT_CLASS:
779
- fieldName = this.fields.subject;
780
- break;
781
- case cls.LOCATION_CLASS:
782
- fieldName = this.fields.location;
783
- break;
784
- case cls.EVENT_WINDOW_START_CLASS:
785
- fieldName = this.fields.startTime;
786
- break;
787
- case cls.EVENT_WINDOW_END_CLASS:
788
- fieldName = this.fields.endTime;
789
- break;
790
- case cls.DESCRIPTION_CLASS:
791
- fieldName = this.fields.description;
792
- break;
793
- case cls.EVENT_WINDOW_ALL_DAY_CLASS:
794
- fieldName = this.fields.isAllDay;
795
- break;
796
- case cls.EVENT_WINDOW_START_TZ_CLASS:
797
- fieldName = this.fields.startTimezone;
798
- break;
799
- case cls.EVENT_WINDOW_END_TZ_CLASS:
800
- fieldName = this.fields.endTimezone;
801
- break;
802
- case cls.TIME_ZONE_CLASS:
803
- fieldName = 'Timezone';
804
- break;
805
- case cls.EVENT_WINDOW_REPEAT_CLASS:
806
- fieldName = 'Repeat';
807
- break;
808
- }
809
- return fieldName;
810
- }
811
-
812
- private getFieldLabel(fieldName: string): string {
813
- let labelText: string = '';
814
- switch (fieldName) {
815
- case cls.SUBJECT_CLASS:
816
- labelText = this.parent.editorTitles.subject;
817
- break;
818
- case cls.LOCATION_CLASS:
819
- labelText = this.parent.editorTitles.location;
820
- break;
821
- case cls.DESCRIPTION_CLASS:
822
- labelText = this.parent.editorTitles.description;
823
- break;
824
- case cls.EVENT_WINDOW_START_CLASS:
825
- labelText = this.parent.editorTitles.startTime;
826
- break;
827
- case cls.EVENT_WINDOW_END_CLASS:
828
- labelText = this.parent.editorTitles.endTime;
829
- break;
830
- case cls.EVENT_WINDOW_START_TZ_CLASS:
831
- labelText = this.parent.editorTitles.startTimezone;
832
- break;
833
- case cls.EVENT_WINDOW_END_TZ_CLASS:
834
- labelText = this.parent.editorTitles.endTimezone;
835
- break;
836
- case cls.EVENT_WINDOW_REPEAT_CLASS:
837
- labelText = this.parent.editorTitles.recurrenceRule;
838
- break;
839
- case cls.EVENT_WINDOW_ALL_DAY_CLASS:
840
- labelText = this.parent.editorTitles.isAllDay;
841
- break;
842
- case cls.TIME_ZONE_CLASS:
843
- labelText = this.l10n.getConstant('timezone');
844
- break;
845
- }
846
- return labelText;
847
- }
848
-
849
- private onChange(args: ChangeEventArgs): void {
850
- if (args.event && args.event.target) {
851
- const targetSelector: string = `.${cls.EVENT_WINDOW_ALL_DAY_CLASS},.${cls.TIME_ZONE_CLASS},.${cls.EVENT_WINDOW_REPEAT_CLASS}`;
852
- const target: Element = closest(args.event.target as Element, targetSelector);
853
- if (target.classList.contains(cls.EVENT_WINDOW_ALL_DAY_CLASS)) {
854
- this.onAllDayChange(args.checked);
855
- } else if (target.classList.contains(cls.TIME_ZONE_CLASS)) {
856
- this.timezoneChangeStyle(args.checked);
857
- } else if (target.classList.contains(cls.EVENT_WINDOW_REPEAT_CLASS)) {
858
- this.onRepeatChange(args.checked);
859
- }
860
- }
861
- }
862
-
863
- private renderRepeatDialog(): void {
864
- const element: HTMLElement = createElement('div');
865
- this.repeatDialogObject = new Dialog({
866
- header: this.l10n.getConstant('recurrence'),
867
- visible: false,
868
- content: '<div class="e-rec-editor"></div>',
869
- closeOnEscape: true,
870
- width: '90%',
871
- buttons: [{
872
- click: this.repeatSaveDialog.bind(this),
873
- buttonModel: { content: this.l10n.getConstant('save'), cssClass: 'e-save', isPrimary: true }
874
- },
875
- { click: this.repeatCancelDialog.bind(this), buttonModel: { cssClass: 'e-cancel', content: this.l10n.getConstant('cancel') } }],
876
- target: this.element,
877
- animationSettings: { effect: 'Zoom' },
878
- enableRtl: this.parent.enableRtl,
879
- enableHtmlSanitizer: this.parent.enableHtmlSanitizer,
880
- isModal: true,
881
- cssClass: REPEAT_DIALOG_CLASS,
882
- open: this.repeatOpenDialog.bind(this)
883
- });
884
- this.element.appendChild(element);
885
- this.repeatDialogObject.appendTo(element);
886
- this.createRecurrenceEditor(<HTMLElement>this.repeatDialogObject.element.querySelector('.e-rec-editor'));
887
- }
888
-
889
- private loadRecurrenceEditor(): void {
890
- this.repeatDialogObject.show();
891
- if (this.recurrenceEditor && this.repeatRule) {
892
- this.recurrenceEditor.setRecurrenceRule(this.repeatRule);
893
- }
894
- }
895
-
896
- private onRepeatChange(state: boolean): void {
897
- if (state) {
898
- if (!this.repeatDialogObject) {
899
- this.renderRepeatDialog();
900
- }
901
- this.recurrenceEditor.setProperties({ startDate: <Date>this.repeatStartDate, selectedType: 0 });
902
- this.loadRecurrenceEditor();
903
- } else {
904
- if (this.repeatDialogObject) {
905
- this.repeatDialogObject.hide();
906
- }
907
- this.repeatRule = '';
908
- if (this.recurrenceEditor) {
909
- this.recurrenceEditor.setRecurrenceRule(this.repeatRule);
910
- this.updateRepeatLabel(this.repeatRule);
911
- }
912
- const element: HTMLElement = <HTMLElement>this.element.querySelector('.' + REPEAT_CONTAINER_CLASS);
913
- addClass([element], HIDE_STYLE_CLASS);
914
- }
915
- }
916
-
917
- private repeatSaveDialog(): void {
918
- this.repeatRule = this.recurrenceEditor.getRecurrenceRule();
919
- const element: HTMLElement = <HTMLElement>this.element.querySelector('.' + REPEAT_CONTAINER_CLASS);
920
- if (this.recurrenceEditor.getRecurrenceRule()) {
921
- removeClass([element], HIDE_STYLE_CLASS);
922
- } else {
923
- addClass([element], HIDE_STYLE_CLASS);
924
- this.repeatStatus.setProperties({ checked: false });
925
- }
926
- this.updateRepeatLabel(this.repeatRule);
927
- this.closeRepeatDialog();
928
- }
929
-
930
- private closeRepeatDialog(): void {
931
- this.repeatDialogObject.hide();
932
- }
933
-
934
- private repeatCancelDialog(): void {
935
- this.closeRepeatDialog();
936
- if (this.recurrenceEditor) {
937
- this.recurrenceEditor.setRecurrenceRule(this.repeatTempRule);
938
- }
939
- if (!this.repeatTempRule) {
940
- this.repeatStatus.setProperties({ checked: false });
941
- }
942
- }
943
-
944
- private repeatOpenDialog(): void {
945
- this.repeatTempRule = this.recurrenceEditor.getRecurrenceRule();
946
- }
947
-
948
- private onCellDetailsUpdate(eventObj: Record<string, any>, repeatType: number): void {
949
- if (!this.parent.eventSettings.allowAdding) {
950
- return;
951
- }
952
- if (this.parent.isAdaptive && repeatType && !this.repeatDialogObject) {
953
- this.renderRepeatDialog();
954
- }
955
- this.element.querySelector('.' + cls.FORM_CLASS).removeAttribute('data-id');
956
- if (isNullOrUndefined(this.parent.editorHeaderTemplate)) {
957
- this.element.querySelector('.' + cls.EVENT_WINDOW_TITLE_TEXT_CLASS).innerHTML = this.l10n.getConstant('newEvent');
958
- }
959
- eventObj.Timezone = false;
960
- this.repeatStartDate = <Date>eventObj[this.fields.startTime];
961
- this.repeatRule = '';
962
- if (!isNullOrUndefined(this.parent.eventSettings.fields.subject.default)) {
963
- eventObj[this.fields.subject] = this.parent.eventSettings.fields.subject.default;
964
- }
965
- if (!isNullOrUndefined(this.parent.eventSettings.fields.location.default)) {
966
- eventObj[this.fields.location] = this.parent.eventSettings.fields.location.default;
967
- }
968
- if (!isNullOrUndefined(this.parent.eventSettings.fields.description.default)) {
969
- eventObj[this.fields.description] = this.parent.eventSettings.fields.description.default;
970
- }
971
- this.showDetails(eventObj);
972
- if (eventObj[this.fields.recurrenceRule] && this.recurrenceEditor) {
973
- this.recurrenceEditor.setRecurrenceRule(<string>eventObj[this.fields.recurrenceRule], <Date>eventObj[this.fields.startTime]);
974
- this.repeatRule = <string>eventObj[this.fields.recurrenceRule];
975
- }
976
- const deleteButton: Element = this.element.querySelector('.' + cls.DELETE_EVENT_CLASS);
977
- if (deleteButton) {
978
- addClass([deleteButton], cls.DISABLE_CLASS);
979
- }
980
- if (this.recurrenceEditor) {
981
- this.recurrenceEditor.setProperties({
982
- startDate: <Date>eventObj[this.fields.startTime],
983
- selectedType: !isNullOrUndefined(repeatType) ? repeatType : !isNullOrUndefined(eventObj[this.fields.recurrenceRule]) ?
984
- this.recurrenceEditor.selectedType : 0
985
- });
986
- this.repeatRule = this.recurrenceEditor.value;
987
- }
988
- if (this.parent.isAdaptive && isNullOrUndefined(this.parent.editorTemplate)) {
989
- const element: HTMLElement = <HTMLElement>this.element.querySelector('.' + REPEAT_CONTAINER_CLASS);
990
- if (eventObj[this.fields.recurrenceRule] || repeatType) {
991
- removeClass([element], HIDE_STYLE_CLASS);
992
- this.repeatStatus.setProperties({ checked: true });
993
- }
994
- else {
995
- addClass([element], HIDE_STYLE_CLASS);
996
- this.repeatStatus.setProperties({ checked: false });
997
- }
998
- this.updateRepeatLabel(this.repeatRule);
999
- } else {
1000
- const saveButton: Element = this.element.querySelector('.' + cls.EVENT_WINDOW_SAVE_BUTTON_CLASS);
1001
- this.disableButton(saveButton, false);
1002
- }
1003
- this.dialogObject.show();
1004
- }
1005
-
1006
- public convertToEventData(cellsData: Record<string, any>, eventObj: Record<string, any>): void {
1007
- if (!cellsData) { return; }
1008
- if (cellsData.subject) {
1009
- eventObj[this.fields.subject] = cellsData.subject;
1010
- }
1011
- eventObj[this.fields.startTime] = cellsData.startTime;
1012
- eventObj[this.fields.endTime] = cellsData.endTime;
1013
- eventObj[this.fields.isAllDay] = cellsData.isAllDay;
1014
- if (cellsData.RecurrenceRule) {
1015
- eventObj[this.fields.recurrenceRule] = cellsData.RecurrenceRule;
1016
- }
1017
- if (this.parent.resourceCollection.length > 0 || this.parent.activeViewOptions.group.resources.length > 0) {
1018
- this.parent.resourceBase.setResourceValues(eventObj);
1019
- }
1020
- }
1021
-
1022
- private applyFormValidation(): void {
1023
- const form: HTMLFormElement = this.element.querySelector('.' + cls.FORM_CLASS) as HTMLFormElement;
1024
- if (!form) {
1025
- return;
1026
- }
1027
- const getValidationRule: CallbackFunction = (rules: Record<string, any>) =>
1028
- (rules && Object.keys(rules).length > 0) ? rules : undefined;
1029
- const rules: Record<string, any> = {};
1030
- const subjectRule: Record<string, any> = getValidationRule(this.parent.eventSettings.fields.subject.validation);
1031
- if (!isNullOrUndefined(subjectRule)) {
1032
- rules[this.parent.eventSettings.fields.subject.name] = subjectRule;
1033
- }
1034
- const locationRule: Record<string, any> = getValidationRule(this.parent.eventSettings.fields.location.validation);
1035
- if (!isNullOrUndefined(locationRule)) {
1036
- rules[this.parent.eventSettings.fields.location.name] = locationRule;
1037
- }
1038
- const startTimeRule: Record<string, any> = getValidationRule(this.parent.eventSettings.fields.startTime.validation);
1039
- if (!isNullOrUndefined(startTimeRule)) {
1040
- rules[this.parent.eventSettings.fields.startTime.name] = startTimeRule;
1041
- }
1042
- const endTimeRule: Record<string, any> = getValidationRule(this.parent.eventSettings.fields.endTime.validation);
1043
- if (!isNullOrUndefined(endTimeRule)) {
1044
- rules[this.parent.eventSettings.fields.endTime.name] = endTimeRule;
1045
- }
1046
- const descriptionRule: Record<string, any> = getValidationRule(this.parent.eventSettings.fields.description.validation);
1047
- if (!isNullOrUndefined(descriptionRule)) {
1048
- rules[this.parent.eventSettings.fields.description.name] = descriptionRule;
1049
- }
1050
- if (this.fieldValidator) {
1051
- this.fieldValidator.destroy();
1052
- this.fieldValidator = null;
1053
- }
1054
- this.fieldValidator = new FieldValidator();
1055
- this.fieldValidator.renderFormValidator(form, rules, this.element, this.parent.locale);
1056
- }
1057
-
1058
- private showDetails(eventData: Record<string, any>): void {
1059
- this.eventData = eventData;
1060
- const eventObj: Record<string, any> = <Record<string, any>>extend({}, eventData, null, true);
1061
- const formElements: HTMLInputElement[] = this.getFormElements(cls.EVENT_WINDOW_DIALOG_CLASS);
1062
- if ((!this.cellClickAction || this.cellClickAction && !isNullOrUndefined(this.parent.editorTemplate)) &&
1063
- (<Date>eventObj[this.fields.endTime]).getHours() === 0 && (<Date>eventObj[this.fields.endTime]).getMinutes() === 0) {
1064
- this.trimAllDay(eventObj);
1065
- }
1066
- const keyNames: string[] = Object.keys(eventObj);
1067
- for (const curElement of formElements) {
1068
- const columnName: string = curElement.name || this.getColumnName(curElement);
1069
- if (!isNullOrUndefined(columnName) && columnName !== '') {
1070
- if (keyNames.indexOf(columnName) !== -1) {
1071
- this.setValueToElement(curElement as HTMLElement, eventObj[`${columnName}`] as string);
1072
- } else {
1073
- this.setDefaultValueToElement(curElement as HTMLElement);
1074
- }
1075
- }
1076
- }
1077
- if (isNullOrUndefined(this.parent.editorTemplate)) {
1078
- this.onAllDayChange(eventObj[this.fields.isAllDay] as boolean);
1079
- const timezoneObj: CheckBox = this.getInstance(cls.TIME_ZONE_CLASS + '.' + EVENT_FIELD) as unknown as CheckBox;
1080
- if (!(isNullOrUndefined(eventObj[this.fields.startTimezone]) && isNullOrUndefined(eventObj[this.fields.endTimezone]))) {
1081
- timezoneObj.checked = true;
1082
- timezoneObj.dataBind();
1083
- }
1084
- this.timezoneChangeStyle(timezoneObj.checked);
1085
- delete eventObj.Timezone;
1086
- }
1087
- }
1088
-
1089
- private getColumnName(element: HTMLInputElement): string {
1090
- let attrName: string = element.getAttribute('data-name') || '';
1091
- if (attrName === '') {
1092
- let isDropDowns: boolean = false;
1093
- let fieldSelector: string = '';
1094
- if (element.classList.contains('e-dropdownlist')) {
1095
- fieldSelector = 'e-ddl';
1096
- isDropDowns = true;
1097
- } else if (element.classList.contains('e-multiselect')) {
1098
- fieldSelector = 'e-multiselect';
1099
- isDropDowns = true;
1100
- } else if (element.classList.contains('e-datetimepicker')) {
1101
- fieldSelector = 'e-datetimepicker';
1102
- } else if (element.classList.contains('e-datepicker')) {
1103
- fieldSelector = 'e-datepicker';
1104
- } else if (element.classList.contains('e-checkbox')) {
1105
- fieldSelector = 'e-checkbox';
1106
- } else if (element.classList.contains('e-numerictextbox')) {
1107
- fieldSelector = 'e-numerictextbox';
1108
- }
1109
- const classSelector: string = isDropDowns ? `.${fieldSelector}:not(.e-control)` : `.${fieldSelector}`;
1110
- const control: Element = closest(element, classSelector) || element.querySelector(`.${fieldSelector}`);
1111
- if (control) {
1112
- const attrEle: Element = control.querySelector('[name]');
1113
- if (attrEle) {
1114
- attrName = (<HTMLInputElement>attrEle).name;
1115
- }
1116
- }
1117
- }
1118
- return attrName;
1119
- }
1120
-
1121
- private onAllDayChange(allDayStatus: boolean): void {
1122
- const startObj: DateTimePicker = this.getInstance(cls.EVENT_WINDOW_START_CLASS) as unknown as DateTimePicker;
1123
- const endObj: DateTimePicker = this.getInstance(cls.EVENT_WINDOW_END_CLASS) as unknown as DateTimePicker;
1124
- const timezoneDiv: HTMLElement = this.element.querySelector('.e-time-zone-container') as HTMLElement;
1125
- let format: string;
1126
- if (allDayStatus) {
1127
- format = (isNullOrUndefined(this.parent.dateFormat)) ? this.getFormat('dateFormats') : this.parent.dateFormat;
1128
- addClass(this.element.querySelectorAll('.e-time-icon'), cls.EVENT_WINDOW_ICON_DISABLE_CLASS);
1129
- addClass([timezoneDiv], cls.DISABLE_CLASS);
1130
- if (this.element.querySelector('.' + cls.EVENT_WINDOW_TIME_ZONE_DIV_CLASS)) {
1131
- removeClass([this.element.querySelector('.' + cls.EVENT_WINDOW_TIME_ZONE_DIV_CLASS)], cls.ENABLE_CLASS);
1132
- }
1133
- startObj.format = endObj.format = format;
1134
- } else {
1135
- format = (isNullOrUndefined(this.parent.dateFormat)) ? this.getFormat('dateFormats') + ' ' +
1136
- this.parent.activeViewOptions.timeFormat : this.parent.dateFormat + ' ' + this.parent.activeViewOptions.timeFormat;
1137
- removeClass(this.element.querySelectorAll('.e-time-icon'), cls.EVENT_WINDOW_ICON_DISABLE_CLASS);
1138
- removeClass([timezoneDiv], cls.DISABLE_CLASS);
1139
- if ((this.element.querySelector('.e-checkbox-wrapper .e-time-zone') as HTMLInputElement).checked) {
1140
- addClass([this.element.querySelector('.' + cls.EVENT_WINDOW_TIME_ZONE_DIV_CLASS)], cls.ENABLE_CLASS);
1141
- }
1142
- startObj.format = endObj.format = format;
1143
- }
1144
- if (this.cellClickAction) { this.updateDateTime(allDayStatus, startObj, endObj); }
1145
- startObj.dataBind();
1146
- endObj.dataBind();
1147
- if (!isNullOrUndefined(this.recurrenceEditor)) {
1148
- this.recurrenceEditor.updateRuleUntilDate(startObj.value);
1149
- }
1150
- }
1151
-
1152
- private updateDateTime(allDayStatus: boolean, startObj: DateTimePicker, endObj: DateTimePicker): void {
1153
- let startDate: Date; let endDate: Date;
1154
- if (isNullOrUndefined(this.eventWindowTime.startTime) && isNullOrUndefined(this.eventWindowTime.endTime)) { return; }
1155
- if (allDayStatus) {
1156
- startDate = util.resetTime(new Date(this.eventWindowTime.startTime.getTime()));
1157
- if (this.parent.activeCellsData.isAllDay) {
1158
- const temp: number = util.addDays(new Date((<Date>this.eventWindowTime.endTime).getTime()), -1).getTime();
1159
- endDate = (+this.eventWindowTime.startTime > temp) ? this.eventWindowTime.endTime : new Date(temp);
1160
- } else {
1161
- endDate = util.resetTime(new Date(this.eventWindowTime.endTime.getTime()));
1162
- }
1163
- } else {
1164
- const start: Date = this.parent.activeCellsData.startTime;
1165
- startDate = new Date(this.eventWindowTime.startTime.getTime());
1166
- startDate.setHours(start.getHours(), start.getMinutes(), start.getSeconds());
1167
- if (this.parent.activeCellsData.isAllDay) {
1168
- const startHour: Date = this.parent.getStartEndTime(this.parent.workHours.start);
1169
- startDate.setHours(startHour.getHours(), startHour.getMinutes(), startHour.getSeconds());
1170
- endDate = new Date(startDate.getTime());
1171
- endDate.setMilliseconds(util.MS_PER_MINUTE * this.getSlotDuration());
1172
- } else {
1173
- endDate = new Date(startDate.getTime());
1174
- endDate.setMilliseconds(this.parent.activeCellsData.endTime.getTime() - this.parent.activeCellsData.startTime.getTime());
1175
- }
1176
- }
1177
- this.eventWindowTime = { startTime: new Date(startDate.getTime()), endTime: new Date(endDate.getTime()) };
1178
- startObj.value = startDate;
1179
- endObj.value = endDate;
1180
- startObj.dataBind();
1181
- endObj.dataBind();
1182
- }
1183
-
1184
- private getFormat(formatType: string): string {
1185
- let format: string;
1186
- if (isNullOrUndefined(this.parent.locale) || this.parent.locale === 'en' || this.parent.locale === 'en-US') {
1187
- format = getValue(formatType + '.short', getDefaultDateObject(this.parent.getCalendarMode()));
1188
- } else {
1189
- format = getValue(`main.${this.parent.locale}.dates.calendars.${this.parent.getCalendarMode()}.${formatType}.short`, cldrData);
1190
- }
1191
- return format;
1192
- }
1193
-
1194
- private onEventDetailsUpdate(eventObj: Record<string, any>): void {
1195
- if (!this.parent.eventSettings.allowEditing) {
1196
- return;
1197
- }
1198
- if (!this.parent.isAdaptive && isNullOrUndefined(this.parent.editorFooterTemplate)) {
1199
- removeClass([this.element.querySelector('.' + cls.DELETE_EVENT_CLASS)], cls.DISABLE_CLASS);
1200
- }
1201
- if (isNullOrUndefined(this.parent.editorHeaderTemplate)) {
1202
- this.element.querySelector('.' + cls.EVENT_WINDOW_TITLE_TEXT_CLASS).innerHTML = this.l10n.getConstant('editEvent');
1203
- }
1204
- this.element.querySelector('.' + cls.FORM_CLASS).setAttribute('data-id', eventObj[this.fields.id].toString());
1205
- if (isNullOrUndefined(this.parent.editorTemplate)) {
1206
- eventObj = <Record<string, any>>extend({}, eventObj, null, true);
1207
- const timezoneObj: CheckBox = this.getInstance(cls.TIME_ZONE_CLASS + '.' + EVENT_FIELD) as unknown as CheckBox;
1208
- let timezoneValue: boolean;
1209
- if (eventObj[this.fields.startTimezone] || eventObj[this.fields.endTimezone]) {
1210
- timezoneValue = true;
1211
- this.parent.eventBase.timezoneConvert(eventObj);
1212
- } else {
1213
- timezoneValue = false;
1214
- }
1215
- eventObj.Timezone = timezoneValue;
1216
- timezoneObj.checked = timezoneValue;
1217
- timezoneObj.dataBind();
1218
- }
1219
- this.showDetails(eventObj);
1220
- if (eventObj[this.fields.recurrenceRule] && this.recurrenceEditor) {
1221
- this.recurrenceEditor.setRecurrenceRule(<string>eventObj[this.fields.recurrenceRule], <Date>eventObj[this.fields.startTime]);
1222
- } else if (!this.parent.isAdaptive && this.recurrenceEditor) {
1223
- this.recurrenceEditor.setProperties({ startDate: eventObj[this.fields.startTime] });
1224
- this.recurrenceEditor.setRecurrenceRule('');
1225
- }
1226
- this.repeatStartDate = <Date>eventObj[this.fields.startTime];
1227
- this.repeatRule = '';
1228
- if (eventObj[this.fields.recurrenceRule]) {
1229
- if (this.recurrenceEditor) {
1230
- this.recurrenceEditor.setRecurrenceRule(
1231
- <string>eventObj[this.fields.recurrenceRule], <Date>eventObj[this.fields.startTime]);
1232
- }
1233
- this.repeatRule = <string>eventObj[this.fields.recurrenceRule];
1234
- }
1235
- if (this.parent.isAdaptive && isNullOrUndefined(this.parent.editorTemplate)) {
1236
- const element: HTMLElement = <HTMLElement>this.element.querySelector('.' + REPEAT_CONTAINER_CLASS);
1237
- if (eventObj[this.fields.recurrenceRule]) {
1238
- removeClass([element], HIDE_STYLE_CLASS);
1239
- this.repeatStatus.setProperties({ checked: true });
1240
- } else {
1241
- addClass([element], HIDE_STYLE_CLASS);
1242
- this.repeatStatus.setProperties({ checked: false });
1243
- }
1244
- this.updateRepeatLabel(this.repeatRule);
1245
- }
1246
- const isDisable: boolean = (this.parent.readonly || eventObj[this.fields.isReadonly]) as boolean;
1247
- if (!this.parent.isAdaptive) {
1248
- const saveButton: Element = this.element.querySelector('.' + cls.EVENT_WINDOW_SAVE_BUTTON_CLASS);
1249
- const deleteButton: Element = this.element.querySelector('.' + cls.DELETE_EVENT_CLASS);
1250
- this.disableButton(saveButton, isDisable);
1251
- this.disableButton(deleteButton, isDisable);
1252
- } else {
1253
- const saveIcon: Element = this.element.querySelector('.' + cls.EVENT_WINDOW_SAVE_ICON_CLASS);
1254
- if (saveIcon) {
1255
- if (isDisable) {
1256
- addClass([saveIcon], cls.ICON_DISABLE_CLASS);
1257
- } else {
1258
- removeClass([saveIcon], cls.ICON_DISABLE_CLASS);
1259
- }
1260
- }
1261
- }
1262
- this.dialogObject.show();
1263
- }
1264
-
1265
- private disableButton(element: Element, value: boolean): void {
1266
- if (element) {
1267
- ((element as EJ2Instance).ej2_instances[0] as Button).disabled = value;
1268
- }
1269
- }
1270
-
1271
- private renderRecurrenceEditor(): RecurrenceEditor {
1272
- return new RecurrenceEditor({
1273
- calendarMode: this.parent.calendarMode,
1274
- cssClass: this.parent.cssClass,
1275
- dateFormat: this.parent.dateFormat,
1276
- enableRtl: this.parent.enableRtl,
1277
- firstDayOfWeek: this.parent.activeViewOptions.firstDayOfWeek,
1278
- locale: this.parent.locale
1279
- });
1280
- }
1281
-
1282
- public updateMinMaxDateToEditor(): void {
1283
- const startDate: Element = this.element.querySelector('.e-start');
1284
- const endDate: Element = this.element.querySelector('.e-end');
1285
- if (startDate && endDate) {
1286
- const startObj: DatePicker = (startDate as EJ2Instance).ej2_instances[0] as DatePicker;
1287
- const endObj: DatePicker = (endDate as EJ2Instance).ej2_instances[0] as DatePicker;
1288
- startObj.min = this.parent.minDate;
1289
- startObj.max = new Date(new Date(+this.parent.maxDate).setHours(23, 59, 59));
1290
- endObj.min = this.parent.minDate;
1291
- endObj.max = new Date(new Date(+this.parent.maxDate).setHours(23, 59, 59));
1292
- startObj.dataBind();
1293
- endObj.dataBind();
1294
- }
1295
- if (this.recurrenceEditor) {
1296
- const untilDate: Element = this.recurrenceEditor.element.querySelector('.e-until-date');
1297
- if (untilDate) {
1298
- const untilObj: DatePicker = (untilDate as EJ2Instance).ej2_instances[0] as DatePicker;
1299
- untilObj.min = this.parent.minDate;
1300
- untilObj.max = this.parent.maxDate;
1301
- untilObj.dataBind();
1302
- }
1303
- }
1304
- }
1305
-
1306
- private updateRepeatLabel(repeatRule: string): void {
1307
- if (this.parent.isAdaptive && !this.repeatDialogObject) {
1308
- this.renderRepeatDialog();
1309
- }
1310
- const data: string = repeatRule ?
1311
- (this.l10n.getConstant('repeats') + ' ' + this.recurrenceEditor.getRuleSummary(repeatRule)) : this.l10n.getConstant('repeat');
1312
- this.repeatStatus.setProperties({ label: data });
1313
- }
1314
-
1315
- public dialogClose(event?: Event): void {
1316
- if (this.isEnterKey) {
1317
- this.isEnterKey = false;
1318
- return;
1319
- }
1320
- this.dialogEvent = event;
1321
- this.isCrudAction = false;
1322
- this.parent.activeEventData = { event: undefined, element: undefined };
1323
- this.parent.currentAction = null;
1324
- this.dialogObject.hide();
1325
- }
1326
-
1327
- private resetForm(): void {
1328
- this.fieldValidator.destroyToolTip();
1329
- this.resetFormFields();
1330
- if (!this.parent.isAdaptive && this.recurrenceEditor && !this.recurrenceEditor.isDestroyed) {
1331
- this.recurrenceEditor.resetFields();
1332
- }
1333
- }
1334
-
1335
- private timezoneChangeStyle(value: boolean): void {
1336
- const timezoneDiv: HTMLElement = this.element.querySelector('.' + cls.EVENT_WINDOW_TIME_ZONE_DIV_CLASS) as HTMLElement;
1337
- const localTimezoneName: string = this.parent.tzModule.getLocalTimezoneName();
1338
- if (value) {
1339
- addClass([timezoneDiv], cls.ENABLE_CLASS);
1340
- const startTimezoneObj: DropDownList = this.getInstance(cls.EVENT_WINDOW_START_TZ_CLASS) as unknown as DropDownList;
1341
- const endTimezoneObj: DropDownList = this.getInstance(cls.EVENT_WINDOW_END_TZ_CLASS) as unknown as DropDownList;
1342
- const timezone: Record<string, any>[] = startTimezoneObj.dataSource as Record<string, any>[];
1343
- if (!startTimezoneObj.value || !this.parent.timezone) {
1344
- const found: boolean = timezone.some((tz: Record<string, any>) => { return tz.Value === localTimezoneName; });
1345
- if (!found) {
1346
- timezone.push({ Value: localTimezoneName, Text: localTimezoneName });
1347
- startTimezoneObj.dataSource = timezone;
1348
- endTimezoneObj.dataSource = timezone;
1349
- startTimezoneObj.dataBind();
1350
- endTimezoneObj.dataBind();
1351
- }
1352
- }
1353
- startTimezoneObj.value = startTimezoneObj.value || this.parent.timezone || localTimezoneName;
1354
- endTimezoneObj.value = endTimezoneObj.value || this.parent.timezone || localTimezoneName;
1355
- startTimezoneObj.dataBind();
1356
- endTimezoneObj.dataBind();
1357
- } else {
1358
- removeClass([timezoneDiv], cls.ENABLE_CLASS);
1359
- }
1360
- }
1361
-
1362
- private resetFormFields(): void {
1363
- const formElement: HTMLInputElement[] = this.getFormElements(cls.EVENT_WINDOW_DIALOG_CLASS);
1364
- for (const currentElement of formElement) {
1365
- const columnName: string = currentElement.name || this.getColumnName(currentElement);
1366
- if (!isNullOrUndefined(columnName) && columnName !== '') {
1367
- this.setDefaultValueToElement(currentElement as HTMLElement);
1368
- }
1369
- }
1370
- }
1371
-
1372
- public eventSave(event: Event, alert?: string): void {
1373
- if (this.isEnterKey) {
1374
- this.isEnterKey = false;
1375
- return;
1376
- }
1377
- const formElement: Element = this.element.querySelector('.' + cls.FORM_CLASS);
1378
- if (formElement && formElement.classList.contains('e-formvalidator') &&
1379
- !((formElement as EJ2Instance).ej2_instances[0] as FormValidator).validate()) {
1380
- return;
1381
- }
1382
- const dataCollection: Record<string, Record<string, any>> = this.getEventDataFromEditor();
1383
- if (this.processEventValidation(dataCollection.tempData, alert)) {
1384
- return;
1385
- }
1386
- this.eventCrudData = dataCollection.eventData;
1387
- this.dialogEvent = event;
1388
- this.isCrudAction = true;
1389
- this.dialogObject.hide();
1390
- }
1391
-
1392
- public getEventDataFromEditor(): Record<string, Record<string, any>> {
1393
- const eventObj: Record<string, any> =
1394
- extend({}, this.getObjectFromFormData(cls.EVENT_WINDOW_DIALOG_CLASS)) as Record<string, any>;
1395
- if (!eventObj.Timezone) {
1396
- eventObj[this.fields.startTimezone] = null;
1397
- eventObj[this.fields.endTimezone] = null;
1398
- }
1399
- delete eventObj.Timezone;
1400
- delete eventObj.Repeat;
1401
- this.setDefaultValueToObject(eventObj);
1402
- eventObj[this.fields.recurrenceRule] = this.recurrenceEditor ? this.recurrenceEditor.getRecurrenceRule() || null : undefined;
1403
- const tempObj: Record<string, any> = extend({}, eventObj, null, true) as Record<string, any>;
1404
- if (eventObj[this.fields.isAllDay]) {
1405
- eventObj[this.fields.startTime] = (isNullOrUndefined(eventObj[this.fields.startTime])) ? null
1406
- : util.resetTime(new Date((<Date>eventObj[this.fields.startTime]).getTime()));
1407
- eventObj[this.fields.endTime] = (isNullOrUndefined(eventObj[this.fields.endTime])) ? null
1408
- : util.addDays(util.resetTime(new Date((<Date>eventObj[this.fields.endTime]).getTime())), 1);
1409
- }
1410
- return { eventData: eventObj, tempData: tempObj };
1411
- }
1412
-
1413
- private processEventValidation(eventObj: Record<string, any>, alert?: string): boolean {
1414
- let alertType: string;
1415
- if (isNullOrUndefined(this.parent.editorTemplate)) {
1416
- if (!eventObj[this.fields.startTime] || !eventObj[this.fields.endTime]) {
1417
- this.parent.quickPopup.openValidationError('invalidDateError');
1418
- return true;
1419
- }
1420
- if (eventObj[this.fields.startTime] > eventObj[this.fields.endTime]) {
1421
- this.parent.quickPopup.openValidationError('startEndError');
1422
- return true;
1423
- }
1424
- }
1425
- if (this.recurrenceEditor && this.recurrenceEditor.value && this.recurrenceEditor.value !== '') {
1426
- if (this.parent.currentAction !== 'EditOccurrence') {
1427
- alertType = this.recurrenceValidation(<Date>eventObj[this.fields.startTime], <Date>eventObj[this.fields.endTime], alert);
1428
- }
1429
- let isShowAlert: boolean = true;
1430
- if (alertType === 'seriesChangeAlert' && this.parent.uiStateValues.isIgnoreOccurrence) {
1431
- isShowAlert = false;
1432
- }
1433
- if (!isNullOrUndefined(alertType) && isShowAlert
1434
- && ((!this.parent.enableRecurrenceValidation && alertType === 'wrongPattern') || this.parent.enableRecurrenceValidation)) {
1435
- this.parent.quickPopup.openRecurrenceValidationAlert(alertType);
1436
- return true;
1437
- }
1438
- }
1439
- return false;
1440
- }
1441
-
1442
- private processCrudActions(eventObj: Record<string, any>): boolean {
1443
- this.parent.uiStateValues.isBlock = false;
1444
- const resourceData: string[] | number[] = this.getResourceData(eventObj);
1445
- const isResourceEventExpand: boolean = (this.parent.activeViewOptions.group.resources.length > 0 ||
1446
- this.parent.resourceCollection.length > 0) && !this.parent.activeViewOptions.group.allowGroupEdit
1447
- && !isNullOrUndefined(resourceData);
1448
- const eventId: string = this.getEventIdFromForm();
1449
- if (!isNullOrUndefined(eventId)) {
1450
- let eveId: number | string = this.parent.eventBase.getEventIDType() === 'string' ? eventId : parseInt(eventId, 10);
1451
- let editedData: Record<string, any> = this.parent.eventsData.filter((data: Record<string, any>) =>
1452
- data[this.fields.id] === eveId)[0];
1453
- if (isNullOrUndefined(editedData)) {
1454
- editedData = this.parent.blockData.filter((data: Record<string, any>) =>
1455
- data[this.fields.id] === eveId)[0];
1456
- }
1457
- eventObj = extend({}, editedData, eventObj) as Record<string, any>;
1458
- if (eventObj[this.fields.isReadonly]) {
1459
- return false;
1460
- }
1461
- if (this.parent.eventBase.checkOverlap(eventObj)) {
1462
- return true;
1463
- }
1464
- let currentAction: CurrentAction;
1465
- if (!isNullOrUndefined(editedData[this.fields.recurrenceRule])) {
1466
- currentAction = this.parent.currentAction;
1467
- eventObj.Guid = (<Record<string, any>>this.parent.activeEventData.event).Guid;
1468
- if (this.parent.currentAction === 'EditOccurrence') {
1469
- if (!eventObj[this.fields.recurrenceID]) {
1470
- eventObj[this.fields.id] = this.parent.eventBase.getEventMaxID();
1471
- eventObj.Guid = (<Record<string, any>>this.parent.activeEventData.event).Guid;
1472
- } else {
1473
- eveId = eventObj[this.fields.recurrenceID] as number;
1474
- currentAction = null;
1475
- }
1476
- if (this.parent.enableRecurrenceValidation && this.editOccurrenceValidation(eveId, eventObj)) {
1477
- return true;
1478
- }
1479
- }
1480
- if (this.parent.currentAction === 'EditSeries' || eventObj[this.fields.id] !== editedData[this.fields.id]) {
1481
- eventObj[this.fields.recurrenceID] = editedData[this.fields.id];
1482
- } else if (this.parent.currentAction === 'EditFollowingEvents') {
1483
- eventObj[this.fields.id] = this.parent.eventBase.getEventMaxID();
1484
- eventObj[this.fields.followingID] = editedData[this.fields.id];
1485
- }
1486
- }
1487
- if (isResourceEventExpand) {
1488
- this.resourceSaveEvent(eventObj, 'Save', currentAction);
1489
- } else {
1490
- this.parent.saveEvent(eventObj, currentAction);
1491
- }
1492
- } else {
1493
- this.parent.currentAction = 'Add';
1494
- if (this.parent.eventBase.checkOverlap(eventObj)) {
1495
- return true;
1496
- }
1497
- if (isResourceEventExpand) {
1498
- this.resourceSaveEvent(eventObj, this.parent.currentAction);
1499
- } else {
1500
- eventObj[this.fields.id] = this.parent.eventBase.getEventMaxID();
1501
- this.parent.addEvent(eventObj);
1502
- }
1503
- }
1504
- return this.parent.uiStateValues.isBlock;
1505
- }
1506
-
1507
- private getResourceData(eventObj: Record<string, any>): string[] | number[] {
1508
- let resourceData: string[] | number[] = null;
1509
- if (!isNullOrUndefined(this.parent.resourceBase) && !isNullOrUndefined(this.parent.resourceBase.resourceCollection)
1510
- && this.parent.resourceBase.resourceCollection.length > 0) {
1511
- const lastResourceData: ResourcesModel = this.parent.resourceBase.resourceCollection.slice(-1)[0];
1512
- resourceData = eventObj[lastResourceData.field] as string[] | number[];
1513
- }
1514
- return resourceData;
1515
- }
1516
-
1517
- public getObjectFromFormData(className: string): Record<string, any> {
1518
- const formElement: HTMLInputElement[] = this.getFormElements(className);
1519
- const eventObj: Record<string, any> = {};
1520
- for (const currentElement of formElement) {
1521
- const columnName: string = currentElement.name || this.getColumnName(currentElement);
1522
- if (!isNullOrUndefined(columnName) && columnName !== '') {
1523
- eventObj[`${columnName}`] = this.getValueFromElement(currentElement as HTMLElement);
1524
- }
1525
- }
1526
- return eventObj;
1527
- }
1528
-
1529
- public setDefaultValueToObject(eventObj: Record<string, any>): void {
1530
- if (!isNullOrUndefined(eventObj[this.fields.subject])) {
1531
- eventObj[this.fields.subject] = eventObj[this.fields.subject] || this.parent.eventSettings.fields.subject.default
1532
- || this.l10n.getConstant('addTitle');
1533
- }
1534
- if (!isNullOrUndefined(eventObj[this.fields.location])) {
1535
- eventObj[this.fields.location] = eventObj[this.fields.location] || this.parent.eventSettings.fields.location.default;
1536
- }
1537
- if (!isNullOrUndefined(eventObj[this.fields.description])) {
1538
- eventObj[this.fields.description] = eventObj[this.fields.description] || this.parent.eventSettings.fields.description.default;
1539
- }
1540
- }
1541
-
1542
- private recurrenceValidation(startDate: Date, endDate: Date, alert: string): string {
1543
- let alertMessage: string;
1544
- const recEditor: RecurrenceEditor = this.recurrenceEditor;
1545
- const interval: number = (this.getInstance('e-repeat-interval.e-numerictextbox') as unknown as NumericTextBox).value;
1546
- if (alert !== this.l10n.getConstant('ok')) {
1547
- const activeEvent: Record<string, any> = <Record<string, any>>this.parent.activeEventData.event;
1548
- let excludedEvents: Record<string, any>[] = [];
1549
- if ((this.parent.currentAction === 'EditSeries' || this.parent.currentAction === 'EditFollowingEvents')
1550
- && !isNullOrUndefined(activeEvent)) {
1551
- const eventStartTime: string = activeEvent[this.parent.eventFields.startTime] as string;
1552
- const seriesEvents: Record<string, any>[] = this.parent.eventBase.getSeriesEvents(this.eventData, eventStartTime);
1553
- if (seriesEvents.length > 0) {
1554
- excludedEvents = this.parent.eventBase.getEditedOccurrences(seriesEvents, eventStartTime);
1555
- } else {
1556
- const event: Record<string, any> = this.parent.eventBase.getEventById(
1557
- activeEvent[this.parent.eventFields.id] as string);
1558
- excludedEvents = this.parent.eventBase.getEditedOccurrences([event], eventStartTime);
1559
- }
1560
- if (this.parent.currentAction === 'EditSeries'
1561
- && !isNullOrUndefined(this.eventData[this.parent.eventFields.recurrenceException])) {
1562
- excludedEvents.push(this.eventData);
1563
- }
1564
- }
1565
- if (excludedEvents.length > 0) {
1566
- alertMessage = 'seriesChangeAlert';
1567
- }
1568
- if ((this.getInstance('e-end-on-left .e-ddl .e-dropdownlist') as unknown as DropDownList).value === 'until' &&
1569
- (this.getInstance('e-end-on-date .e-datepicker') as unknown as DatePicker).value < startDate) {
1570
- alertMessage = 'wrongPattern';
1571
- }
1572
- if (isNullOrUndefined(alertMessage)) {
1573
- let types: string[] = recEditor.value.split(';')[1].split('=')[1].split(',');
1574
- const obj: Record<string, any> = { 'SU': 0, 'MO': 1, 'TU': 2, 'WE': 3, 'TH': 4, 'FR': 5, 'SA': 6 };
1575
- const temp: number[] = [];
1576
- const tempDiff: number[] = [];
1577
- let tempValue: number[];
1578
- switch (recEditor.value.split(';')[0].split('=')[1]) {
1579
- case 'DAILY':
1580
- if ((((endDate.getTime() - startDate.getTime()) / (1000 * 3600)) > (interval * 24))) {
1581
- alertMessage = 'createError';
1582
- }
1583
- break;
1584
- case 'WEEKLY':
1585
- types = recEditor.value.split(';')[1].split('=')[1].split(',');
1586
- for (let index: number = 0; index < types.length * (interval + 1); index++) {
1587
- temp[parseInt(index.toString(), 10)] =
1588
- (types.length > index) ? <number>obj[types[parseInt(index.toString(), 10)]] :
1589
- temp[index - types.length] + (7 * interval);
1590
- }
1591
- tempValue = temp.sort((a: number, b: number) => a - b);
1592
- for (let index: number = 1; index < tempValue.length; index++) {
1593
- tempDiff.push(tempValue[parseInt(index.toString(), 10)] - tempValue[index - 1]);
1594
- }
1595
- if ((((endDate.getTime() - startDate.getTime()) / (1000 * 3600)) >= Math.min(...tempDiff) * 24)
1596
- || isNullOrUndefined(interval)) {
1597
- alertMessage = 'createError';
1598
- }
1599
- break;
1600
- case 'MONTHLY':
1601
- if (endDate.getTime() >= new Date(+startDate).setMonth(startDate.getMonth() + interval)) {
1602
- alertMessage = 'createError';
1603
- }
1604
- break;
1605
- case 'YEARLY':
1606
- if (endDate.getTime() >= new Date(+startDate).setFullYear(startDate.getFullYear() + interval)) {
1607
- alertMessage = 'createError';
1608
- }
1609
- break;
1610
- }
1611
- }
1612
- } else {
1613
- if (endDate.getTime() >= new Date(+startDate).setMonth(startDate.getMonth() + interval)) {
1614
- alertMessage = 'createError';
1615
- }
1616
- if (isNullOrUndefined(alertMessage)) {
1617
- this.parent.quickPopup.quickDialog.hide();
1618
- }
1619
- }
1620
- if (isNullOrUndefined(interval)) {
1621
- alertMessage = 'createError';
1622
- }
1623
- return alertMessage;
1624
- }
1625
-
1626
- private getRecurrenceIndex(recColl: Record<string, any>[], event: Record<string, any>): number {
1627
- let recIndex: number;
1628
- for (let index: number = 0; index < recColl.length; index++) {
1629
- if (event[this.fields.startTime].valueOf() === recColl[parseInt(index.toString(), 10)][this.fields.startTime].valueOf()) {
1630
- recIndex = index;
1631
- break;
1632
- }
1633
- }
1634
- return recIndex;
1635
- }
1636
-
1637
- private trimAllDay(data: Record<string, any>): void {
1638
- if (data[this.fields.isAllDay]) {
1639
- const temp: number = util.addDays(new Date(+data[this.fields.endTime]), -1).getTime();
1640
- data[this.fields.endTime] = (+data[this.fields.startTime] > temp) ? data[this.fields.endTime] : new Date(temp);
1641
- }
1642
- }
1643
-
1644
- public editOccurrenceValidation(eventId: string | number, currentData: Record<string, any>, editData?: Record<string, any>)
1645
- : boolean {
1646
- if (editData === void 0) { editData = this.eventData; }
1647
- const recurColl: Record<string, any>[] = <Record<string, any>[]>this.parent.getOccurrencesByID(eventId);
1648
- const excludedDatas: Record<string, any>[] = this.parent.eventsData.filter((data: Record<string, any>) =>
1649
- data[this.fields.recurrenceID] === eventId) as Record<string, any>[];
1650
- excludedDatas.map((data: Record<string, any>) => recurColl.push(extend({}, data) as Record<string, any>));
1651
- currentData = extend({}, currentData) as Record<string, any>;
1652
- this.trimAllDay(currentData);
1653
- for (const data of recurColl) {
1654
- this.trimAllDay(data);
1655
- }
1656
- this.parent.eventBase.sortByTime(recurColl);
1657
- const index: number = this.getRecurrenceIndex(recurColl, editData);
1658
- if (isNullOrUndefined(index)) {
1659
- return false;
1660
- }
1661
- const currentStartTime: Date = new Date(+currentData[this.fields.startTime]);
1662
- const currentEndTime: Date = new Date(+currentData[this.fields.endTime]);
1663
- let nextStartTime: Date;
1664
- let nextEndTime: Date;
1665
- if (index !== recurColl.length - 1) {
1666
- nextStartTime = new Date(+recurColl[index + 1][this.fields.startTime]);
1667
- nextEndTime = new Date(+recurColl[index + 1][this.fields.endTime]);
1668
- }
1669
- const lastEndTime: Date = new Date(+recurColl[recurColl.length - 1][this.fields.endTime]);
1670
- if (index === 0) {
1671
- if (!isNullOrUndefined(recurColl[index + 1])) {
1672
- if (!(nextStartTime.getTime() >= currentEndTime.getTime()) &&
1673
- (util.resetTime(lastEndTime).getTime() >=
1674
- util.resetTime(currentStartTime).getTime()) ||
1675
- util.resetTime(lastEndTime).getTime() < util.resetTime(currentStartTime).getTime()) {
1676
- this.parent.quickPopup.openRecurrenceValidationAlert('occurrenceAlert');
1677
- return true;
1678
- } else if (!(util.resetTime(currentStartTime).getTime() <
1679
- util.resetTime(nextStartTime).getTime())) {
1680
- this.parent.quickPopup.openRecurrenceValidationAlert('sameDayAlert');
1681
- return true;
1682
- }
1683
- }
1684
- return false;
1685
- }
1686
- else {
1687
- const previousStartTime: Date = new Date(+recurColl[index - 1][this.fields.startTime]);
1688
- const previousEndTime: Date = new Date(+recurColl[index - 1][this.fields.endTime]);
1689
- if (index === recurColl.length - 1) {
1690
- if (util.resetTime(new Date(+recurColl[(recurColl.length - 1) - index][this.fields.startTime])).getTime() >
1691
- util.resetTime(currentStartTime).getTime()) {
1692
- this.parent.quickPopup.openRecurrenceValidationAlert('occurrenceAlert');
1693
- return true;
1694
- }
1695
- else if (!((previousEndTime.getTime() <= currentStartTime.getTime()) &&
1696
- (util.resetTime(currentStartTime).getTime() > util.resetTime(previousStartTime).getTime()))) {
1697
- this.parent.quickPopup.openRecurrenceValidationAlert('sameDayAlert');
1698
- return true;
1699
- }
1700
- }
1701
- else if (!(((
1702
- util.resetTime(previousStartTime).getTime() < util.resetTime(currentStartTime).getTime()) ||
1703
- util.resetTime(new Date(+recurColl[0][this.fields.startTime])).getTime() >
1704
- util.resetTime(currentStartTime).getTime()) &&
1705
- ((util.resetTime(nextStartTime).getTime() > util.resetTime(currentStartTime).getTime()) ||
1706
- (lastEndTime.getTime() < currentStartTime.getTime())))) {
1707
- this.parent.quickPopup.openRecurrenceValidationAlert('sameDayAlert');
1708
- return true;
1709
- }
1710
- else if (!(previousEndTime.getTime() <= currentStartTime.getTime() && nextStartTime.getTime() >=
1711
- currentEndTime.getTime()) || (util.resetTime(nextEndTime).getTime() <
1712
- util.resetTime(currentStartTime).getTime()) ||
1713
- (util.resetTime(previousStartTime).getTime() > util.resetTime(currentEndTime).getTime()) ||
1714
- !(util.resetTime(currentStartTime).getTime() < util.resetTime(nextStartTime).getTime())) {
1715
- this.parent.quickPopup.openRecurrenceValidationAlert('occurrenceAlert');
1716
- return true;
1717
- }
1718
- }
1719
- return false;
1720
- }
1721
-
1722
- private resourceSaveEvent(eventObj: Record<string, any>, action?: CurrentAction, currentAction?: CurrentAction): void {
1723
- const lastResourceData: ResourcesModel = this.parent.resourceBase.resourceCollection.slice(-1)[0];
1724
- let resourceData: string[] | number[] = eventObj[lastResourceData.field] as string[] | number[];
1725
- resourceData = (resourceData instanceof Array) ? resourceData.reverse() : [resourceData].reverse();
1726
- const lastLevel: TdData[] = this.parent.resourceBase.lastResourceLevel;
1727
- const eventList: Record<string, any>[] = [];
1728
- for (let i: number = 0; i < resourceData.length; i++) {
1729
- const events: Record<string, any> = <Record<string, any>>extend({}, eventObj, null, true);
1730
- events[this.fields.id] = this.parent.eventBase.getEventMaxID();
1731
- const temp: Record<string, any>[] = [];
1732
- const addValues: CallbackFunction = () => {
1733
- if (action === 'Save' && i === resourceData.length - 1) {
1734
- if (temp.length > 0) {
1735
- temp[0][this.fields.id] = eventObj[this.fields.id];
1736
- for (let k: number = 1; k < temp.length; k++) {
1737
- temp[parseInt(k.toString(), 10)][this.fields.id] = this.parent.eventBase.getEventMaxID(i);
1738
- eventList.push(temp[parseInt(k.toString(), 10)]);
1739
- this.parent.saveEvent(temp[0], currentAction);
1740
- }
1741
- } else {
1742
- events[this.fields.id] = eventObj[this.fields.id];
1743
- this.parent.saveEvent(events, currentAction);
1744
- }
1745
- } else {
1746
- if (temp.length > 0) {
1747
- for (let j: number = 0; j < temp.length; j++) {
1748
- temp[parseInt(j.toString(), 10)][this.fields.id] = this.parent.eventBase.getEventMaxID(j);
1749
- eventList.push(temp[parseInt(j.toString(), 10)]);
1750
- }
1751
- } else {
1752
- events[this.fields.id] = this.parent.eventBase.getEventMaxID(i);
1753
- eventList.push(events);
1754
- }
1755
- }
1756
- };
1757
- if (this.parent.activeViewOptions.group.byGroupID && (!isNullOrUndefined(lastLevel))) {
1758
- const lastResource: Record<string, any>[] = lastResourceData.dataSource as Record<string, any>[];
1759
- const resCol: Record<string, any>[] = this.parent.resourceCollection as Record<string, any>[];
1760
- let index: number;
1761
- if (resCol.length > 1) {
1762
- index =
1763
- util.findIndexInData(lastResource, lastResourceData.idField, resourceData[parseInt(i.toString(), 10)] as string,
1764
- events, resCol);
1765
- } else {
1766
- index =
1767
- util.findIndexInData(lastResource, lastResourceData.idField, resourceData[parseInt(i.toString(), 10)] as string);
1768
- }
1769
- if (index < 0) {
1770
- return;
1771
- }
1772
- const groupId: Record<string, any> =
1773
- lastResource[parseInt(index.toString(), 10)][lastResourceData.groupIDField] as Record<string, any>;
1774
- const filter: TdData = lastLevel.filter((obj: TdData) => obj.resourceData[lastResourceData.idField] ===
1775
- resourceData[parseInt(i.toString(), 10)]).
1776
- filter((obj: TdData) => obj.resourceData[lastResourceData.groupIDField] === groupId)[0];
1777
- const groupOrder: number[] | string[] = filter.groupOrder;
1778
- for (let index: number = 0; index < this.parent.resourceBase.resourceCollection.length; index++) {
1779
- const field: string = this.parent.resourceBase.resourceCollection[parseInt(index.toString(), 10)].field;
1780
- events[`${field}`] = ((groupOrder[parseInt(index.toString(), 10)] as any) instanceof Array) ? groupOrder[parseInt(index.toString(), 10)][0] :
1781
- groupOrder[parseInt(index.toString(), 10)];
1782
- }
1783
- addValues();
1784
- } else {
1785
- for (let index: number = 0; index < this.parent.resourceBase.resourceCollection.length - 1; index++) {
1786
- const field: string = this.parent.resourceBase.resourceCollection[parseInt(index.toString(), 10)].field;
1787
- if (events[`${field}`] instanceof Array && (events[`${field}`] as Record<string, any>[]).length > 1) {
1788
- for (let k: number = 0; k < (events[`${field}`] as Record<string, any>[]).length; k++) {
1789
- const event: Record<string, any> = <Record<string, any>>extend({}, events, null, true);
1790
- event[`${field}`] = (eventObj[`${field}`] as Record<string, any>)[parseInt(k.toString(), 10)];
1791
- event[lastResourceData.field] = resourceData[parseInt(i.toString(), 10)];
1792
- temp.push(event);
1793
- }
1794
- } else {
1795
- if (temp.length === 0) {
1796
- events[`${field}`] = (eventObj[`${field}`] instanceof Array) ?
1797
- (eventObj[`${field}`] as Record<string, any>)[0] : eventObj[`${field}`];
1798
- events[lastResourceData.field] = resourceData[parseInt(i.toString(), 10)];
1799
- } else {
1800
- for (let l: number = 0; l < temp.length; l++) {
1801
- temp[parseInt(l.toString(), 10)][`${field}`] = (eventObj[`${field}`] instanceof Array) ?
1802
- (eventObj[`${field}`] as Record<string, any>)[0] : eventObj[`${field}`];
1803
- }
1804
- }
1805
- }
1806
- }
1807
- events[lastResourceData.field] = resourceData[parseInt(i.toString(), 10)];
1808
- addValues();
1809
- }
1810
- }
1811
- if (eventList.length > 0) {
1812
- for (const event of eventList) {
1813
- event[this.fields.recurrenceException] = null;
1814
- event[this.fields.recurrenceID] = null;
1815
- }
1816
- this.parent.addEvent(eventList);
1817
- }
1818
- }
1819
-
1820
- private getEventIdFromForm(): string {
1821
- return this.element.querySelector('.' + cls.FORM_CLASS).getAttribute('data-id');
1822
- }
1823
-
1824
- private getFormElements(className: string): HTMLInputElement[] {
1825
- let elements: HTMLInputElement[] = [];
1826
- if (className === cls.EVENT_WINDOW_DIALOG_CLASS) {
1827
- elements = [].slice.call(this.element.querySelectorAll('.' + EVENT_FIELD));
1828
- } else {
1829
- elements = [].slice.call(this.parent.element.querySelectorAll('.' + className + ' .' + EVENT_FIELD));
1830
- }
1831
- return elements;
1832
- }
1833
-
1834
- private getValueFromElement(element: HTMLElement): number | string | Date | boolean | string[] | number[] {
1835
- let value: number | string | Date | boolean | string[] | number[];
1836
- if (element.classList.contains('e-datepicker')) {
1837
- value = ((element as EJ2Instance).ej2_instances[0] as DatePicker).value as Date;
1838
- } else if (element.classList.contains('e-datetimepicker')) {
1839
- value = ((element as EJ2Instance).ej2_instances[0] as DateTimePicker).value as Date;
1840
- } else if (element.classList.contains('e-dropdownlist')) {
1841
- value = ((element as EJ2Instance).ej2_instances[0] as DropDownList).value as string | number;
1842
- } else if (element.classList.contains('e-multiselect')) {
1843
- value = ((element as EJ2Instance).ej2_instances[0] as MultiSelect).value as string[] | number[];
1844
- } else if (element.classList.contains('e-checkbox')) {
1845
- value = ((element as EJ2Instance).ej2_instances[0] as CheckBox).checked as boolean;
1846
- } else if (element.classList.contains('e-numerictextbox')) {
1847
- value = ((element as EJ2Instance).ej2_instances[0] as NumericTextBox).value as number;
1848
- } else {
1849
- if ((element as HTMLInputElement).type === 'checkbox') {
1850
- value = (element as HTMLInputElement).checked as boolean;
1851
- } else {
1852
- value = this.parent.enableHtmlSanitizer ?
1853
- SanitizeHtmlHelper.sanitize((element as HTMLInputElement).value as string) : (element as HTMLInputElement).value;
1854
- }
1855
- }
1856
- return value;
1857
- }
1858
-
1859
- private setValueToElement(element: HTMLElement, value: number | string | Date | boolean | number[] | string[]): void {
1860
- if (element.classList.contains('e-datepicker')) {
1861
- const instance: DatePicker = (element as EJ2Instance).ej2_instances[0] as DatePicker;
1862
- instance.value = <Date>value;
1863
- instance.dataBind();
1864
- } else if (element.classList.contains('e-datetimepicker')) {
1865
- const instance: DateTimePicker = (element as EJ2Instance).ej2_instances[0] as DateTimePicker;
1866
- if (instance.element.classList.contains(cls.EVENT_WINDOW_START_CLASS)) {
1867
- this.eventWindowTime.startTime = new Date('' + value);
1868
- } else {
1869
- this.eventWindowTime.endTime = new Date('' + value);
1870
- }
1871
- instance.value = <Date>value;
1872
- instance.dataBind();
1873
- } else if (element.classList.contains('e-dropdownlist')) {
1874
- const instance: DropDownList = (element as EJ2Instance).ej2_instances[0] as DropDownList;
1875
- instance.value = <string>value;
1876
- instance.dataBind();
1877
- } else if (element.classList.contains('e-multiselect')) {
1878
- const instance: MultiSelect = (element as EJ2Instance).ej2_instances[0] as MultiSelect;
1879
- instance.value = [];
1880
- instance.value = <string[]>((value instanceof Array) ? value : [value]);
1881
- instance.dataBind();
1882
- } else if (element.classList.contains('e-checkbox')) {
1883
- const instance: CheckBox = (element as EJ2Instance).ej2_instances[0] as CheckBox;
1884
- instance.checked = <boolean>value;
1885
- instance.dataBind();
1886
- } else if (element.classList.contains('e-numerictextbox')) {
1887
- const instance: NumericTextBox = (element as EJ2Instance).ej2_instances[0] as NumericTextBox;
1888
- instance.value = <number>value;
1889
- instance.dataBind();
1890
- } else {
1891
- if ((element as HTMLInputElement).type !== 'checkbox') {
1892
- (element as HTMLInputElement).value = <string>value || '';
1893
- } else {
1894
- (element as HTMLInputElement).checked = <boolean>value;
1895
- }
1896
- }
1897
- }
1898
-
1899
- private setDefaultValueToElement(element: HTMLElement): void {
1900
- if (element.classList.contains('e-datepicker')) {
1901
- const instance: DatePicker = (element as EJ2Instance).ej2_instances[0] as DatePicker;
1902
- instance.value = this.parent.getCurrentTime();
1903
- instance.dataBind();
1904
- } else if (element.classList.contains('e-datetimepicker')) {
1905
- const instance: DateTimePicker = (element as EJ2Instance).ej2_instances[0] as DateTimePicker;
1906
- const dateValue: Date = this.parent.getCurrentTime();
1907
- this.eventWindowTime = { startTime: dateValue, endTime: dateValue };
1908
- instance.value = dateValue;
1909
- instance.dataBind();
1910
- } else if (element.classList.contains('e-dropdownlist')) {
1911
- const instance: DropDownList = (element as EJ2Instance).ej2_instances[0] as DropDownList;
1912
- instance.value = null;
1913
- instance.dataBind();
1914
- } else if (element.classList.contains('e-multiselect')) {
1915
- const instance: MultiSelect = (element as EJ2Instance).ej2_instances[0] as MultiSelect;
1916
- instance.value = [];
1917
- instance.dataBind();
1918
- } else if (element.classList.contains('e-checkbox')) {
1919
- const instance: CheckBox = (element as EJ2Instance).ej2_instances[0] as CheckBox;
1920
- instance.checked = false;
1921
- instance.dataBind();
1922
- } else if (element.classList.contains('e-numerictextbox')) {
1923
- const instance: NumericTextBox = (element as EJ2Instance).ej2_instances[0] as NumericTextBox;
1924
- instance.value = null;
1925
- instance.dataBind();
1926
- } else {
1927
- if ((element as HTMLInputElement).type === 'checkbox') {
1928
- (element as HTMLInputElement).checked = false;
1929
- } else {
1930
- (element as HTMLInputElement).value = '';
1931
- }
1932
- }
1933
- }
1934
-
1935
- private getInstance(className: string): Record<string, any> {
1936
- const element: HTMLElement = this.element.querySelector('.' + className) as HTMLElement;
1937
- return element ? (element as EJ2Instance).ej2_instances[0] : null;
1938
- }
1939
-
1940
- private eventDelete(event: Event): void {
1941
- if (this.isEnterKey) {
1942
- this.isEnterKey = false;
1943
- return;
1944
- }
1945
- switch (this.parent.currentAction) {
1946
- case 'EditOccurrence':
1947
- if (!isNullOrUndefined((<Record<string, any>>this.parent.activeEventData.event)[this.parent.eventFields.recurrenceRule])) {
1948
- this.parent.currentAction = 'DeleteOccurrence';
1949
- } else {
1950
- this.parent.currentAction = 'Delete';
1951
- }
1952
- break;
1953
- case 'EditSeries':
1954
- this.parent.currentAction = 'DeleteSeries';
1955
- break;
1956
- case 'Save':
1957
- this.parent.currentAction = 'Delete';
1958
- break;
1959
- case 'EditFollowingEvents':
1960
- if (!isNullOrUndefined((<Record<string, any>>this.parent.activeEventData.event)[this.parent.eventFields.recurrenceRule])) {
1961
- this.parent.currentAction = 'DeleteFollowingEvents';
1962
- }
1963
- break;
1964
- }
1965
- this.dialogEvent = event;
1966
- this.isCrudAction = false;
1967
- this.dialogObject.hide();
1968
- this.parent.quickPopup.openDeleteAlert();
1969
- }
1970
-
1971
- public getRecurrenceEditorInstance(): RecurrenceEditor {
1972
- if (this.parent.isAdaptive && !this.repeatDialogObject) {
1973
- this.renderRepeatDialog();
1974
- }
1975
- return this.recurrenceEditor;
1976
- }
1977
-
1978
- private destroyComponents(): void {
1979
- const formElements: HTMLInputElement[] = this.getFormElements(cls.EVENT_WINDOW_DIALOG_CLASS);
1980
- for (const element of formElements) {
1981
- let instance: Record<string, any>[];
1982
- if (element.classList.contains('e-datetimepicker')) {
1983
- instance = ((<HTMLElement>element) as EJ2Instance).ej2_instances;
1984
- } else if (element.classList.contains('e-datepicker')) {
1985
- instance = ((<HTMLElement>element) as EJ2Instance).ej2_instances;
1986
- } else if (element.classList.contains('e-checkbox')) {
1987
- instance = ((<HTMLElement>element) as EJ2Instance).ej2_instances;
1988
- } else if (element.classList.contains('e-dropdownlist')) {
1989
- instance = ((<HTMLElement>element) as EJ2Instance).ej2_instances;
1990
- } else if (element.classList.contains('e-multiselect')) {
1991
- instance = ((<HTMLElement>element) as EJ2Instance).ej2_instances;
1992
- } else if (element.classList.contains('e-numerictextbox')) {
1993
- instance = ((<HTMLElement>element) as EJ2Instance).ej2_instances;
1994
- }
1995
- if (instance && instance[0]) {
1996
- (instance[0] as unknown as Schedule).destroy();
1997
- }
1998
- }
1999
- if (this.buttonObj) {
2000
- this.buttonObj.destroy();
2001
- }
2002
- }
2003
-
2004
- private detachComponents(): void {
2005
- const formElements: HTMLInputElement[] = this.getFormElements(cls.EVENT_WINDOW_DIALOG_CLASS);
2006
- for (const element of formElements) {
2007
- detach(element);
2008
- }
2009
- }
2010
-
2011
- public destroy(isIgnore?: boolean): void {
2012
- if (this.parent && !this.parent.isDestroyed) {
2013
- this.parent.resetTemplates(['editorTemplate', 'editorHeaderTemplate', 'editorFooterTemplate']);
2014
- }
2015
- this.destroyComponents();
2016
- if (this.recurrenceEditor) {
2017
- this.recurrenceEditor.destroy();
2018
- detach(this.recurrenceEditor.element);
2019
- this.recurrenceEditor = null;
2020
- }
2021
- if (this.fieldValidator) {
2022
- this.fieldValidator.destroy();
2023
- this.fieldValidator = null;
2024
- }
2025
- if (this.repeatDialogObject) {
2026
- this.repeatDialogObject.destroy();
2027
- this.repeatDialogObject = null;
2028
- }
2029
- this.detachComponents();
2030
- if (this.dialogObject) {
2031
- if (this.dialogObject.element) {
2032
- const form: HTMLFormElement = this.dialogObject.element.querySelector('form');
2033
- util.removeChildren(form);
2034
- detach(form);
2035
- EventHandler.remove(this.dialogObject.element, 'keydown', this.preventEventSave);
2036
- }
2037
- this.dialogObject.destroy();
2038
- this.dialogObject = null;
2039
- }
2040
- if (this.element) {
2041
- remove(this.element);
2042
- this.element = null;
2043
- }
2044
- if (!isIgnore) {
2045
- this.l10n = null;
2046
- this.parent = null;
2047
- this.fields = null;
2048
- this.buttonObj = null;
2049
- this.repeatStatus = null;
2050
- this.eventWindowTime = null;
2051
- this.dialogEvent = null;
2052
- }
2053
- }
2054
-
2055
- }