November Happy Hour will be moved to Thursday December 5th.

multipleDefine console error when adding custom dojo editor control

Vote:
 

I've added a custom UTC Time picker control to my CMS 12 solution. This was previously working in a CMS 11 website. When loading the CMS editor i get the following "multipleDefine" errors in the console:

I've added the js files to my wwwroot here:

And i've added a module.config to the root of my project

The js files are downloading from this client resources folder. 

TimePickerUtc.js

define([
		'dojo/_base/lang',
		'dijit/_TimePicker',
		'dojo/_base/array',
		'dojo/date', // date.compare
		'dojo/date/locale', // locale.format
		'dojo/date/stamp', // stamp.fromISOString stamp.toISOString
		'dojo/_base/declare', // declare
		'dojo/dom-class', // domClass.add domClass.contains domClass.toggle
		'dojo/dom-construct' // domConstruct.create
	],
	function(lang, _TimePicker, array, dojoDate, locale, stamp, declare, domClass, domConstruct) {

		return declare('Epik/Editors/TimePickerUtc', [_TimePicker],
			{
				// summary:
				//      Patch TimePicker to display UTC time
				_createOption: function(/*Number*/ index) {
					// summary:
					//		Patch the method to create time option in UTC
					var date = new Date(this._refDate);
					var incrementDate = this._clickableIncrementDate;
					date.setTime(date.getTime() +
						incrementDate.getHours() * index * 3600000 +
						incrementDate.getMinutes() * index * 60000 +
						incrementDate.getSeconds() * index * 1000);

					/*------PATCH START------*/

					if (this.constraints.selector === 'time') {
						date.setUTCFullYear(1970, 0, 1); // make sure each time is for the same UTC date
					}
					// show UTC time on the options
					var utcOffsetDate = new Date(date.getTime() + date.getTimezoneOffset() * 60 * 1000);
					var dateString = locale.format(utcOffsetDate, this.constraints);

					/*------PATCH END------*/

					if (this.filterString && dateString.toLowerCase().indexOf(this.filterString) !== 0) {
						// Doesn't match the filter - return null
						return null;
					}

					var div = this.ownerDocument.createElement('div');
					div.className = this.baseClass + 'Item';
					div.date = date;
					div.idx = index;
					domConstruct.create('div',
						{
							"class": this.baseClass + 'ItemInner',
							innerHTML: dateString
						},
						div);

					if (index % this._visibleIncrement < 1 && index % this._visibleIncrement > -1) {
						domClass.add(div, this.baseClass + 'Marker');
					} else if (!(index % this._clickableIncrement)) {
						domClass.add(div, this.baseClass + 'Tick');
					}

					//if (this.isDisabledate(date)) {
					//	// set disabled
					//	domClass.add(div, this.baseClass + 'ItemDisabled');
					//}
					if (this.value && !dojoDate.compare(this.value, date, this.constraints.selector)) {
						div.selected = true;
						domClass.add(div, this.baseClass + 'ItemSelected');
						if (domClass.contains(div, this.baseClass + 'Marker')) {
							domClass.add(div, this.baseClass + 'MarkerSelected');
						} else {
							domClass.add(div, this.baseClass + 'TickSelected');
						}

						// Initially highlight the current value.   User can change highlight by up/down arrow keys
						// or mouse movement.
						this._highlightOption(div, true);
					}
					return div;
				}
			});
	});

TimeTextBoxUtc.js

define([
		'dojo/_base/declare',
		'dojo/date/locale', // locale.format
		'dojo/date/stamp', // stamp.fromISOString stamp.toISOString
		'dijit/form/TimeTextBox',
		'./TimePickerUtc'
	],
	function(declare, locale, stamp, TimeTextBox, TimePickerUtc) {

		return declare('Epik/Editors/TimeTextBoxUtc', [TimeTextBox],
			{
				// summary:
				//      TimeTextBox in UTC time

				// with patched time picker
				popupClass: TimePickerUtc,

				parse: function () {
					// summary:
					//		Override the method to parse the string as UTC time

					// the value is parsed as local time
					var value = this.inherited(arguments);

					// calculate UTC time
					if (value instanceof Date) {
						value = new Date(value.getTime() - value.getTimezoneOffset() * 60 * 1000);
					}
					return value;
				},

				_setValueAttr: function (value, priorityChange, formattedValue) {
					// summary:
					//		Override the method to set UTC time. Note: value can be a JavaScript Date literal or a string to be parsed.

					if (typeof value === 'string') {
						value = stamp.fromISOString(value);
					}
					if (value instanceof Date && !this._isInvalidDate(value)) {
						// set UTC time string as formattedValue, which is shown in the textBox
						var utcOffsetDate = new Date(value.getTime() + value.getTimezoneOffset() * 60 * 1000);
						arguments[2] = locale.format(utcOffsetDate, this.constraints);
						arguments.length = 3;
					}
					this.inherited(arguments);
				}
			});
	});

What am i missing in the dojo setup?

#322925
Edited, May 31, 2024 5:31
Vote:
 

Hi Patrick,

I do not see the detail error. I think we need to find which component name is duplicated first. Could you try to turn on Client Debug and let's see if we can see error more detail?

You can turn on Client Debug in Optimizely cms 12 via this link https://docs.developers.optimizely.com/content-management-system/docs/debugging-cms-ui

#323030
Jun 03, 2024 7:35
Vote:
 

I have the client debug turned on, but don't see any more detail than what is above. Here is the info console entry expanded:

#323090
Edited, Jun 04, 2024 2:40
Vote:
 

