@syncfusion/ej2-schedule 30.2.4 → 31.1.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (308) 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 +132 -43
  5. package/dist/es6/ej2-schedule.es2015.js.map +1 -1
  6. package/dist/es6/ej2-schedule.es5.js +132 -43
  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/dist/ts/common/calendar-util.d.ts +92 -0
  12. package/dist/ts/common/calendar-util.ts +261 -0
  13. package/dist/ts/common/index.d.ts +4 -0
  14. package/dist/ts/common/index.ts +4 -0
  15. package/dist/ts/components.d.ts +5 -0
  16. package/dist/ts/components.ts +5 -0
  17. package/dist/ts/index.d.ts +6 -0
  18. package/dist/ts/index.ts +7 -0
  19. package/dist/ts/recurrence-editor/date-generator.d.ts +76 -0
  20. package/dist/ts/recurrence-editor/date-generator.ts +1699 -0
  21. package/dist/ts/recurrence-editor/index.d.ts +6 -0
  22. package/dist/ts/recurrence-editor/index.ts +6 -0
  23. package/dist/ts/recurrence-editor/recurrence-editor-model.d.ts +112 -0
  24. package/dist/ts/recurrence-editor/recurrence-editor.d.ts +245 -0
  25. package/dist/ts/recurrence-editor/recurrence-editor.ts +1257 -0
  26. package/dist/ts/schedule/actions/action-base.d.ts +44 -0
  27. package/dist/ts/schedule/actions/action-base.ts +493 -0
  28. package/dist/ts/schedule/actions/crud.d.ts +41 -0
  29. package/dist/ts/schedule/actions/crud.ts +784 -0
  30. package/dist/ts/schedule/actions/data.d.ts +63 -0
  31. package/dist/ts/schedule/actions/data.ts +128 -0
  32. package/dist/ts/schedule/actions/drag.d.ts +75 -0
  33. package/dist/ts/schedule/actions/drag.ts +1401 -0
  34. package/dist/ts/schedule/actions/keyboard.d.ts +100 -0
  35. package/dist/ts/schedule/actions/keyboard.ts +1435 -0
  36. package/dist/ts/schedule/actions/resize.d.ts +27 -0
  37. package/dist/ts/schedule/actions/resize.ts +602 -0
  38. package/dist/ts/schedule/actions/scroll.d.ts +69 -0
  39. package/dist/ts/schedule/actions/scroll.ts +105 -0
  40. package/dist/ts/schedule/actions/touch.d.ts +32 -0
  41. package/dist/ts/schedule/actions/touch.ts +314 -0
  42. package/dist/ts/schedule/actions/virtual-scroll.d.ts +55 -0
  43. package/dist/ts/schedule/actions/virtual-scroll.ts +596 -0
  44. package/dist/ts/schedule/actions/work-cells.d.ts +14 -0
  45. package/dist/ts/schedule/actions/work-cells.ts +151 -0
  46. package/dist/ts/schedule/base/constant.d.ts +102 -0
  47. package/dist/ts/schedule/base/constant.ts +103 -0
  48. package/dist/ts/schedule/base/css-constant.d.ts +475 -0
  49. package/dist/ts/schedule/base/css-constant.ts +475 -0
  50. package/dist/ts/schedule/base/interface.d.ts +673 -0
  51. package/dist/ts/schedule/base/interface.ts +738 -0
  52. package/dist/ts/schedule/base/resource.d.ts +59 -0
  53. package/dist/ts/schedule/base/resource.ts +1091 -0
  54. package/dist/ts/schedule/base/schedule-model.d.ts +930 -0
  55. package/dist/ts/schedule/base/schedule.d.ts +1967 -0
  56. package/dist/ts/schedule/base/schedule.ts +4221 -0
  57. package/dist/ts/schedule/base/type.d.ts +134 -0
  58. package/dist/ts/schedule/base/type.ts +142 -0
  59. package/dist/ts/schedule/base/util.d.ts +266 -0
  60. package/dist/ts/schedule/base/util.ts +492 -0
  61. package/dist/ts/schedule/event-renderer/agenda-base.d.ts +15 -0
  62. package/dist/ts/schedule/event-renderer/agenda-base.ts +423 -0
  63. package/dist/ts/schedule/event-renderer/event-base.d.ts +101 -0
  64. package/dist/ts/schedule/event-renderer/event-base.ts +1501 -0
  65. package/dist/ts/schedule/event-renderer/inline-edit.d.ts +23 -0
  66. package/dist/ts/schedule/event-renderer/inline-edit.ts +287 -0
  67. package/dist/ts/schedule/event-renderer/month.d.ts +60 -0
  68. package/dist/ts/schedule/event-renderer/month.ts +760 -0
  69. package/dist/ts/schedule/event-renderer/timeline-view.d.ts +51 -0
  70. package/dist/ts/schedule/event-renderer/timeline-view.ts +606 -0
  71. package/dist/ts/schedule/event-renderer/vertical-view.d.ts +57 -0
  72. package/dist/ts/schedule/event-renderer/vertical-view.ts +898 -0
  73. package/dist/ts/schedule/event-renderer/year.d.ts +27 -0
  74. package/dist/ts/schedule/event-renderer/year.ts +623 -0
  75. package/dist/ts/schedule/exports/calendar-export.d.ts +16 -0
  76. package/dist/ts/schedule/exports/calendar-export.ts +160 -0
  77. package/dist/ts/schedule/exports/calendar-import.d.ts +18 -0
  78. package/dist/ts/schedule/exports/calendar-import.ts +277 -0
  79. package/dist/ts/schedule/exports/excel-export.d.ts +14 -0
  80. package/dist/ts/schedule/exports/excel-export.ts +89 -0
  81. package/dist/ts/schedule/exports/index.d.ts +7 -0
  82. package/dist/ts/schedule/exports/index.ts +7 -0
  83. package/dist/ts/schedule/exports/print.d.ts +20 -0
  84. package/dist/ts/schedule/exports/print.ts +233 -0
  85. package/dist/ts/schedule/index.d.ts +26 -0
  86. package/dist/ts/schedule/index.ts +26 -0
  87. package/dist/ts/schedule/models/event-settings-model.d.ts +165 -0
  88. package/dist/ts/schedule/models/event-settings.d.ts +149 -0
  89. package/dist/ts/schedule/models/event-settings.ts +187 -0
  90. package/dist/ts/schedule/models/field-options-model.d.ts +37 -0
  91. package/dist/ts/schedule/models/field-options.d.ts +31 -0
  92. package/dist/ts/schedule/models/field-options.ts +41 -0
  93. package/dist/ts/schedule/models/fields-model.d.ts +129 -0
  94. package/dist/ts/schedule/models/fields.d.ts +117 -0
  95. package/dist/ts/schedule/models/fields.ts +149 -0
  96. package/dist/ts/schedule/models/group-model.d.ts +69 -0
  97. package/dist/ts/schedule/models/group.d.ts +60 -0
  98. package/dist/ts/schedule/models/group.ts +75 -0
  99. package/dist/ts/schedule/models/header-rows-model.d.ts +33 -0
  100. package/dist/ts/schedule/models/header-rows.d.ts +30 -0
  101. package/dist/ts/schedule/models/header-rows.ts +35 -0
  102. package/dist/ts/schedule/models/models.d.ts +14 -0
  103. package/dist/ts/schedule/models/models.ts +15 -0
  104. package/dist/ts/schedule/models/quick-info-templates-model.d.ts +52 -0
  105. package/dist/ts/schedule/models/quick-info-templates.d.ts +47 -0
  106. package/dist/ts/schedule/models/quick-info-templates.ts +56 -0
  107. package/dist/ts/schedule/models/resources-model.d.ts +122 -0
  108. package/dist/ts/schedule/models/resources.d.ts +106 -0
  109. package/dist/ts/schedule/models/resources.ts +138 -0
  110. package/dist/ts/schedule/models/time-scale-model.d.ts +57 -0
  111. package/dist/ts/schedule/models/time-scale.d.ts +50 -0
  112. package/dist/ts/schedule/models/time-scale.ts +61 -0
  113. package/dist/ts/schedule/models/toolbar-model.d.ts +196 -0
  114. package/dist/ts/schedule/models/toolbar.d.ts +176 -0
  115. package/dist/ts/schedule/models/toolbar.ts +196 -0
  116. package/dist/ts/schedule/models/views-model.d.ts +370 -0
  117. package/dist/ts/schedule/models/views.d.ts +335 -0
  118. package/dist/ts/schedule/models/views.ts +408 -0
  119. package/dist/ts/schedule/models/work-hours-model.d.ts +29 -0
  120. package/dist/ts/schedule/models/work-hours.d.ts +24 -0
  121. package/dist/ts/schedule/models/work-hours.ts +31 -0
  122. package/dist/ts/schedule/popups/event-tooltip.d.ts +16 -0
  123. package/dist/ts/schedule/popups/event-tooltip.ts +203 -0
  124. package/dist/ts/schedule/popups/event-window.d.ts +118 -0
  125. package/dist/ts/schedule/popups/event-window.ts +2055 -0
  126. package/dist/ts/schedule/popups/form-validator.d.ts +16 -0
  127. package/dist/ts/schedule/popups/form-validator.ts +110 -0
  128. package/dist/ts/schedule/popups/quick-popups.d.ts +78 -0
  129. package/dist/ts/schedule/popups/quick-popups.ts +1470 -0
  130. package/dist/ts/schedule/renderer/agenda.d.ts +45 -0
  131. package/dist/ts/schedule/renderer/agenda.ts +497 -0
  132. package/dist/ts/schedule/renderer/day.d.ts +20 -0
  133. package/dist/ts/schedule/renderer/day.ts +28 -0
  134. package/dist/ts/schedule/renderer/header-renderer.d.ts +48 -0
  135. package/dist/ts/schedule/renderer/header-renderer.ts +736 -0
  136. package/dist/ts/schedule/renderer/month-agenda.d.ts +29 -0
  137. package/dist/ts/schedule/renderer/month-agenda.ts +184 -0
  138. package/dist/ts/schedule/renderer/month.d.ts +61 -0
  139. package/dist/ts/schedule/renderer/month.ts +766 -0
  140. package/dist/ts/schedule/renderer/renderer.d.ts +13 -0
  141. package/dist/ts/schedule/renderer/renderer.ts +165 -0
  142. package/dist/ts/schedule/renderer/timeline-header-row.d.ts +15 -0
  143. package/dist/ts/schedule/renderer/timeline-header-row.ts +132 -0
  144. package/dist/ts/schedule/renderer/timeline-month.d.ts +29 -0
  145. package/dist/ts/schedule/renderer/timeline-month.ts +184 -0
  146. package/dist/ts/schedule/renderer/timeline-view.d.ts +31 -0
  147. package/dist/ts/schedule/renderer/timeline-view.ts +308 -0
  148. package/dist/ts/schedule/renderer/timeline-year.d.ts +22 -0
  149. package/dist/ts/schedule/renderer/timeline-year.ts +450 -0
  150. package/dist/ts/schedule/renderer/vertical-view.d.ts +63 -0
  151. package/dist/ts/schedule/renderer/vertical-view.ts +911 -0
  152. package/dist/ts/schedule/renderer/view-base.d.ts +83 -0
  153. package/dist/ts/schedule/renderer/view-base.ts +709 -0
  154. package/dist/ts/schedule/renderer/week.d.ts +22 -0
  155. package/dist/ts/schedule/renderer/week.ts +35 -0
  156. package/dist/ts/schedule/renderer/work-week.d.ts +22 -0
  157. package/dist/ts/schedule/renderer/work-week.ts +36 -0
  158. package/dist/ts/schedule/renderer/year.d.ts +46 -0
  159. package/dist/ts/schedule/renderer/year.ts +470 -0
  160. package/dist/ts/schedule/timezone/timezone.d.ts +16 -0
  161. package/dist/ts/schedule/timezone/timezone.ts +313 -0
  162. package/package.json +56 -21
  163. package/src/schedule/actions/action-base.js +3 -0
  164. package/src/schedule/actions/drag.js +11 -4
  165. package/src/schedule/actions/keyboard.js +1 -1
  166. package/src/schedule/actions/resize.js +9 -5
  167. package/src/schedule/actions/virtual-scroll.js +3 -0
  168. package/src/schedule/base/css-constant.d.ts +2 -0
  169. package/src/schedule/base/css-constant.js +2 -0
  170. package/src/schedule/base/schedule.js +15 -1
  171. package/src/schedule/event-renderer/agenda-base.d.ts +1 -1
  172. package/src/schedule/event-renderer/agenda-base.js +5 -4
  173. package/src/schedule/event-renderer/inline-edit.js +11 -6
  174. package/src/schedule/event-renderer/month.js +5 -3
  175. package/src/schedule/event-renderer/vertical-view.js +3 -0
  176. package/src/schedule/event-renderer/year.d.ts +2 -0
  177. package/src/schedule/event-renderer/year.js +28 -4
  178. package/src/schedule/popups/event-tooltip.js +4 -0
  179. package/src/schedule/popups/event-window.js +2 -2
  180. package/src/schedule/popups/quick-popups.js +5 -1
  181. package/src/schedule/renderer/agenda.js +3 -2
  182. package/src/schedule/renderer/month.js +9 -7
  183. package/src/schedule/renderer/vertical-view.js +1 -1
  184. package/src/schedule/renderer/view-base.d.ts +2 -0
  185. package/src/schedule/renderer/view-base.js +9 -0
  186. package/src/schedule/renderer/year.js +3 -2
  187. package/styles/bds-lite.css +11 -8
  188. package/styles/bds.css +11 -8
  189. package/styles/bootstrap-dark-lite.css +12 -9
  190. package/styles/bootstrap-dark.css +12 -9
  191. package/styles/bootstrap-lite.css +12 -9
  192. package/styles/bootstrap.css +12 -9
  193. package/styles/bootstrap4-lite.css +11 -8
  194. package/styles/bootstrap4.css +11 -8
  195. package/styles/bootstrap5-dark-lite.css +11 -8
  196. package/styles/bootstrap5-dark.css +11 -8
  197. package/styles/bootstrap5-lite.css +11 -8
  198. package/styles/bootstrap5.3-lite.css +11 -8
  199. package/styles/bootstrap5.3.css +11 -8
  200. package/styles/bootstrap5.css +11 -8
  201. package/styles/fabric-dark-lite.css +12 -9
  202. package/styles/fabric-dark.css +12 -9
  203. package/styles/fabric-lite.css +12 -9
  204. package/styles/fabric.css +12 -9
  205. package/styles/fluent-dark-lite.css +13 -10
  206. package/styles/fluent-dark.css +13 -10
  207. package/styles/fluent-lite.css +13 -10
  208. package/styles/fluent.css +13 -10
  209. package/styles/fluent2-lite.css +11 -8
  210. package/styles/fluent2.css +11 -8
  211. package/styles/highcontrast-light-lite.css +12 -9
  212. package/styles/highcontrast-light.css +12 -9
  213. package/styles/highcontrast-lite.css +12 -9
  214. package/styles/highcontrast.css +12 -9
  215. package/styles/material-dark-lite.css +12 -9
  216. package/styles/material-dark.css +12 -9
  217. package/styles/material-lite.css +12 -9
  218. package/styles/material.css +12 -9
  219. package/styles/material3-dark-lite.css +11 -8
  220. package/styles/material3-dark.css +11 -8
  221. package/styles/material3-lite.css +11 -8
  222. package/styles/material3.css +11 -8
  223. package/styles/recurrence-editor/_bds-definition.scss +1 -0
  224. package/styles/recurrence-editor/_bootstrap-dark-definition.scss +1 -0
  225. package/styles/recurrence-editor/_bootstrap-definition.scss +1 -0
  226. package/styles/recurrence-editor/_bootstrap4-definition.scss +1 -0
  227. package/styles/recurrence-editor/_bootstrap5-definition.scss +1 -0
  228. package/styles/recurrence-editor/_bootstrap5.3-definition.scss +1 -0
  229. package/styles/recurrence-editor/_fabric-dark-definition.scss +1 -0
  230. package/styles/recurrence-editor/_fabric-definition.scss +1 -0
  231. package/styles/recurrence-editor/_fluent-definition.scss +1 -0
  232. package/styles/recurrence-editor/_fluent2-definition.scss +1 -0
  233. package/styles/recurrence-editor/_fusionnew-definition.scss +1 -0
  234. package/styles/recurrence-editor/_highcontrast-definition.scss +1 -0
  235. package/styles/recurrence-editor/_highcontrast-light-definition.scss +1 -0
  236. package/styles/recurrence-editor/_layout.scss +5 -1
  237. package/styles/recurrence-editor/_material-dark-definition.scss +1 -0
  238. package/styles/recurrence-editor/_material-definition.scss +1 -0
  239. package/styles/recurrence-editor/_material3-definition.scss +1 -0
  240. package/styles/recurrence-editor/_tailwind-definition.scss +1 -0
  241. package/styles/recurrence-editor/_tailwind3-definition.scss +1 -0
  242. package/styles/recurrence-editor/bds.css +3 -0
  243. package/styles/recurrence-editor/bootstrap-dark.css +4 -1
  244. package/styles/recurrence-editor/bootstrap.css +4 -1
  245. package/styles/recurrence-editor/bootstrap4.css +3 -0
  246. package/styles/recurrence-editor/bootstrap5-dark.css +3 -0
  247. package/styles/recurrence-editor/bootstrap5.3.css +3 -0
  248. package/styles/recurrence-editor/bootstrap5.css +3 -0
  249. package/styles/recurrence-editor/fabric-dark.css +4 -1
  250. package/styles/recurrence-editor/fabric.css +4 -1
  251. package/styles/recurrence-editor/fluent-dark.css +4 -1
  252. package/styles/recurrence-editor/fluent.css +4 -1
  253. package/styles/recurrence-editor/fluent2.css +3 -0
  254. package/styles/recurrence-editor/highcontrast-light.css +4 -1
  255. package/styles/recurrence-editor/highcontrast.css +4 -1
  256. package/styles/recurrence-editor/material-dark.css +4 -1
  257. package/styles/recurrence-editor/material.css +4 -1
  258. package/styles/recurrence-editor/material3-dark.css +3 -0
  259. package/styles/recurrence-editor/material3.css +3 -0
  260. package/styles/recurrence-editor/tailwind-dark.css +3 -0
  261. package/styles/recurrence-editor/tailwind.css +3 -0
  262. package/styles/recurrence-editor/tailwind3.css +3 -0
  263. package/styles/schedule/_bds-definition.scss +2 -0
  264. package/styles/schedule/_bootstrap-dark-definition.scss +2 -0
  265. package/styles/schedule/_bootstrap-definition.scss +2 -0
  266. package/styles/schedule/_bootstrap4-definition.scss +2 -0
  267. package/styles/schedule/_bootstrap5-definition.scss +2 -0
  268. package/styles/schedule/_bootstrap5.3-definition.scss +2 -0
  269. package/styles/schedule/_fabric-dark-definition.scss +2 -0
  270. package/styles/schedule/_fabric-definition.scss +2 -0
  271. package/styles/schedule/_fluent-definition.scss +3 -1
  272. package/styles/schedule/_fluent2-definition.scss +2 -0
  273. package/styles/schedule/_fusionnew-definition.scss +2 -0
  274. package/styles/schedule/_highcontrast-definition.scss +2 -0
  275. package/styles/schedule/_highcontrast-light-definition.scss +2 -0
  276. package/styles/schedule/_layout.scss +12 -11
  277. package/styles/schedule/_material-dark-definition.scss +2 -0
  278. package/styles/schedule/_material-definition.scss +2 -0
  279. package/styles/schedule/_material3-definition.scss +2 -0
  280. package/styles/schedule/_tailwind-definition.scss +2 -0
  281. package/styles/schedule/_tailwind3-definition.scss +2 -0
  282. package/styles/schedule/bds.css +8 -8
  283. package/styles/schedule/bootstrap-dark.css +8 -8
  284. package/styles/schedule/bootstrap.css +8 -8
  285. package/styles/schedule/bootstrap4.css +8 -8
  286. package/styles/schedule/bootstrap5-dark.css +8 -8
  287. package/styles/schedule/bootstrap5.3.css +8 -8
  288. package/styles/schedule/bootstrap5.css +8 -8
  289. package/styles/schedule/fabric-dark.css +8 -8
  290. package/styles/schedule/fabric.css +8 -8
  291. package/styles/schedule/fluent-dark.css +9 -9
  292. package/styles/schedule/fluent.css +9 -9
  293. package/styles/schedule/fluent2.css +8 -8
  294. package/styles/schedule/highcontrast-light.css +8 -8
  295. package/styles/schedule/highcontrast.css +8 -8
  296. package/styles/schedule/material-dark.css +8 -8
  297. package/styles/schedule/material.css +8 -8
  298. package/styles/schedule/material3-dark.css +8 -8
  299. package/styles/schedule/material3.css +8 -8
  300. package/styles/schedule/tailwind-dark.css +8 -8
  301. package/styles/schedule/tailwind.css +8 -8
  302. package/styles/schedule/tailwind3.css +8 -8
  303. package/styles/tailwind-dark-lite.css +11 -8
  304. package/styles/tailwind-dark.css +11 -8
  305. package/styles/tailwind-lite.css +11 -8
  306. package/styles/tailwind.css +11 -8
  307. package/styles/tailwind3-lite.css +11 -8
  308. package/styles/tailwind3.css +11 -8
