DateTimeRangeCadencePickerView.js 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. /*
  2. * Licensed Materials - Property of IBM
  3. *
  4. * IBM Cognos Products: SHARE
  5. *
  6. * (C) Copyright IBM Corp. 2016, 2017
  7. *
  8. * US Government Users Restricted Rights - Use, duplication or disclosure
  9. * restricted by GSA ADP Schedule Contract with IBM Corp.
  10. */
  11. define([
  12. 'bi/schedule/views/CadencePickerView',
  13. 'bi/schedule/app/appControler',
  14. 'jquery',
  15. 'bi/sharecommon/utils/translator',
  16. 'bi/content_apps/utils/GlassContextHelper',
  17. 'q',
  18. 'moment-timezone',
  19. 'bi/sharecommon/utils/simpledoT',
  20. 'text!bi/schedule/templates/DateTimeRangeCadencePicker.html',
  21. 'underscore',
  22. 'bi/commons/ui/widgets/DatePicker',
  23. 'bi/commons/ui/widgets/TimePicker',
  24. 'bi/commons/ui/properties/CheckBox',
  25. 'bi/commons/utils/DateTimeUtils'
  26. ], function(View, controler, $, t, GlassContextHelper, Q, moment, dot, template, _, DatePicker, TimePicker, CheckBox, DateTimeUtils) {
  27. 'use strict';
  28. var DateTimeRange = View.extend({
  29. /**
  30. * @constructor
  31. */
  32. init: function(options) {
  33. DateTimeRange.inherited('init', this, arguments);
  34. _.extend(this, options);
  35. this.descriptor = this.objectInformation.descriptor;
  36. this.isEditMode = typeof(this.descriptor) !== "undefined";
  37. this.noEndDateCheckbox = null;
  38. this.uniqueId = _.uniqueId();
  39. this.timezone = this.glassContext.services.userProfile.preferences.timeZoneID;
  40. this.locale = this._determineDateLocale();
  41. this.logger = this.glassContext.getCoreSvc && this.glassContext.getCoreSvc('.Logger'); //backwards compatible
  42. },
  43. _determineDateLocale: function() {
  44. var prodLocale = GlassContextHelper.getUserPreference(this.glassContext, 'productLocale');
  45. var contentLocale = GlassContextHelper.getUserPreference(this.glassContext, 'contentLocale');
  46. if (prodLocale === contentLocale.substring(0, 2)) {
  47. return contentLocale;
  48. } else {
  49. return prodLocale;
  50. }
  51. },
  52. _renderDateStartEndPeriod: function(translatedStrings) {
  53. var todayAtMidnight = moment.tz(this.timezone).startOf('day');
  54. var sdate = this.isEditMode ? moment.utc(this.descriptor.scheduleInfo.startDate).toDate() : todayAtMidnight.toDate();
  55. this.startDate = new DatePicker({
  56. $el: this.$el.find(".schedule_period_start"),
  57. ariaLabelText: translatedStrings.schedule_datepicker_start,
  58. timezone: this.timezone,
  59. locale: this.locale,
  60. logger: this.logger,
  61. attributes: {
  62. inputFieldDate: sdate
  63. }
  64. });
  65. return this.startDate.render().then(function() {
  66. var edate = new Date(sdate);
  67. edate.setMonth(edate.getMonth() + 3);
  68. if (this.isEditMode) {
  69. if (this.descriptor.scheduleInfo.endType === "onDate") {
  70. edate = moment.utc(this.descriptor.scheduleInfo.endDate).toDate();
  71. }
  72. }
  73. this.endDate = new DatePicker({
  74. $el: this.$el.find(".schedule_period_end"),
  75. ariaLabelText: translatedStrings.schedule_datepicker_end,
  76. timezone: this.timezone,
  77. locale: this.locale,
  78. logger: this.logger,
  79. attributes: {
  80. defaultDate: '+3m',
  81. inputFieldDate: edate
  82. }
  83. });
  84. return this.endDate.render();
  85. }.bind(this));
  86. },
  87. _renderNoEndDateCheckBox: function() {
  88. var checked = false;
  89. if (this.isEditMode && this.descriptor.scheduleInfo && this.descriptor.scheduleInfo.endType && this.descriptor.scheduleInfo.endType != 'onDate') {
  90. this.$el.find(".schedule_date_section_end").hide();
  91. checked = true;
  92. }
  93. this.noEndDateCheckbox = new CheckBox({
  94. 'id': 'schedule_noEndDate_checkbox_' + this.uniqueId,
  95. 'el': this.$el.find('.no_endDate_checkbox'),
  96. 'name': 'schedule_DateTimeRange_noEndDate',
  97. 'label': t.translate('schedule_date_noEndDate'),
  98. 'ariaLabel': t.translate('schedule_date_noEndDate'),
  99. 'checked': checked,
  100. 'controlOnLeft': true,
  101. 'onChange': this._hideShowEndDate.bind(this)
  102. });
  103. this.noEndDateCheckbox.doRender();
  104. },
  105. /**
  106. * Render the new schedule view date time range picker section
  107. *
  108. */
  109. render: function() {
  110. var deferred = Q.defer();
  111. var htmlGenerator = dot.simpleTemplate(template);
  112. var attributes = {
  113. schedule_datepicker_label: t.translate("schedule_datepicker_label"),
  114. schedule_datepicker_start: t.translate("period_start_label"),
  115. schedule_datepicker_end: t.translate("period_end_label"),
  116. schedule_timepicker_label: t.translate("schedule_timepicker_label"),
  117. schedule_timepicker_start: t.translate("period_start_time_label"),
  118. schedule_timepicker_end: t.translate("period_end_time_label"),
  119. uniqueid: this.uniqueId
  120. };
  121. this.$el.append(htmlGenerator(attributes));
  122. this._renderDateStartEndPeriod(attributes).then(function() {
  123. this._renderDateTimeRangeTimePickers();
  124. this._renderNoEndDateCheckBox();
  125. deferred.resolve(this);
  126. }.bind(this));
  127. return deferred.promise;
  128. },
  129. /**
  130. * All views should overwrite this function. It takes a partially
  131. * populated json schedule descriptor and adds to it based on the
  132. * properties of this view.
  133. *
  134. * @param desc the partial JSON schedule descriptor
  135. * @returns the descriptor passed in, with added attributes.
  136. */
  137. toDescriptor: function(desc) {
  138. // Moved from ScheduleView, startDate/endDate is set here, not passed in.
  139. // startDate is midnight on the start date in their timezone.
  140. var startDate = this.startDate.getDateAsISOString();
  141. // Assemble datetime for startDate and endDate based on the selections from the widgets
  142. var asStartDate = moment(startDate).toDate();
  143. // Get the right format for desc
  144. var asStartTime = this.rangeStartTime.getDateTimeUTC(asStartDate);
  145. var endType = this.noEndDateCheckbox.isChecked() ? "indefinite" : "onDate";
  146. var asEndTime = "";
  147. if (endType === "onDate") {
  148. var endDate = this.endDate.getDateAsISOString();
  149. var asEndDate = moment(endDate).toDate();
  150. asEndTime = this.rangeEndTime.getDateTimeUTC(asEndDate);
  151. }
  152. // Push into the desc
  153. desc.startDate = asStartTime;
  154. desc.endDate = asEndTime;
  155. desc.endType = endType;
  156. return desc;
  157. },
  158. validate: function(msgs) {
  159. var parameters = {};
  160. var noEndDateChecked = this.noEndDateCheckbox.isChecked();
  161. // Date
  162. var $startDateDiv = this.$el.find(".schedule_period_start");
  163. var $endDateDiv = this.$el.find(".schedule_period_end");
  164. $startDateDiv.removeAttr('aria-invalid aria-describedby');
  165. $endDateDiv.removeAttr('aria-invalid aria-describedby');
  166. // Time
  167. var $iStartTime = this.$el.find(".schedule_time_start");
  168. var $iEndTime = this.$el.find(".schedule_time_end");
  169. $iStartTime.removeAttr('aria-invalid aria-describedby');
  170. $iEndTime.removeAttr('aria-invalid aria-describedby');
  171. if (!this.startDate.isValidDate()) {
  172. parameters.param1 = t.translate("schedule_period");
  173. parameters.param2 = t.translate("schedule_datepicker_label");
  174. parameters.param3 = t.translate("period_start_label");
  175. msgs.push(t.translate("schedule_invalid_date", parameters));
  176. $startDateDiv.attr({
  177. 'aria-invalid': 'true',
  178. 'aria-describedby': msgs[0]
  179. });
  180. } else if (!noEndDateChecked && !this.endDate.isValidDate()) {
  181. parameters.param1 = t.translate("schedule_period");
  182. parameters.param2 = t.translate("schedule_datepicker_label");
  183. parameters.param3 = t.translate("period_end_label");
  184. msgs.push(t.translate("schedule_invalid_date", parameters));
  185. $endDateDiv.attr({
  186. 'aria-invalid': 'true',
  187. 'aria-describedby': msgs[0]
  188. });
  189. } else if (!this.rangeStartTime.isValidTime()) {
  190. parameters.param1 = t.translate("schedule_period");
  191. parameters.param2 = t.translate("period_start_label");
  192. msgs.push(t.translate("schedule_invalid_time", parameters));
  193. $iStartTime.attr({
  194. 'aria-invalid': 'true',
  195. 'aria-describedby': msgs[0]
  196. });
  197. } else if (!noEndDateChecked && !this.rangeEndTime.isValidTime()) {
  198. parameters.param1 = t.translate("schedule_period");
  199. parameters.param2 = t.translate("period_end_label");
  200. msgs.push(t.translate("schedule_invalid_time", parameters));
  201. $iEndTime.attr({
  202. 'aria-invalid': 'true',
  203. 'aria-describedby': msgs[0]
  204. });
  205. } else if (this.startDate.isValidDate() && this.endDate.isValidDate()) {
  206. // Check start date is less than end date
  207. // No end date not checked
  208. if (!noEndDateChecked) {
  209. var startingDate = this.startDate.getDateObj();
  210. var endingDate = this.endDate.getDateObj();
  211. if (startingDate > endingDate) {
  212. parameters.param1 = t.translate("schedule_period");
  213. parameters.param2 = t.translate("schedule_datepicker_label");
  214. msgs.push(t.translate("schedule_invalid_date_range", parameters));
  215. $endDateDiv.attr({
  216. 'aria-invalid': 'true',
  217. 'aria-describedby': msgs[0]
  218. });
  219. }
  220. }
  221. }
  222. return msgs;
  223. },
  224. _renderDateTimeRangeTimePickers: function() {
  225. this.rangeStartTime = new TimePicker({
  226. $el: this.$el.find(".schedule_time_start"),
  227. timezone: this.timezone,
  228. ariaLabel: t.translate("period_start_time_label"),
  229. attributes: {
  230. showMeridian: !DateTimeUtils.is24HrFormat(this.locale)
  231. }
  232. });
  233. this.rangeStartTime.render();
  234. this.rangeEndTime = new TimePicker({
  235. $el: this.$el.find(".schedule_time_end"),
  236. timezone: this.timezone,
  237. ariaLabel: t.translate("period_end_time_label"),
  238. attributes: {
  239. showMeridian: !DateTimeUtils.is24HrFormat(this.locale)
  240. }
  241. });
  242. this.rangeEndTime.render();
  243. if (this.isEditMode) {
  244. if (this.descriptor.scheduleInfo && this.descriptor.scheduleInfo.startDate) {
  245. this.rangeStartTime.setDateTimeUTC(this.descriptor.scheduleInfo.startDate);
  246. }
  247. if (this.descriptor.scheduleInfo && this.descriptor.scheduleInfo.endDate) {
  248. this.rangeEndTime.setDateTimeUTC(this.descriptor.scheduleInfo.endDate);
  249. }
  250. }
  251. },
  252. _hideShowEndDate: function(name, value) {
  253. if (value) {
  254. this.$el.find(".schedule_date_section_end").hide();
  255. } else {
  256. this.$el.find(".schedule_date_section_end").show();
  257. }
  258. }
  259. });
  260. return DateTimeRange;
  261. });