I believe that it is "dijit/form/TimeTextBox" that is being loaded more than once.

#323093
Jun 04, 2024 3:47
Vote:
 

Hi Patrick

I think your issue is path related. The path for dojo "EpiK" should be "Scripts" without slash. For client resources path should be "Scripts/Editors/TimeTextBoxUtc.js" same as the other one. 

 

I hope above helps. If my suggetion solved your issue, help others by not ''forgetting to mark it as accepted solution" :)

#323137
Jun 05, 2024 0:30
Vote:
 

Changing the paths as suggested above does not resolve the errors, i'm still seeing the multipleDefine error.

#323138
Jun 05, 2024 3:08
Vote:
 

Hi Patrick,

Should define module id in your Dojo module like define('Epik/Editors/TimePickerUtc',...) to avoid duplicating with default one or something like this

Update js as following:

TimePickerUtc.js

define('Epik/Editors/TimePickerUtc', [
		'dojo/_base/lang',
		'dijit/_TimePicker',
		'dojo/_base/array',
		'dojo/date', // date.compare
		'dojo/date/locale', // locale.format
		'dojo/date/stamp', // stamp.fromISOString stamp.toISOString
		'dojo/_base/declare', // declare
		'dojo/dom-class', // domClass.add domClass.contains domClass.toggle
		'dojo/dom-construct' // domConstruct.create
	],
	function(lang, _TimePicker, array, dojoDate, locale, stamp, declare, domClass, domConstruct) {

		return declare([_TimePicker],
			{
				// summary:
				//      Patch TimePicker to display UTC time
				_createOption: function(/*Number*/ index) {
					// summary:
					//		Patch the method to create time option in UTC
					var date = new Date(this._refDate);
					var incrementDate = this._clickableIncrementDate;
					date.setTime(date.getTime() +
						incrementDate.getHours() * index * 3600000 +
						incrementDate.getMinutes() * index * 60000 +
						incrementDate.getSeconds() * index * 1000);

					/*------PATCH START------*/

					if (this.constraints.selector === 'time') {
						date.setUTCFullYear(1970, 0, 1); // make sure each time is for the same UTC date
					}
					// show UTC time on the options
					var utcOffsetDate = new Date(date.getTime() + date.getTimezoneOffset() * 60 * 1000);
					var dateString = locale.format(utcOffsetDate, this.constraints);

					/*------PATCH END------*/

					if (this.filterString && dateString.toLowerCase().indexOf(this.filterString) !== 0) {
						// Doesn't match the filter - return null
						return null;
					}

					var div = this.ownerDocument.createElement('div');
					div.className = this.baseClass + 'Item';
					div.date = date;
					div.idx = index;
					domConstruct.create('div',
						{
							"class": this.baseClass + 'ItemInner',
							innerHTML: dateString
						},
						div);

					if (index % this._visibleIncrement < 1 && index % this._visibleIncrement > -1) {
						domClass.add(div, this.baseClass + 'Marker');
					} else if (!(index % this._clickableIncrement)) {
						domClass.add(div, this.baseClass + 'Tick');
					}

					//if (this.isDisabledate(date)) {
					//	// set disabled
					//	domClass.add(div, this.baseClass + 'ItemDisabled');
					//}
					if (this.value && !dojoDate.compare(this.value, date, this.constraints.selector)) {
						div.selected = true;
						domClass.add(div, this.baseClass + 'ItemSelected');
						if (domClass.contains(div, this.baseClass + 'Marker')) {
							domClass.add(div, this.baseClass + 'MarkerSelected');
						} else {
							domClass.add(div, this.baseClass + 'TickSelected');
						}

						// Initially highlight the current value.   User can change highlight by up/down arrow keys
						// or mouse movement.
						this._highlightOption(div, true);
					}
					return div;
				}
			});
	});

TimeTextBoxUtc.js

define('Epik/Editors/TimeTextBoxUtc', [
		'dojo/_base/declare',
		'dojo/date/locale', // locale.format
		'dojo/date/stamp', // stamp.fromISOString stamp.toISOString
		'dijit/form/TimeTextBox',
		'./TimePickerUtc'
	],
	function(declare, locale, stamp, TimeTextBox, TimePickerUtc) {

		return declare([TimeTextBox],
			{
				// summary:
				//      TimeTextBox in UTC time

				// with patched time picker
				popupClass: TimePickerUtc,

				parse: function () {
					// summary:
					//		Override the method to parse the string as UTC time

					// the value is parsed as local time
					var value = this.inherited(arguments);

					// calculate UTC time
					if (value instanceof Date) {
						value = new Date(value.getTime() - value.getTimezoneOffset() * 60 * 1000);
					}
					return value;
				},

				_setValueAttr: function (value, priorityChange, formattedValue) {
					// summary:
					//		Override the method to set UTC time. Note: value can be a JavaScript Date literal or a string to be parsed.

					if (typeof value === 'string') {
						value = stamp.fromISOString(value);
					}
					if (value instanceof Date && !this._isInvalidDate(value)) {
						// set UTC time string as formattedValue, which is shown in the textBox
						var utcOffsetDate = new Date(value.getTime() + value.getTimezoneOffset() * 60 * 1000);
						arguments[2] = locale.format(utcOffsetDate, this.constraints);
						arguments.length = 3;
					}
					this.inherited(arguments);
				}
			});
	});
#323139
Jun 05, 2024 6:00
Vote:
 

Moving the "'Epik/Editors/TimeTextBoxUtc'" definition to the define method of the javascript has fixed the issue.

#323142
Jun 05, 2024 7:52
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.