@@ -0,0 +1,1257 @@
1
+ import { Component, Property, NotifyPropertyChanges, INotifyPropertyChanged, Event, Browser, detach } from '@syncfusion/ej2-base';
2
+ import { EmitType, getDefaultDateObject, getValue, cldrData, L10n, isNullOrUndefined, removeClass, addClass } from '@syncfusion/ej2-base';
3
+ import { DropDownList, ChangeEventArgs } from '@syncfusion/ej2-dropdowns';
4
+ import { NumericTextBox } from '@syncfusion/ej2-inputs';
5
+ import { DatePicker, ChangedEventArgs } from '@syncfusion/ej2-calendars';
6
+ import { Button, RadioButton } from '@syncfusion/ej2-buttons';
7
+ import { EventHandler, MouseEventArgs, classList } from '@syncfusion/ej2-base';
8
+ import { EJ2Instance } from '../schedule/base/interface';
9
+ import { RecRule, extractObjectFromRule, generate, generateSummary, getRecurrenceStringFromDate, getCalendarUtil } from './date-generator';
10
+ import { RecurrenceEditorModel } from './recurrence-editor-model';
11
+ import { CalendarUtil, CalendarType } from '../common/calendar-util';
12
+ import { capitalizeFirstWord } from '../schedule/base/util';
13
+
14
+ const HEADER: string = 'e-editor';
15
+ const INPUTWARAPPER: string = 'e-input-wrapper';
16
+ const INPUTWARAPPERSIDE: string = 'e-input-wrapper-side';
17
+ const REPEATELEMENT: string = 'e-repeat-element';
18
+ const REPEATINTERVAL: string = 'e-repeat-interval';
19
+ const INTERVALCLASS: string = 'e-interval';
20
+ const DAYWRAPPER: string = 'e-days';
21
+ const WEEKWRAPPER: string = 'e-non-week';
22
+ const WEEKPOSITION: string = 'e-week-position';
23
+ const DAYPOSITION: string = 'e-day-position';
24
+ const YEAREXPANDERWRAPPER: string = 'e-year-expander';
25
+ const YEAREXPANDERELEMENT: string = 'e-year-expander-element';
26
+ const MONETHEXPANDERWRAPPER: string = 'e-month-expander';
27
+ const MONETHEXPANDWRAPPER: string = 'e-month-expand-wrapper';
28
+ const MONTHEXPANDERELEMENT: string = 'e-month-expander-element';
29
+ const MONTHEXPANDERCHECKBOXWRAPPER: string = 'e-month-expander-checkbox-wrapper';
30
+ const REPEATONWEEKSELECTOR: string = 'e-repeat-on-week-selector';
31
+ const FORMLEFT: string = 'e-form-left';
32
+ const FORMRIGHT: string = 'e-form-right';
33
+ const MONTHDAYWRAPPER: string = 'e-month-day';
34
+ const MONTHEXPANNDERELEM: string = 'e-month-expander-wrapper';
35
+ const MONTHPOS: string = 'e-month-pos';
36
+ const MONTHWEEK: string = 'e-month-week';
37
+ const ENDON: string = 'e-end-on';
38
+ const MONTHEXPANDERLABEL: string = 'e-month-expander-label';
39
+ const WEEKEXPANDERLABEL: string = 'e-week-expander-label';
40
+ const ENDONLEFT: string = 'e-end-on-left';
41
+ const MONTHDAYELEMENT: string = 'e-monthday-element';
42
+ const ENDONELEMENT: string = 'e-end-on-element';
43
+ const ENDONDATE: string = 'e-end-on-date';
44
+ const UNTILDATE: string = 'e-until-date';
45
+ const ENDONCOUNTWRAPPER: string = 'e-end-on-count';
46
+ const ENDONCOUNT: string = 'e-recurrence-count';
47
+ const HIDEWRAPPER: string = 'e-hide-recurrence-element';
48
+ const RTLCLASS: string = 'e-rtl';
49
+ const PRIMARY: string = 'e-primary';
50
+ const ACTIVE: string = 'e-active';
51
+ const RECURRENCETABLE: string = 'e-recurrence-table';
52
+ const REPEATCONTENT: string = 'e-repeat-content';
53
+ const REPEATCONTENTWRAPPER: string = 'e-repeat-content-wrapper';
54
+ const NONE: string = 'none';
55
+ const DAILY: string = 'daily';
56
+ const WEEKLY: string = 'weekly';
57
+ const MONTHLY: string = 'monthly';
58
+ const YEARLY: string = 'yearly';
59
+ const NEVER: string = 'never';
60
+ const UNTIL: string = 'until';
61
+ const COUNT: string = 'count';
62
+ const TEXTFIELD: string = 'text';
63
+ const VALUEFIELD: string = 'value';
64
+ const LAST: string = 'last';
65
+ const REPEAT: string = 'repeat';
66
+ const REPEATEVERY: string = 'repeatEvery';
67
+ const ON: string = 'on';
68
+ const END: string = 'end';
69
+ const RADIOLABEL: string = 'onDay';
70
+ const RULEUNTIL: string = 'UNTIL';
71
+ const RULEBYDAY: string = 'BYDAY';
72
+ const RULEBYMONTHDAY: string = 'BYMONTHDAY';
73
+ const RULEBYMONTH: string = 'BYMONTH';
74
+ const RULEINTERVAL: string = 'INTERVAL';
75
+ const RULECOUNT: string = 'COUNT';
76
+ const RULESETPOS: string = 'BYSETPOS';
77
+ const RULEFREQ: string = 'FREQ';
78
+ const RULEDAILY: string = 'DAILY';
79
+ const RULEWEEKLY: string = 'WEEKLY';
80
+ const RULEMONTHLY: string = 'MONTHLY';
81
+ const RULEYEARLY: string = 'YEARLY';
82
+ const RULESUNDAY: string = 'SU';
83
+ const RULEMONDAY: string = 'MO';
84
+ const RULETUESDAY: string = 'TU';
85
+ const RULEWEDNESDAY: string = 'WE';
86
+ const RULETHURSDAY: string = 'TH';
87
+ const RULEFRIDAY: string = 'FR';
88
+ const RULESATURDAY: string = 'SA';
89
+ const KEYSUNDAY: string = 'sun';
90
+ const KEYMONDAY: string = 'mon';
91
+ const KEYTUESDAY: string = 'tue';
92
+ const KEYWEDNESDAY: string = 'wed';
93
+ const KEYTHURSDAY: string = 'thu';
94
+ const KEYFRIDAY: string = 'fri';
95
+ const KEYSATURDAY: string = 'sat';
96
+ const EQUAL: string = '=';
97
+ const SEMICOLON: string = ';';
98
+ const COMMA: string = ',';
99
+ const FIRST: string = 'first';
100
+ const SECOND: string = 'second';
101
+ const THIRD: string = 'third';
102
+ const FOURTH: string = 'fourth';
103
+ const contentType: { [key: string]: string } = {
104
+ none: '',
105
+ daily: 'days',
106
+ weekly: 'weeks',
107
+ monthly: 'months',
108
+ yearly: 'years'
109
+ };
110
+ const valueData: { [key: string]: string } = {
111
+ 'sun': RULESUNDAY,
112
+ 'mon': RULEMONDAY,
113
+ 'tue': RULETUESDAY,
114
+ 'wed': RULEWEDNESDAY,
115
+ 'thu': RULETHURSDAY,
116
+ 'fri': RULEFRIDAY,
117
+ 'sat': RULESATURDAY
118
+ };
119
+ const neverClassList: string[] = [DAYWRAPPER, WEEKWRAPPER, ENDON, INTERVALCLASS, YEAREXPANDERWRAPPER, MONETHEXPANDERWRAPPER];
120
+ const weekClassList: string[] = [WEEKWRAPPER];
121
+ const monthClassList: string[] = [DAYWRAPPER, YEAREXPANDERWRAPPER];
122
+ const yearClassList: string[] = [DAYWRAPPER];
123
+ const dailyClassList: string[] = [DAYWRAPPER, WEEKWRAPPER, YEAREXPANDERWRAPPER, MONETHEXPANDERWRAPPER];
124
+ const noEndClassList: string[] = [ENDONDATE, ENDONCOUNTWRAPPER];
125
+ const endOnCountClassList: string[] = [ENDONDATE];
126
+ const endOnDateClassList: string[] = [ENDONCOUNTWRAPPER];
127
+
128
+ /**
129
+ * Represents the RecurrenceEditor component.
130
+ * ```html
131
+ * <div id="recurrence"></div>
132
+ * ```
133
+ * ```typescript
134
+ * <script>
135
+ * var recObj = new RecurrenceEditor();
136
+ * recObj.appendTo("#recurrence");
137
+ * </script>
138
+ * ```
139
+ */
140
+ @NotifyPropertyChanges
141
+ export class RecurrenceEditor extends Component<HTMLElement> implements INotifyPropertyChanged {
142
+ // RecurrenceEditor Options
143
+ /**
144
+ * Sets the recurrence pattern on the editor.
145
+ *
146
+ * @default ['none', 'daily', 'weekly', 'monthly', 'yearly']
147
+ */
148
+ @Property(['none', 'daily', 'weekly', 'monthly', 'yearly'])
149
+ public frequencies: RepeatType[];
150
+
151
+ /**
152
+ * Sets the type of recurrence end for the recurrence pattern on the editor.
153
+ *
154
+ * @default ['never', 'until', 'count']
155
+ */
156
+ @Property(['never', 'until', 'count'])
157
+ public endTypes: EndType[];
158
+
159
+ /**
160
+ * Sets the first day of the week.
161
+ *
162
+ * @default 0
163
+ */
164
+ @Property(0)
165
+ public firstDayOfWeek: number;
166
+
167
+ /**
168
+ * Sets the start date on recurrence editor.
169
+ *
170
+ * @default new Date()
171
+ * @aspDefaultValue DateTime.Now
172
+ */
173
+ @Property(new Date())
174
+ public startDate: Date;
175
+
176
+ /**
177
+ * Sets the user specific date format on recurrence editor.
178
+ *
179
+ * @default null
180
+ */
181
+ @Property()
182
+ public dateFormat: string;
183
+
184
+ /**
185
+ * Sets the specific calendar type to be applied on recurrence editor.
186
+ *
187
+ * @default 'Gregorian'
188
+ */
189
+ @Property('Gregorian')
190
+ public calendarMode: CalendarType;
191
+
192
+ /**
193
+ * Allows styling with custom class names.
194
+ *
195
+ * @default null
196
+ */
197
+ @Property()
198
+ public cssClass: string;
199
+
200
+ /**
201
+ * Sets the recurrence rule as its output values.
202
+ *
203
+ * @default null
204
+ */
205
+ @Property()
206
+ public value: string;
207
+
208
+ /**
209
+ * Sets the minimum date on recurrence editor.
210
+ *
211
+ * @default new Date(1900, 0, 1)
212
+ * @aspDefaultValue new DateTime(1900, 1, 1)
213
+ */
214
+ @Property(new Date(1900, 0, 1))
215
+ public minDate: Date;
216
+
217
+ /**
218
+ * Sets the maximum date on recurrence editor.
219
+ *
220
+ * @default new Date(2099, 11, 31)
221
+ * @aspDefaultValue new DateTime(2099, 12, 31)
222
+ */
223
+ @Property(new Date(2099, 11, 31))
224
+ public maxDate: Date;
225
+
226
+ /**
227
+ * Sets the current repeat type to be set on the recurrence editor.
228
+ *
229
+ * @default 0
230
+ * @aspType int
231
+ */
232
+ @Property(0)
233
+ public selectedType: number;
234
+
235
+ /**
236
+ * Triggers for value changes on every sub-controls rendered within the recurrence editor.
237
+ *
238
+ * @event 'change'
239
+ */
240
+ @Event()
241
+ public change: EmitType<RecurrenceEditorChangeEventArgs>;
242
+
243
+ /**
244
+ * Triggers when the component is created.
245
+ *
246
+ * @event 'created'
247
+ */
248
+ @Event()
249
+ public created: EmitType<Object>;
250
+
251
+ /**
252
+ * Triggers when the component is destroyed.
253
+ *
254
+ * @event 'destroyed'
255
+ */
256
+ @Event()
257
+ public destroyed: EmitType<Object>;
258
+
259
+ /**
260
+ * Constructor for creating the widget
261
+ *
262
+ * @param {RecurrenceEditorModel} options Accepts the recurrence editor model properties to initiate the rendering
263
+ * @param {string | HTMLElement} element Accepts the DOM element reference
264
+ */
265
+ constructor(options?: RecurrenceEditorModel, element?: string | HTMLElement) {
266
+ super(options, <string | HTMLElement>element);
267
+ }
268
+
269
+ public localeObj: L10n;
270
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
271
+ private defaultLocale: Record<string, any> = {
272
+ none: 'None',
273
+ daily: 'Daily',
274
+ weekly: 'Weekly',
275
+ monthly: 'Monthly',
276
+ month: 'Month',
277
+ yearly: 'Yearly',
278
+ never: 'Never',
279
+ until: 'Until',
280
+ count: 'Count',
281
+ first: 'First',
282
+ second: 'Second',
283
+ third: 'Third',
284
+ fourth: 'Fourth',
285
+ last: 'Last',
286
+ repeat: 'Repeat',
287
+ repeatEvery: 'Repeat every',
288
+ on: 'Repeat On',
289
+ end: 'End',
290
+ onDay: 'Day',
291
+ days: 'Day(s)',
292
+ weeks: 'Week(s)',
293
+ months: 'Month(s)',
294
+ years: 'Year(s)',
295
+ every: 'every',
296
+ summaryTimes: 'time(s)',
297
+ summaryOn: 'on',
298
+ summaryUntil: 'until',
299
+ summaryRepeat: 'Repeats',
300
+ summaryDay: 'day(s)',
301
+ summaryWeek: 'week(s)',
302
+ summaryMonth: 'month(s)',
303
+ summaryYear: 'year(s)',
304
+ monthWeek: 'Month Week',
305
+ monthPosition: 'Month Position',
306
+ monthExpander: 'Month Expander',
307
+ yearExpander: 'Year Expander',
308
+ repeatInterval: 'Repeat Interval'
309
+ };
310
+ private renderStatus: boolean = false;
311
+ private ruleObject: RecRule;
312
+ private recurrenceCount: NumericTextBox;
313
+ private monthDate: NumericTextBox;
314
+ private repeatInterval: NumericTextBox;
315
+ private untilDateObj: DatePicker;
316
+ private repeatType: DropDownList;
317
+ private endType: DropDownList;
318
+ private monthWeekPos: DropDownList;
319
+ private monthWeekDays: DropDownList;
320
+ private monthValue: DropDownList;
321
+ private onMonthDay: RadioButton;
322
+ private onWeekDay: RadioButton;
323
+ private dayButtons: Button[] = [];
324
+ private monthButtons: RadioButton[] = [];
325
+ private calendarUtil: CalendarUtil;
326
+ private startState(freq: string, endOn: string, startDate: Date): void {
327
+ this.showFormElement();
328
+ this.updateForm(freq);
329
+ this.freshOnEndForm();
330
+ this.updateEndOnForm(endOn);
331
+ this.selectMonthDay(startDate);
332
+ this.updateUntilDate(startDate);
333
+ this.onMonthDay.setProperties({ checked: true });
334
+ }
335
+ protected preRender(): void {
336
+ this.localeObj = new L10n(this.getModuleName(), this.defaultLocale, this.locale);
337
+ this.calendarUtil = getCalendarUtil(this.calendarMode);
338
+ }
339
+ private applyCustomClass(cssClass: string): void {
340
+ if (cssClass) {
341
+ addClass([this.element], cssClass.split(' '));
342
+ }
343
+ }
344
+ private initialize(): void {
345
+ addClass([this.element], 'e-' + this.getModuleName());
346
+ this.renderComponent();
347
+ if (typeof this.startDate === 'string') {
348
+ this.setProperties({ startDate: new Date(this.startDate) }, false);
349
+ }
350
+ if (!isNullOrUndefined(this.value) && this.value !== '') {
351
+ this.setRecurrenceRule(this.value as string);
352
+ } else {
353
+ if (!isNullOrUndefined(this.repeatType.value)) {
354
+ this.startState(this.repeatType.value.toString().toUpperCase(), this.endTypes[0], this.startDate);
355
+ this.updateForm(this.repeatType.value.toString());
356
+ }
357
+ if (this.selectedType > 0) {
358
+ this.setProperties({ value: this.getRecurrenceRule() }, false);
359
+ }
360
+ }
361
+ this.applyCustomClass(this.cssClass);
362
+ }
363
+ private triggerChangeEvent(): void {
364
+ if (this.renderStatus) {
365
+ const value: string = this.getRecurrenceRule();
366
+ this.trigger('change', { value: value }, (args: { [key: string]: string }) => this.setProperties({ value: args.value }, false));
367
+ }
368
+ }
369
+ private resetDayButton(): void {
370
+ const elements: HTMLElement[] = [].slice.call(this.element.querySelectorAll('.' + DAYWRAPPER + ' button'));
371
+ elements.forEach((element: HTMLElement) => removeClass([element], [ACTIVE, PRIMARY]));
372
+ }
373
+ private daySelection(dayIndex: number): void {
374
+ this.resetDayButton();
375
+ const days: number[] = [0, 1, 2, 3, 4, 5, 6];
376
+ this.rotateArray(days, this.firstDayOfWeek);
377
+ const element: Element = this.element.querySelector('.' + DAYWRAPPER + ' button[data-index="' + days.indexOf(dayIndex) + '"]');
378
+ if (element) {
379
+ addClass([element], [ACTIVE, PRIMARY]);
380
+ }
381
+ }
382
+ private rtlClass(status: boolean): void {
383
+ if (status) {
384
+ addClass([this.element], RTLCLASS);
385
+ } else {
386
+ removeClass([this.element], RTLCLASS);
387
+ }
388
+ }
389
+ private updateUntilDate(date: Date): void {
390
+ const tempDate: Date = new Date(date.getTime());
391
+ tempDate.setDate(tempDate.getDate() + 60);
392
+ this.untilDateObj.setProperties({ value: tempDate });
393
+ }
394
+ private selectMonthDay(date: Date): void {
395
+ const weekday: string[] = [KEYSUNDAY, KEYMONDAY, KEYTUESDAY, KEYWEDNESDAY, KEYTHURSDAY, KEYFRIDAY, KEYSATURDAY];
396
+ this.monthDate.setProperties({ value: this.calendarUtil.getDate(date) });
397
+ this.monthWeekDays.setProperties({ value: valueData[weekday[date.getDay()]] });
398
+ this.monthValue.setProperties({ value: '' + this.calendarUtil.getMonth(date) });
399
+ this.monthWeekPos.setProperties({ value: this.getDayPosition(date) });
400
+ this.daySelection(date.getDay());
401
+ }
402
+ private updateForm(state: string): void {
403
+ this.repeatType.setProperties({ value: state });
404
+ const end: Element = this.element.querySelector('.' + ENDON);
405
+ if (state === DAILY) {
406
+ classList(end, [FORMLEFT], [FORMRIGHT]);
407
+ } else {
408
+ classList(end, [FORMRIGHT], [FORMLEFT]);
409
+ }
410
+ switch (state) {
411
+ case NONE:
412
+ neverClassList.forEach((className: string) => addClass([this.element.querySelector('.' + className)], HIDEWRAPPER));
413
+ break;
414
+ case WEEKLY:
415
+ weekClassList.forEach((className: string) => addClass([this.element.querySelector('.' + className)], HIDEWRAPPER));
416
+ break;
417
+ case MONTHLY:
418
+ monthClassList.forEach((className: string) => addClass([this.element.querySelector('.' + className)], HIDEWRAPPER));
419
+ break;
420
+ case YEARLY:
421
+ yearClassList.forEach((className: string) => addClass([this.element.querySelector('.' + className)], HIDEWRAPPER));
422
+ break;
423
+ case DAILY:
424
+ dailyClassList.forEach((className: string) => addClass([this.element.querySelector('.' + className)], HIDEWRAPPER));
425
+ break;
426
+
427
+ }
428
+ }
429
+ private updateEndOnForm(state: string): void {
430
+ this.endType.setProperties({ value: state });
431
+ switch (state) {
432
+ case NEVER:
433
+ noEndClassList.forEach((className: string) => addClass([this.element.querySelector('.' + className)], HIDEWRAPPER));
434
+ break;
435
+ case UNTIL:
436
+ endOnDateClassList.forEach((className: string) => addClass([this.element.querySelector('.' + className)], HIDEWRAPPER));
437
+ break;
438
+ case COUNT:
439
+ endOnCountClassList.forEach((className: string) => addClass([this.element.querySelector('.' + className)], HIDEWRAPPER));
440
+ break;
441
+ }
442
+ }
443
+ private freshOnEndForm(): void {
444
+ noEndClassList.forEach((className: string) => {
445
+ const element: Element = this.element.querySelector('.' + className);
446
+ if (element) {
447
+ removeClass([element], HIDEWRAPPER);
448
+ }
449
+ });
450
+ }
451
+ private showFormElement(): void {
452
+ neverClassList.forEach((className: string) => {
453
+ const hideElement: HTMLElement = this.element.querySelector('.' + className);
454
+ if (hideElement) {
455
+ removeClass([hideElement], HIDEWRAPPER);
456
+ }
457
+ });
458
+ }
459
+ private renderDropdowns(): void {
460
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
461
+ const self: RecurrenceEditor = this;
462
+ this.repeatType = new DropDownList({
463
+ //set the data to dataSource property
464
+ dataSource: this.getRepeatData(),
465
+ floatLabelType: 'Always',
466
+ enableRtl: this.enableRtl,
467
+ index: (<number>this.selectedType),
468
+ fields: {
469
+ text: TEXTFIELD,
470
+ value: VALUEFIELD
471
+ },
472
+ placeholder: this.localeObj.getConstant(REPEAT),
473
+ htmlAttributes: { 'title': this.localeObj.getConstant(REPEAT) },
474
+ change: (args: ChangeEventArgs) => {
475
+ self.setProperties({ selectedType: this.frequencies.indexOf(args.value as RepeatType) }, false);
476
+ self.element.querySelector('.' + REPEATCONTENT).innerHTML =
477
+ self.localeObj.getConstant(contentType[args.value as number | string]);
478
+ self.showFormElement();
479
+ self.updateForm(<string>args.value);
480
+ self.resetFormValues();
481
+ self.triggerChangeEvent();
482
+ }
483
+ });
484
+ // set placeholder to DropDownList input element
485
+ this.repeatType.appendTo(<HTMLElement>this.element.querySelector('.' + REPEATELEMENT));
486
+
487
+ this.endType = new DropDownList({
488
+ dataSource: this.getEndData(),
489
+ popupWidth: this.getPopupWidth(),
490
+ floatLabelType: 'Always',
491
+ placeholder: this.localeObj.getConstant(END),
492
+ enableRtl: this.enableRtl,
493
+ index: 1,
494
+ fields: {
495
+ text: TEXTFIELD,
496
+ value: VALUEFIELD
497
+ },
498
+ change: (args: ChangeEventArgs) => {
499
+ self.freshOnEndForm();
500
+ self.updateEndOnForm(<string>args.value);
501
+ self.resetFormValues();
502
+ self.triggerChangeEvent();
503
+ }
504
+ });
505
+ this.endType.appendTo(<HTMLElement>this.element.querySelector('.' + ENDONELEMENT));
506
+
507
+ const renderDropDownList: Function = (dropDownData: [{ [key: string]: string | number }]) => {
508
+ return new DropDownList({
509
+ dataSource: dropDownData,
510
+ popupWidth: this.getPopupWidth(),
511
+ enableRtl: this.enableRtl,
512
+ fields: {
513
+ text: TEXTFIELD,
514
+ value: VALUEFIELD
515
+ },
516
+ index: 1,
517
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
518
+ change: (args: ChangeEventArgs) => {
519
+ self.onWeekDay.setProperties({ checked: true });
520
+ self.resetFormValues();
521
+ self.triggerChangeEvent();
522
+ }
523
+ });
524
+ };
525
+
526
+ this.monthWeekPos = renderDropDownList(this.getMonthPosData());
527
+ this.monthWeekPos.appendTo(<HTMLElement>this.element.querySelector('.' + MONTHPOS));
528
+
529
+ this.monthWeekDays = renderDropDownList(this.getDayData('wide'));
530
+ this.monthWeekDays.appendTo(<HTMLElement>this.element.querySelector('.' + MONTHWEEK));
531
+
532
+ this.monthValue = new DropDownList({
533
+ dataSource: this.getMonthData(),
534
+ fields: {
535
+ text: TEXTFIELD,
536
+ value: VALUEFIELD
537
+ },
538
+ enableRtl: this.enableRtl,
539
+ index: 7,
540
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
541
+ change: (args: ChangeEventArgs) => {
542
+ self.resetFormValues();
543
+ self.triggerChangeEvent();
544
+ }
545
+ });
546
+ this.monthValue.appendTo(<HTMLElement>this.element.querySelector('.' + YEAREXPANDERELEMENT));
547
+ }
548
+
549
+ private setDefaultValue(): void {
550
+ const formelement: HTMLElement[] = [].slice.call(this.element.querySelectorAll('.e-control .e-numerictextbox'));
551
+ for (const element of formelement) {
552
+ const instance: NumericTextBox = ((element as EJ2Instance).ej2_instances[0] as NumericTextBox);
553
+ if (instance.element.classList.contains(REPEATINTERVAL)) {
554
+ instance.value = 1;
555
+ instance.dataBind();
556
+ } else if (instance.element.classList.contains(ENDONCOUNT)) {
557
+ instance.value = 10;
558
+ instance.dataBind();
559
+ }
560
+ }
561
+ }
562
+
563
+ private resetFormValues(): void {
564
+ const recurreneElement: HTMLElement[] = [].slice.call(this.element.querySelectorAll('.e-control [type="text"]'));
565
+ for (const element of recurreneElement) {
566
+ let instance: DatePicker | DropDownList | NumericTextBox;
567
+ if (element.classList.contains('e-datepicker')) {
568
+ instance = (element as EJ2Instance).ej2_instances[0] as DropDownList;
569
+ if (instance.value) {
570
+ // eslint-disable-next-line no-self-assign
571
+ instance.value = instance.value;
572
+ instance.dataBind();
573
+ } else {
574
+ this.updateUntilDate(this.startDate);
575
+ }
576
+ } else if (element.classList.contains('e-dropdownlist')) {
577
+ instance = (element as EJ2Instance).ej2_instances[0] as DropDownList;
578
+ instance.index = instance.index || 0;
579
+ instance.dataBind();
580
+ } else if (element.classList.contains('e-numerictextbox')) {
581
+ instance = (element as EJ2Instance).ej2_instances[0] as NumericTextBox;
582
+ let value: number;
583
+ if (instance.element.classList.contains(REPEATINTERVAL)) {
584
+ value = 1;
585
+ } else if (instance.element.classList.contains(ENDONCOUNT)) {
586
+ value = 10;
587
+ } else {
588
+ value = this.startDate.getDate();
589
+ }
590
+ instance.value = instance.value || value;
591
+ instance.dataBind();
592
+ }
593
+ }
594
+ }
595
+
596
+ private getPopupWidth(): string {
597
+ return Browser.isDevice ? '100%' : 'auto';
598
+ }
599
+ private renderDatePickers(): void {
600
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
601
+ const self: RecurrenceEditor = this;
602
+ this.untilDateObj = new DatePicker({
603
+ firstDayOfWeek: this.firstDayOfWeek,
604
+ enableRtl: this.enableRtl,
605
+ locale: this.locale,
606
+ min: this.minDate,
607
+ max: this.maxDate,
608
+ format: (isNullOrUndefined(this.dateFormat) ? this.getFormat('dateFormats') : this.dateFormat),
609
+ change: (args: ChangedEventArgs) => {
610
+ if (args.value) {
611
+ self.triggerChangeEvent();
612
+ }
613
+ }
614
+ });
615
+ this.untilDateObj.appendTo(<HTMLElement>this.element.querySelector('.' + UNTILDATE));
616
+ }
617
+ private getFormat(formatType: string): string {
618
+ let format: string;
619
+ if (this.locale === 'en' || this.locale === 'en-US') {
620
+ format = getValue(formatType + '.short', getDefaultDateObject(this.getCalendarMode()));
621
+ } else {
622
+ format = getValue('main.' + '' + this.locale + '.dates.calendars.' + this.getCalendarMode() + '.' + formatType + '.short', cldrData);
623
+ }
624
+ return format;
625
+ }
626
+ private dayButtonRender(): void {
627
+ const btns: HTMLButtonElement[] = [].slice.call(this.element.querySelectorAll('.' + DAYWRAPPER + ' button'));
628
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
629
+ const self: RecurrenceEditor = this;
630
+ for (const btn of btns) {
631
+ const button: Button = new Button({ isToggle: true, enableRtl: this.enableRtl }, btn);
632
+ this.dayButtons.push(button);
633
+ EventHandler.add(btn, 'click', (args: MouseEventArgs) => {
634
+ const btns: HTMLElement[] = [].slice.call(this.element.querySelectorAll('.' + DAYWRAPPER + ' button.' + PRIMARY));
635
+ const element: HTMLElement = <HTMLElement>args.target;
636
+ if (!element.classList.contains(PRIMARY)) {
637
+ addClass([element], PRIMARY);
638
+ self.triggerChangeEvent();
639
+ } else if (btns.length > 1) {
640
+ removeClass([element], PRIMARY);
641
+ self.triggerChangeEvent();
642
+ }
643
+ });
644
+ }
645
+ }
646
+ private radioButtonRender(): void {
647
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
648
+ const self: RecurrenceEditor = this;
649
+ this.onMonthDay = new RadioButton({
650
+ label: this.localeObj.getConstant(RADIOLABEL),
651
+ enableRtl: this.enableRtl,
652
+ name: 'monthType',
653
+ value: 'day',
654
+ change: () => {
655
+ self.resetFormValues();
656
+ self.triggerChangeEvent();
657
+ }
658
+ });
659
+ this.onMonthDay.appendTo(<HTMLElement>this.element.querySelector('.' + MONTHEXPANDERELEMENT));
660
+ this.monthButtons.push(this.onMonthDay);
661
+ this.onWeekDay = new RadioButton({
662
+ label: this.localeObj.getConstant('monthExpander'),
663
+ cssClass: 'e-month-type',
664
+ name: 'monthType',
665
+ enableRtl: this.enableRtl,
666
+ value: 'daypos',
667
+ change: () => {
668
+ self.resetFormValues();
669
+ self.triggerChangeEvent();
670
+ }
671
+ });
672
+ this.onWeekDay.appendTo(<HTMLElement>this.element.querySelector('.' + MONTHEXPANNDERELEM));
673
+ this.monthButtons.push(this.onWeekDay);
674
+ }
675
+ private numericTextboxRender(): void {
676
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
677
+ const self: RecurrenceEditor = this;
678
+ this.recurrenceCount = new NumericTextBox({
679
+ value: 10,
680
+ format: '#',
681
+ enableRtl: this.enableRtl,
682
+ min: 1,
683
+ max: 999,
684
+ change: () => {
685
+ self.triggerChangeEvent();
686
+ }
687
+ });
688
+ this.recurrenceCount.appendTo(<HTMLElement>this.element.querySelector('.' + ENDONCOUNT));
689
+
690
+ this.monthDate = new NumericTextBox({
691
+ value: 1,
692
+ format: '#',
693
+ enableRtl: this.enableRtl,
694
+ min: 1,
695
+ max: 31,
696
+ change: () => {
697
+ self.onMonthDay.setProperties({ checked: true });
698
+ self.triggerChangeEvent();
699
+ }
700
+ });
701
+ this.monthDate.appendTo(<HTMLElement>this.element.querySelector('.' + MONTHDAYWRAPPER));
702
+ this.repeatInterval = new NumericTextBox({
703
+ value: 1,
704
+ format: '#',
705
+ min: 1,
706
+ max: 999,
707
+ enableRtl: this.enableRtl,
708
+ floatLabelType: 'Always',
709
+ placeholder: this.localeObj.getConstant(REPEATEVERY),
710
+ change: () => {
711
+ self.triggerChangeEvent();
712
+ }
713
+ });
714
+ this.repeatInterval.appendTo(<HTMLElement>this.element.querySelector('.' + REPEATINTERVAL));
715
+ }
716
+ private renderComponent(): void {
717
+ this.setTemplate();
718
+ this.renderDropdowns();
719
+ this.renderDatePickers();
720
+ this.dayButtonRender();
721
+ this.radioButtonRender();
722
+ this.numericTextboxRender();
723
+ }
724
+ private rotateArray(data: (string | number)[], count: number): void {
725
+ let temp: string | number;
726
+ for (let index: number = 0; index < count; index++) {
727
+ temp = data.shift();
728
+ data.push(temp);
729
+ }
730
+ }
731
+ private getEndData(): { [key: string]: string }[] {
732
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
733
+ const self: RecurrenceEditor = this;
734
+ const dataSource: { [key: string]: string }[] = [];
735
+ this.endTypes.forEach((data: string) => {
736
+ dataSource.push({ text: self.localeObj.getConstant(data), value: data });
737
+ });
738
+ return dataSource;
739
+ }
740
+ private getDayPosition(date: Date): number {
741
+ let temp: Date = new Date(date.getTime());
742
+ let endDate: Date = new Date(date.getTime());
743
+ const day: number = date.getDay();
744
+ const positionCollection: number[] = [];
745
+ temp = this.calendarUtil.getMonthStartDate(temp);
746
+ endDate = this.calendarUtil.getMonthEndDate(endDate);
747
+ while (temp < endDate) {
748
+ if (temp.getDay() === day) {
749
+ positionCollection.push(temp.getTime());
750
+ }
751
+ temp.setDate(temp.getDate() + 1);
752
+ }
753
+ if (positionCollection.indexOf(date.getTime()) === positionCollection.length - 1) {
754
+ return -1;
755
+ }
756
+ return (positionCollection.indexOf(date.getTime()) + 1);
757
+ }
758
+ private getRepeatData(): { [key: string]: string }[] {
759
+ const data: { [key: string]: string }[] = [];
760
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
761
+ const self: RecurrenceEditor = this;
762
+ this.frequencies.forEach((element: string) => {
763
+ const textValue: string = (element === NONE) ? NEVER : element;
764
+ data.push({ text: self.localeObj.getConstant(textValue), value: element });
765
+ });
766
+ return data;
767
+ }
768
+ private getMonthPosData(): { [key: string]: string | number }[] {
769
+ const monthpos: string[] = [FIRST, SECOND, THIRD, FOURTH, LAST];
770
+ const monthposValue: { [key: string]: number } = {
771
+ first: 1,
772
+ second: 2,
773
+ third: 3,
774
+ fourth: 4,
775
+ last: -1
776
+ };
777
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
778
+ const self: RecurrenceEditor = this;
779
+ const dataSource: { [key: string]: string | number }[] = [];
780
+ monthpos.forEach((data: string) => {
781
+ dataSource.push({ text: self.localeObj.getConstant(data), value: monthposValue[`${data}`] });
782
+ });
783
+ return dataSource;
784
+ }
785
+ private getDayData(format: DayFormateType): { [key: string]: string }[] {
786
+ const weekday: string[] = [KEYSUNDAY, KEYMONDAY, KEYTUESDAY, KEYWEDNESDAY, KEYTHURSDAY, KEYFRIDAY, KEYSATURDAY];
787
+ const dayData: { [key: string]: string }[] = [];
788
+ let cldrObj: string[];
789
+ this.rotateArray(weekday, this.firstDayOfWeek);
790
+ if (this.locale === 'en' || this.locale === 'en-US') {
791
+ const nameSpaceString: string = 'days.stand-alone.';
792
+ cldrObj = <string[]>(getValue(nameSpaceString + format, getDefaultDateObject(this.getCalendarMode())));
793
+ } else {
794
+ const nameSpaceString: string =
795
+ 'main.' + '' + this.locale + '.dates.calendars.' + this.getCalendarMode() + '.days.stand-alone.' + format;
796
+ cldrObj = <string[]>(getValue(nameSpaceString, cldrData));
797
+ }
798
+ for (const obj of weekday) {
799
+ const day: string = getValue(obj, cldrObj);
800
+ dayData.push({ text: format === 'narrow' ? day : capitalizeFirstWord(day, 'single'), value: valueData[`${obj}`] });
801
+ }
802
+ return dayData;
803
+ }
804
+ private getMonthData(): { [key: string]: string }[] {
805
+ const monthData: { [key: string]: string }[] = [];
806
+ let cldrObj: string[];
807
+ if (this.locale === 'en' || this.locale === 'en-US') {
808
+ const nameSpaceString: string = 'months.stand-alone.wide';
809
+ cldrObj = <string[]>(getValue(nameSpaceString, getDefaultDateObject(this.getCalendarMode())));
810
+ } else {
811
+ const nameSpaceString: string =
812
+ 'main.' + '' + this.locale + '.dates.calendars.' + this.getCalendarMode() + '.months.stand-alone.wide';
813
+ cldrObj = <string[]>(getValue(nameSpaceString, cldrData));
814
+ }
815
+ for (const obj of Object.keys(cldrObj)) {
816
+ monthData.push({
817
+ text: capitalizeFirstWord(<string>getValue(obj, cldrObj), 'single'),
818
+ value: obj
819
+ });
820
+ }
821
+ return monthData;
822
+ }
823
+ private setTemplate(): void {
824
+ const dayData: { [key: string]: string }[] = this.getDayData('narrow');
825
+ const fullDay: { [key: string]: string }[] = this.getDayData('wide');
826
+ this.element.innerHTML = '<div class="' + HEADER + '">' +
827
+ '<div class="' + INPUTWARAPPER + ' ' + FORMLEFT + '">' +
828
+ '<input type="text" tabindex="0" class="' + REPEATELEMENT +
829
+ '"label="' + REPEATELEMENT.substr(2) + '" />' +
830
+ '</div><div class="' + INPUTWARAPPER + ' ' +
831
+ INTERVALCLASS + ' ' + FORMRIGHT + '"><table class="' + RECURRENCETABLE + ' ' + REPEATCONTENTWRAPPER + '" role="none"><tr>' +
832
+ '<td><input type="text" tabindex="0" id="' + this.element.id + '_' + REPEATINTERVAL + '" class="' + REPEATINTERVAL +
833
+ '"title="' + this.localeObj.getConstant('repeatEvery') + '" /></td>' +
834
+ '<td><span class="' + REPEATCONTENT + '"></span></td>' +
835
+ '</tr></table></div><div class="' + INPUTWARAPPERSIDE + ' ' + DAYWRAPPER + ' ' + FORMLEFT + '">' +
836
+ '<div class=' + WEEKEXPANDERLABEL + '>' + this.localeObj.getConstant(ON) + '</div>' +
837
+ '<button type="button" class="e-round" data-index="0" title="' + fullDay[0].text + '">' + dayData[0].text + '</button>' +
838
+ '<button type="button" class="e-round" data-index="1" title="' + fullDay[1].text + '">' + dayData[1].text + '</button>' +
839
+ '<button type="button" class="e-round" data-index="2" title="' + fullDay[2].text + '">' + dayData[2].text + '</button>' +
840
+ '<button type="button" class="e-round" data-index="3" title="' + fullDay[3].text + '">' + dayData[3].text + '</button>' +
841
+ '<button type="button" class="e-round" data-index="4" title="' + fullDay[4].text + '">' + dayData[4].text + '</button>' +
842
+ '<button type="button" class="e-round" data-index="5" title="' + fullDay[5].text + '">' + dayData[5].text + '</button>' +
843
+ '<button type="button" class="e-round" data-index="6" title="' + fullDay[6].text + '">' + dayData[6].text + '</button></div>' +
844
+ '<div class="' + INPUTWARAPPERSIDE + ' ' + WEEKWRAPPER + ' ' + FORMLEFT + '">' +
845
+ '<div class=' + MONTHEXPANDERLABEL + '>' + this.localeObj.getConstant(ON) + '</div>' +
846
+ '<div class="' + YEAREXPANDERWRAPPER + '">' +
847
+ '<input class="' + YEAREXPANDERELEMENT + '" type="text" tabindex="0" title="' +
848
+ this.localeObj.getConstant('yearExpander') + '"/>' +
849
+ '</div>' +
850
+ '<div class="' + MONETHEXPANDERWRAPPER + '">' +
851
+ '<table class="' + RECURRENCETABLE + ' ' + MONETHEXPANDWRAPPER + '" role="none"><tr><td>' +
852
+ '<div class="' + INPUTWARAPPER + ' ' + MONTHEXPANDERCHECKBOXWRAPPER + '">' +
853
+ '<input class="' + MONTHEXPANDERELEMENT + '"title="' + this.localeObj.getConstant('monthExpander') + '" type="radio">' +
854
+ '</div></td>' +
855
+ '<td colspan="2"><div class="' + INPUTWARAPPER + ' ' + MONTHDAYELEMENT + '">' +
856
+ '<input type="text" tabindex="0" id="' + this.element.id + '_' + MONTHDAYWRAPPER + '" class="' + MONTHDAYWRAPPER + '"title="' +
857
+ this.localeObj.getConstant('on') + '" />' +
858
+ '</div></td></tr>' +
859
+ '<tr><td>' +
860
+ '<div class="' + INPUTWARAPPER + ' ' + MONTHEXPANDERCHECKBOXWRAPPER + ' ' + REPEATONWEEKSELECTOR + '">' +
861
+ '<input class="' + MONTHEXPANNDERELEM + '"title="' + this.localeObj.getConstant('monthExpander') + '" type="radio">' +
862
+ '</div></td>' +
863
+ '<td><div class="' + INPUTWARAPPER + ' ' + WEEKPOSITION + '" >' +
864
+ '<input type="text" tabindex="0" class="' + MONTHPOS + '"title="' + this.localeObj.getConstant('monthPosition') + '" />' +
865
+ '</div></td>' +
866
+ '<td><div class="' + INPUTWARAPPER + ' ' + DAYPOSITION + '">' +
867
+ '<input type="text" tabindex="0" class="' + MONTHWEEK + '"title="' + this.localeObj.getConstant('monthWeek') + '" />' +
868
+ '</div></td></tr></table>' +
869
+ '</div></div>' +
870
+ '<div class="' + INPUTWARAPPERSIDE + ' ' + ENDON + ' ' + FORMRIGHT + '">' +
871
+ '<div class="' + INPUTWARAPPER + ' ' + ENDONLEFT + '">' +
872
+ '<input type="text" tabindex="0" class="' + ENDONELEMENT + '"title="' + this.localeObj.getConstant(END) + '" />' +
873
+ '</div>' +
874
+ '<div class="' + INPUTWARAPPER + ' ' + ENDONDATE + '" >' +
875
+ '<input type="text" tabindex="0" class="' + UNTILDATE + '"title="' + this.localeObj.getConstant(UNTIL) + '" />' +
876
+ '</div>' +
877
+ '<div class="' + INPUTWARAPPER + ' ' + ENDONCOUNTWRAPPER + '">' +
878
+ '<input type="text" tabindex="0" id="' + this.element.id + '_' + ENDONCOUNT + '" class="' + ENDONCOUNT + '"title="' + this.localeObj.getConstant(COUNT) + '" />' +
879
+ '</div></div>' +
880
+ '</div></div>';
881
+ }
882
+ private getSelectedDaysData(): string {
883
+ let ruleData: string = RULEBYDAY + EQUAL;
884
+ const elements: HTMLElement[] = [].slice.call(this.element.querySelectorAll('.' + DAYWRAPPER + ' button.' + PRIMARY));
885
+ const weekday: string[] = [RULESUNDAY, RULEMONDAY, RULETUESDAY, RULEWEDNESDAY, RULETHURSDAY, RULEFRIDAY, RULESATURDAY];
886
+ this.rotateArray(weekday, this.firstDayOfWeek);
887
+ for (let index: number = 0; index < elements.length; index++) {
888
+ ruleData += weekday[parseInt(elements[parseInt(index.toString(), 10)].getAttribute('data-index'), 10)] + (index === (elements.length - 1) ? '' : COMMA);
889
+ }
890
+ return ruleData + SEMICOLON;
891
+ }
892
+ private getSelectedMonthData(): string {
893
+ let ruleData: string;
894
+ if (this.onWeekDay.checked) {
895
+ ruleData = RULEBYDAY + EQUAL + this.monthWeekDays.value + SEMICOLON
896
+ + RULESETPOS + EQUAL + this.monthWeekPos.value + SEMICOLON;
897
+ } else {
898
+ ruleData = RULEBYMONTHDAY + EQUAL + this.monthDate.value + SEMICOLON;
899
+ }
900
+ return ruleData;
901
+ }
902
+ private getIntervalData(): string {
903
+ return RULEINTERVAL + EQUAL + this.repeatInterval.value + SEMICOLON;
904
+ }
905
+ private getEndOnCount(): string {
906
+ return RULECOUNT + EQUAL + this.recurrenceCount.value + SEMICOLON;
907
+ }
908
+ private getYearMonthRuleData(): string {
909
+ return RULEBYMONTH + EQUAL + this.monthValue.value + SEMICOLON;
910
+ }
911
+ private updateWeekButton(keys: string[]): void {
912
+ const weekday: string[] = [RULESUNDAY, RULEMONDAY, RULETUESDAY, RULEWEDNESDAY, RULETHURSDAY, RULEFRIDAY, RULESATURDAY];
913
+ this.rotateArray(weekday, this.firstDayOfWeek);
914
+ for (const obj of this.dayButtons) {
915
+ const index: number = parseInt(obj.element.getAttribute('data-index'), 10);
916
+ if (keys.indexOf(weekday[parseInt(index.toString(), 10)]) !== -1) {
917
+ obj.setProperties({ isPrimary: true });
918
+ } else {
919
+ obj.setProperties({ isPrimary: false });
920
+ }
921
+ }
922
+ }
923
+ private updateMonthUI(): void {
924
+ if (this.ruleObject.monthDay.length) {
925
+ this.monthDate.setProperties({ value: this.ruleObject.monthDay[0] });
926
+ this.onMonthDay.setProperties({ checked: true });
927
+ } else {
928
+ this.onWeekDay.setProperties({ checked: true });
929
+ this.monthWeekPos.setProperties({ value: this.ruleObject.setPosition });
930
+ for (const key of Object.keys(valueData)) {
931
+ if (valueData[`${key}`] === this.ruleObject.day[0]) {
932
+ this.monthWeekDays.setProperties({ value: this.ruleObject.day[0] });
933
+ break;
934
+ }
935
+ }
936
+ }
937
+ }
938
+ private updateUI(repeat: string, state: string): void {
939
+ this.repeatInterval.setProperties({ value: this.ruleObject.interval });
940
+ switch (state) {
941
+ case UNTIL:
942
+ this.untilDateObj.setProperties({ value: this.ruleObject.until });
943
+ break;
944
+ case COUNT:
945
+ this.recurrenceCount.setProperties({ value: this.ruleObject.count });
946
+ break;
947
+ }
948
+ switch (repeat) {
949
+ case WEEKLY:
950
+ this.updateWeekButton(this.ruleObject.day);
951
+ break;
952
+ case YEARLY:
953
+ this.monthValue.setProperties({ index: (this.ruleObject.month[0] - 1) });
954
+ this.updateMonthUI();
955
+ break;
956
+ case MONTHLY:
957
+ this.updateMonthUI();
958
+ break;
959
+ }
960
+ }
961
+ private getUntilData(): string {
962
+ if (!this.untilDateObj.value) {
963
+ return '';
964
+ }
965
+ const tempStr: string = getRecurrenceStringFromDate(this.untilDateObj.value);
966
+ return RULEUNTIL + EQUAL + tempStr + SEMICOLON;
967
+ }
968
+ private destroyComponents(): void {
969
+ if (!this.recurrenceCount.isDestroyed) {
970
+ this.recurrenceCount.destroy();
971
+ this.recurrenceCount = null;
972
+ }
973
+ if (!this.monthDate.isDestroyed) {
974
+ this.monthDate.destroy();
975
+ this.monthDate = null;
976
+ }
977
+ if (!this.repeatInterval.isDestroyed) {
978
+ this.repeatInterval.destroy();
979
+ this.repeatInterval = null;
980
+ }
981
+ if (!this.untilDateObj.isDestroyed) {
982
+ this.untilDateObj.destroy();
983
+ this.untilDateObj = null;
984
+ }
985
+ if (!this.repeatType.isDestroyed) {
986
+ this.repeatType.destroy();
987
+ this.repeatType = null;
988
+ }
989
+ if (!this.endType.isDestroyed) {
990
+ this.endType.destroy();
991
+ this.endType = null;
992
+ }
993
+ if (!this.monthWeekPos.isDestroyed) {
994
+ this.monthWeekPos.destroy();
995
+ this.monthWeekPos = null;
996
+ }
997
+ if (!this.monthWeekDays.isDestroyed) {
998
+ this.monthWeekDays.destroy();
999
+ this.monthWeekDays = null;
1000
+ }
1001
+ if (!this.monthValue.isDestroyed) {
1002
+ this.monthValue.destroy();
1003
+ this.monthValue = null;
1004
+ }
1005
+
1006
+ if (!this.onMonthDay.isDestroyed) {
1007
+ this.onMonthDay.destroy();
1008
+ this.onMonthDay = null;
1009
+ }
1010
+
1011
+ if (!this.onWeekDay.isDestroyed) {
1012
+ this.onWeekDay.destroy();
1013
+ this.onWeekDay = null;
1014
+ }
1015
+
1016
+ this.dayButtons.forEach((element: Button) => {
1017
+ if (!element.isDestroyed) {
1018
+ element.destroy();
1019
+ }
1020
+ });
1021
+ this.dayButtons = [];
1022
+ this.monthButtons.forEach((element: RadioButton) => {
1023
+ if (!element.isDestroyed) {
1024
+ element.destroy();
1025
+ }
1026
+ });
1027
+ this.monthButtons = [];
1028
+ }
1029
+ public resetFields(): void {
1030
+ this.startState(NONE, this.endTypes[0], this.startDate);
1031
+ this.setDefaultValue();
1032
+ }
1033
+ public updateRuleUntilDate(startDate: Date): void {
1034
+ if (this.untilDateObj.value && startDate) {
1035
+ const untilDate: Date = this.untilDateObj.value;
1036
+ const newUntilDate: Date = new Date(
1037
+ untilDate.getFullYear(), untilDate.getMonth(), untilDate.getDate(), startDate.getHours(),
1038
+ startDate.getMinutes(), startDate.getMilliseconds());
1039
+ this.untilDateObj.setProperties({ value: newUntilDate });
1040
+ }
1041
+ }
1042
+ private getCalendarMode(): string {
1043
+ return !isNullOrUndefined(this.calendarMode) ? this.calendarMode.toLowerCase() : 'gregorian';
1044
+ }
1045
+ public getRuleSummary(rule: string = this.getRecurrenceRule()): string {
1046
+ return generateSummary(rule, this.localeObj, this.locale, this.calendarMode);
1047
+ }
1048
+ public getRecurrenceDates(startDate: Date, rule: string, excludeDate?: string, maximumCount?: number, viewDate?: Date): number[] {
1049
+ viewDate = isNullOrUndefined(viewDate) ? this.startDate : viewDate;
1050
+ return generate(startDate, rule, excludeDate, this.firstDayOfWeek, maximumCount, viewDate, this.calendarMode);
1051
+ }
1052
+ public getRecurrenceRule(): string {
1053
+ let ruleData: string = RULEFREQ + EQUAL;
1054
+ switch (this.repeatType.value) {
1055
+ case DAILY:
1056
+ ruleData += RULEDAILY + SEMICOLON;
1057
+ break;
1058
+ case WEEKLY:
1059
+ ruleData += RULEWEEKLY + SEMICOLON + this.getSelectedDaysData();
1060
+ break;
1061
+ case MONTHLY:
1062
+ ruleData += RULEMONTHLY + SEMICOLON + this.getSelectedMonthData();
1063
+ break;
1064
+ case YEARLY:
1065
+ ruleData += RULEYEARLY + SEMICOLON + this.getSelectedMonthData() + this.getYearMonthRuleData();
1066
+ break;
1067
+ case NONE:
1068
+ return '';
1069
+ }
1070
+ ruleData += this.getIntervalData();
1071
+ switch (this.endType.value) {
1072
+ case UNTIL:
1073
+ ruleData += this.getUntilData();
1074
+ break;
1075
+ case COUNT:
1076
+ ruleData += this.getEndOnCount();
1077
+ break;
1078
+ }
1079
+ return ruleData;
1080
+ }
1081
+ public setRecurrenceRule(rule: string, startDate: Date = this.startDate): void {
1082
+ if (!rule) {
1083
+ this.repeatType.setProperties({ value: NONE });
1084
+ return;
1085
+ }
1086
+ this.renderStatus = false;
1087
+ this.ruleObject = extractObjectFromRule(rule);
1088
+ const endon: string = this.ruleObject.count ? COUNT : (this.ruleObject.until ? UNTIL : NEVER);
1089
+ switch (this.ruleObject.freq) {
1090
+ case RULEDAILY:
1091
+ this.startState(DAILY, endon, startDate);
1092
+ this.updateUI(DAILY, endon);
1093
+ break;
1094
+ case RULEWEEKLY:
1095
+ this.startState(WEEKLY, endon, startDate);
1096
+ this.updateUI(WEEKLY, endon);
1097
+ break;
1098
+ case RULEMONTHLY:
1099
+ this.startState(MONTHLY, endon, startDate);
1100
+ this.updateUI(MONTHLY, endon);
1101
+ break;
1102
+ case RULEYEARLY:
1103
+ this.startState(YEARLY, endon, startDate);
1104
+ this.updateUI(YEARLY, endon);
1105
+ break;
1106
+ }
1107
+ this.renderStatus = true;
1108
+ this.triggerChangeEvent();
1109
+ }
1110
+
1111
+ private detachInputs(): void {
1112
+ const inputElements: HTMLInputElement[] = [].slice.call(this.element.querySelectorAll('input'));
1113
+ for (const element of inputElements) {
1114
+ detach(element);
1115
+ }
1116
+ }
1117
+
1118
+ /**
1119
+ * Destroys the widget.
1120
+ *
1121
+ * @returns {void}
1122
+ */
1123
+ public destroy(): void {
1124
+ if (!this.isDestroyed) {
1125
+ this.destroyComponents();
1126
+ super.destroy();
1127
+ let removeClasses: string[] = ['e-' + this.getModuleName()];
1128
+ if (this.cssClass) {
1129
+ removeClasses = removeClasses.concat(this.cssClass.split(' '));
1130
+ }
1131
+ removeClass([this.element], removeClasses);
1132
+ this.detachInputs();
1133
+ while (this.element.firstElementChild) {
1134
+ this.element.removeChild(this.element.firstElementChild);
1135
+ }
1136
+ }
1137
+ }
1138
+
1139
+ /**
1140
+ * Get component name.
1141
+ *
1142
+ * @returns {string} Returns the module name
1143
+ * @private
1144
+ */
1145
+ public getModuleName(): string {
1146
+ return 'recurrenceeditor';
1147
+ }
1148
+
1149
+ /**
1150
+ * Get the properties to be maintained in the persisted state.
1151
+ *
1152
+ * @returns {string} Returns the persisted state
1153
+ */
1154
+ public getPersistData(): string {
1155
+ return this.addOnPersist([]);
1156
+ }
1157
+
1158
+ /**
1159
+ * Initialize the control rendering
1160
+ *
1161
+ * @returns {void}
1162
+ * @private
1163
+ */
1164
+ public render(): void {
1165
+ this.initialize();
1166
+ this.rtlClass(this.enableRtl);
1167
+ this.renderStatus = true;
1168
+ this.renderComplete();
1169
+ }
1170
+
1171
+ /**
1172
+ * Called internally, if any of the property value changed.
1173
+ *
1174
+ * @param {RecurrenceEditorModel} newProp Accepts the changed properties new values
1175
+ * @param {RecurrenceEditorModel} oldProp Accepts the changed properties old values
1176
+ * @returns {void}
1177
+ * @private
1178
+ */
1179
+ public onPropertyChanged(newProp: RecurrenceEditorModel, oldProp: RecurrenceEditorModel): void {
1180
+ for (const prop of Object.keys(newProp)) {
1181
+ switch (prop) {
1182
+ case 'startDate':
1183
+ this.selectMonthDay(newProp.startDate);
1184
+ this.updateUntilDate(newProp.startDate);
1185
+ this.endType.setProperties({ index: 0 });
1186
+ break;
1187
+ case 'enableRtl':
1188
+ this.rtlClass(newProp.enableRtl);
1189
+ break;
1190
+ case 'cssClass':
1191
+ if (oldProp.cssClass) { removeClass([this.element], oldProp.cssClass.split(' ')); }
1192
+ if (newProp.cssClass) { addClass([this.element], newProp.cssClass.split(' ')); }
1193
+ break;
1194
+ case 'selectedType':
1195
+ this.repeatType.setProperties({ index: this.selectedType });
1196
+ break;
1197
+ case 'minDate':
1198
+ this.untilDateObj.setProperties({ min: this.minDate });
1199
+ break;
1200
+ case 'maxDate':
1201
+ this.untilDateObj.setProperties({ max: this.maxDate });
1202
+ break;
1203
+ case 'value':
1204
+ if (this.getRecurrenceRule() !== this.value) {
1205
+ this.setRecurrenceRule(this.value as string);
1206
+ }
1207
+ break;
1208
+ case 'calendarMode':
1209
+ this.calendarMode = newProp.calendarMode;
1210
+ this.calendarUtil = getCalendarUtil(newProp.calendarMode);
1211
+ break;
1212
+ case 'locale':
1213
+ case 'frequencies':
1214
+ case 'firstDayOfWeek':
1215
+ case 'endTypes' :
1216
+ this.refresh();
1217
+ break;
1218
+ case 'dateFormat':
1219
+ this.untilDateObj.setProperties({ format: newProp.dateFormat });
1220
+ break;
1221
+ }
1222
+ }
1223
+ }
1224
+ }
1225
+
1226
+ /**
1227
+ * Interface that holds the option on changing the rule in the recurrence editor.
1228
+ */
1229
+ export interface RecurrenceEditorChangeEventArgs {
1230
+ /** Returns the current recurrence rule. */
1231
+ value: string;
1232
+ }
1233
+ type DayFormateType = 'wide' | 'narrow' | 'short';
1234
+
1235
+ /**
1236
+ * Defines the repeat type of the recurrence editor.
1237
+ * ```props
1238
+ * none :- Denotes no repetition.
1239
+ * daily :- Denotes repetition every day.
1240
+ * weekly :- Denotes repetition every week.
1241
+ * monthly :- Denotes repetition every month.
1242
+ * yearly :- Denotes repetition every year.
1243
+ * ```
1244
+ */
1245
+ export type RepeatType = 'none' | 'daily' | 'weekly' | 'monthly' | 'yearly';
1246
+
1247
+ /**
1248
+ * Defines the available types of recurrence end for the recurrence editor.
1249
+ * ```props
1250
+ * The following options are available:
1251
+ *
1252
+ * never :- Denotes that the recurrence has no end date and continues indefinitely.
1253
+ * until :- Denotes that the recurrence ends on a specified date.
1254
+ * count :- Denotes that the recurrence ends after a specified number of occurrences.
1255
+ * ```
1256
+ */
1257
+ export type EndType = 'never' | 'until' | 'count';