/* * THIS FILE IS MEANT TO CONTAIN ANY OVERRIDES MADE ON THE SENCHA CLASSES/METHODS. * IDEALLY, WE SHOULD REQUEST SENCHA TO IMPLEMENT THE CHANGE AND PROVIDE IT IN THE NEXT RELEASE INSTEAD, BUT DEPENDING UPON BUG SEVERITY IT MIGHT NOT ALWAYS BE POSSIBLE. * * PLEASE SPECIFY THE FIDDLE ID IN THE COMMENTS WHICH REPLICATES THE SCENARIO FOR WHICH THE OVERRIDE WAS INTRODUCED, * ALSO SPECIFY COMMENTS IN FIDDLE TOO FOR EASIER UNDERSTANDING/REPLICATION OF THE PROBLEM * SENCHA COULD HAVE FIXED THIS IN THE NEXT RELEASE AND IT WOULD BE VERY EASY TO CHECK IT ON THE FIDDLE RATHER THAN GOING THROUGH CHANGE HISTORIES AND BUGS. * IF FIXED, THE CORRESPONDING OVERRIDE SHOULD BE REMOVED. */ /********************* when Ext.grid.column defaultRenderer to htmlEncode *******************/ // Fiddle ID: 33ut (if fiddle works, then remove this) // Column in the grid has htmldecode by default, so to restrict not to decode(default behaviour) below code has been added. Ext.override(Ext.grid.column.Column, { defaultRenderer: Ext.util.Format.htmlEncode }); /********************************************************************************************/ // Fiddle ID: 3eva (if fiddle works, then remove this. info is in fiddle). // To achieve rtl, we are currently specifying rtl: true on root level container(mainContainer) only. This automatically applies rtl: true on all of its child elements, but floating elements(resource tree, messagebox etc..) are not. // We could either set rtl: true individually on all such floating elements or just use below override to set rtl: true on all elements(which is what already happens for all the child elements under mainContainer anyway) Ext.override(Ext.Component, { rtl: USE_RTL, }); /********************* when Ext.encode is called Converts from java script date to JSON Date ****************************************/ // to encodeDate. Ext.JSON.encodeDate = function (d) { var str = d.getTime(); var timeZoneOffset = d.getTimezoneOffset(); if (timeZoneOffset < 0) { timeZoneOffset *= -1; } var hours = '' + Math.floor(timeZoneOffset / 60); if (hours.length != 2) hours = '0' + hours; var minutes = '' + Math.floor(timeZoneOffset % 60); if (minutes.length != 2) minutes = '0' + minutes; if (d.getTimezoneOffset() > 0) { hours = '-' + hours; } else { hours = '+' + hours; } return '"\/Date(' + str + hours + '' + minutes + ')\/"'; }; /*******************************************************************************************/ /********************* Overrided to implement Locale Date Format ***************************/ Ext.override(Ext.form.field.Date, { invalidText: "{0} is not a valid date.", constructor: function () { // new designer does not load common.js, it does not need dateformats, so check whether Forms.Common.Common is defined or not if (Ext.isDefined(window.Forms) && Forms.Common && Forms.Common.Common) { if (!arguments[0]) { arguments[0] = {}; } //overriding the format of date control with browser locale DateFormat arguments[0].format = Forms.Common.Common.GetDateFormat(); if (arguments[0].dtype) { // Added as part of issue TFS-307894 this.invalidText = this.invalidText.replace("{1}", Forms.Common.Common.GetCsharptDateFormat()); } else { // Added as part of issue 980992 this.invalidText = this.invalidText.replace("{1}", Forms.Common.Common.GetCsharptDateTimeFormat()); } } this.callParent(arguments); }, getValue: function () { if (this.getRawValue() == null || Ext.isEmpty(this.getRawValue())) { return null; } if (Ext.isDate(this.value)) { return this.value; } try { var d = Ext.Date.parse(this.getRawValue(), this.format); if (d) { return d; } } catch (ex) { } return null; } }); Ext.override(Ext.form.field.Time, { constructor: function () { if (!arguments[0]) { arguments[0] = {}; } //overriding the format of time control with browser locale TimeFormat arguments[0].format = Forms.Common.Common.GetTimeFormatWithoutSeconds(); this.callParent(arguments); } }); Ext.override(Ext.grid.column.Date, { constructor: function () { if (!arguments[0]) { arguments[0] = {}; } //overriding the format of time control with browser locale TimeFormat arguments[0].format = Forms.Common.Common.GetDateTimeFormat(); //workqueue and joblist control's datecolumn format, 0-Date, 1-DateTime if (arguments[0].dateFormat == 0) { arguments[0].format = Forms.Common.Common.GetDateFormat(); } this.callParent(arguments); if (!arguments[0].renderer) { this.renderer = this.defaultRenderer; this.scope = this; } } }); /*******************************************************************************************/ /********************* Ext control base overrides *****************************************/ Ext.override(Ext.form.field.Base, { labelSeparator: '', // Fix for SPR00115337 - remove all ":" label separators // donot validate the hidden and not rendered fields in sync with 5.5 isValid: function () { var field = formControl = this, isFieldValid = true; var cell = field.up(); // for datefield/timefield under the calendar control, you need to move up one more level to get the control and cell var isCalendar = Ext.ClassManager.getName(cell) == 'Forms.Controls.Standard.Calendar'; if (isCalendar) { formControl = cell; cell = formControl.up(); } // if the control is hidden by the user then donot validate if (formControl.isUserDefinedHidden || (cell && cell.isUserDefinedHidden)) { field.clearInvalid(); return true; } isFieldValid = field.validateValue(field.processRawValue(field.getRawValue())); if (isFieldValid) { if (!field.disabled && field.isFieldValid !== undefined && !field.isFieldValid) { isFieldValid = field.isFieldValid; field.markInvalid(field.blankText); } } return isFieldValid || field.disabled; }, htmlEncode:true }); /*********************1496653 issue fix *****************************************/ Ext.override(Ext.Component, { visibleByDisplayRulesForTAControls: true, visibleBySecurityTokenForTAControls: true, // As part of 1496653 issue fix, if a control is hidden due to security token it should not be made visible by display rules. // This code has to work for all controls so the EXt.Component is overridden. setVisibleBySecurityTokenForTAControls: function (a) { this.visibleBySecurityTokenForTAControls = a; this.updateVisibleForTAControls(); }, setVisibleByDisplayRulesForTAControls: function (a) { this.visibleByDisplayRulesForTAControls = a; this.updateVisibleForTAControls(); }, updateVisibleForTAControls: function () { if (this.setVisible) { this.setVisible(this.calculateResultingVisibilityForTAControls()) } }, calculateResultingVisibilityForTAControls: function () { var a = true; a &= this.visibleBySecurityTokenForTAControls; a &= this.visibleByDisplayRulesForTAControls; return a }, }); /******************************************************************************************/ /********************* CheckboxGroup Validate override ****************************************/ // donot validate the hidden radio button control Ext.override(Ext.form.CheckboxGroup, { validate: function () { var me = this; // if the parent control of radio group is hidden by the user then donot validate // else validate it by calling the original validate method if (me.xtype == "radiogroup" && me.up() && me.up().isUserDefinedHidden) { return true; } return this.callParent(); } }); /*******************************************************************************************/ /********************* Radio group label separator ****************************************/ Ext.override(Ext.form.RadioGroup, { labelSeparator: '' // Fix for SPR00261660 - remove all ":" for radiogroup label separators }); /*******************************************************************************************/ /********************* Text field controls to add class to it ******************************/ //To not to allow all blank spaces in field, It will be considered as Empty Ext.override(Ext.form.field.Text, { beforeRender: function () { this.callParent(arguments); this.addCls('x-form-field-text'); } }); Ext.override(Ext.form.field.TextArea, { beforeRender: function () { this.callParent(arguments); this.addCls('x-form-field-text'); } }); Ext.override(Ext.form.field.Number, { onRender: function () { this.callParent(arguments); $('#' + this.getId()).addClass('x-form-field-text'); } }); Ext.override(Ext.form.ComboBox, { beforeRender: function () { this.callParent(arguments); this.removeCls('x-form-field-text'); this.addCls('x-form-field-combobox'); } }); /********************************************************************************************/ /********************* Ext.panel.Panel *************************************************************/ Ext.override(Ext.panel.Panel, { // Enables or disables the control setEnable: function (shouldEnable) { this.setDisabled(!shouldEnable); }, setMandatory: function (mandatory) { }, setReadOnly: function (readOnly) { } }); /**************************************************************************************************/ /********************* Ext.view.BoundList htmlencode ***********************************************/ // Ext.util.Format.htmlEncode is added to encode data to avoid javascript injection for dropdown Ext.override(Ext.view.BoundList, { getInnerTpl: function (displayField) { return '{[Ext.util.Format.htmlEncode(values["' + displayField + '"])]}'; } }); // htmlEncode is set to true to encode data to avoid javascript injection for display filed Ext.override(Ext.form.field.Display, { htmlEncode: true }); /**************************************************************************************************/ /********************* Ext.JSON.encodeValue *******************************************************/ /* * The original overriden method ends up calling JSON.stringify(due to Ext.USE_NATIVE_JSON changed to true in 6.6.0) * this results in our other overriden encode methods not being called, especially the Ext.JSON.encodeDate override, which in turn results in wcf failing to deserialize date values * so override Ext.encode to not call JSON.stringify * Note: we could just revert back Ext.USE_NATIVE_JSON to false instead, but that would lead to a security threat for Ext.decode(https://www.sencha.com/forum/showthread.php?285956) * Fiddle ID: 2mig (replication steps are in there) */ Ext.encode = function (o) { return Ext.JSON.encodeValue(o); }; Ext.JSON.encodeValue = function (o, newline) { var useHasOwn = !!{}.hasOwnProperty; var me = this; // http://jsperf.com/is-undefined if (o === null || o === undefined) { return "null"; } else if (Ext.isDate(o)) { return me.encodeDate(o); } else if (Ext.isString(o)) { if (Ext.isMSDate(o)) { return me.encodeMSDate(o); } else { return me.encodeString(o); } } else if (typeof o === "number") { //don't use isNumber here, since finite checks happen inside isNumber return isFinite(o) ? String(o) : "null"; } else if (Ext.isBoolean(o)) { return String(o); } // Allow custom zerialization by adding a toJSON method to any object type. // Date/String have a toJSON in some environments, so check these first. else if (o.toJSON) { return o.toJSON(); } else if (Ext.isArray(o)) { return encodeArray(o, newline); } else if (Ext.isObject(o)) { return encodeObject(o, newline); } else if (typeof o === "function") { return "null"; } return 'undefined'; function encodeObject(o, newline) { if (newline) { return encodeObjectPretty(o, newline); } var a = [ "{", "" ], // Note empty string in case there are no serializable members. i, val; for (i in o) { val = o[i]; if (!useHasOwn || o.hasOwnProperty(i)) { // To match JSON.stringify, we shouldn't encode functions or undefined if (typeof val === 'function') { continue; } a.push(me.encodeValue(i), ":", me.encodeValue(val), ','); } } // Overwrite trailing comma (or empty string) a[a.length - 1] = '}'; return a.join(""); } function encodeObjectPretty(o, newline) { var cnewline = newline + ' ', sep = ',' + cnewline, a = ["{", cnewline], // Note newline in case there are no members i, val; for (i in o) { val = o[i]; if (!useHasOwn || o.hasOwnProperty(i)) { // To match JSON.stringify, we shouldn't encode functions or undefined if (typeof val === 'function' || val === undefined) { continue; } a.push(me.encodeValue(i) + ': ' + me.encodeValue(val, cnewline), sep); } } // Overwrite trailing comma (or empty string) a[a.length - 1] = newline + '}'; return a.join(''); } function encodeArrayPretty(o, newline) { var len = o.length, cnewline = newline + ' ', sep = ',' + cnewline, a = ["[", cnewline], // Note newline in case there are no members i; for (i = 0; i < len; i += 1) { a.push(me.encodeValue(o[i], cnewline), sep); } // Overwrite trailing comma (or empty string) a[a.length - 1] = newline + ']'; return a.join(''); } function encodeArray(o, newline) { if (newline) { return encodeArrayPretty(o, newline); } var a = ["[", ""], // Note empty string in case there are no serializable members. len = o.length, i; for (i = 0; i < len; i += 1) { a.push(me.encodeValue(o[i]), ','); } // Overwrite trailing comma (or empty string) a[a.length - 1] = ']'; return a.join(""); } }; /**************************************************************************************************/ Ext.override(Ext.form.field.Checkbox, { render: function () { this.callParent(arguments); var me = this; if (this.ariaRole == "checkbox") $('#' + this.getId() + ' .x-form-cb-label').addClass('x-form-field-checkbox'); if (this.ariaRole == "radio") { $('#' + this.getId() + ' .x-form-cb-label').addClass('x-form-field-radio'); this.ownerCt.on('afterlayout', function () { var me = this; if (me.labelWidth > 0) { //fix for radio button list label issue var radiobuttonWidth = convertPXToInteger($('#' + me.getId() + ' .x-form-item-body').css('width')); var labelWidth = radiobuttonWidth - convertPXToInteger($('#' + me.getId() + ' input').css('width')); if (me.boxLabelAlign == 'after') { labelWidth = labelWidth - convertPXToInteger($('#' + me.getId() + ' label').css('margin-left')); } else { labelWidth = labelWidth - convertPXToInteger($('#' + me.getId() + ' label').css('margin-right')); } $('#' + me.getId() + ' input').css('vertical-align', 'top'); $('#' + me.getId() + ' label').css('width', labelWidth + 'px'); } }); } } }); /********************* Ext.form.field.ComboBox *******************************************************/ // Fiddle ID: 2vqc (if fiddle works, then remove this, retest the associated bug too) // when there is not enough space to let combobox show its items, then you cannot scroll through and select some of the top/bottom items(depending upon where the list is being shown) // refer bug for more info. below is the override from sencha and which tries to remove maxHeight: 300 from the defaultListConfig, which is causing the problem. // doing so makes the combobox list height adjustable to the height available, the only side effect is - for unusually smaller windows, the combobox list appears smaller(only to fit 1 or 2 items but all can be scrolled) Ext.define(null, { override: 'Ext.form.field.ComboBox', defaultListConfig: { loadingHeight: 70, minWidth: 70, shadow: 'sides' } }); /**************************************************************************************************/ /********************* Ext Grid cell editing *******************************************************/ // Fiddle ID: 2vd5 (if fiddle works, then remove this, retest the associated bug too) // below is a woraround. if a column is disabled, it's editor will be disabled too, but this is causing a problem when you click on disabled cell and delete the row. // all floating elements in the page(menus, dropdowns etc..) are showing up incorrectly or are not showing up at all(refer bug/fiddle) // below is a workaround to get around this problem, this should be called prior to row deletion. we could have choosen other alternatives such as making the cell readOnly instead of disabled, // or not specifying the editor altogether, but it wont be the same as having disabled cells(i.e disabeld cells show up greyed out and moreover they cannot be tabbed through) function cancelActiveEditsBeforeDeletingRows(grid) { var cellEditingPlugin = grid.findPlugin('cellediting'); // plugin wont be set yet during initialization(initializeFormControls calls clearData), so check it before calling cancelEdit // we dont have to call cancelEdit during initialization. moreover, the table control might not have this plugin at all(i.e Modify property is set to No) if (cellEditingPlugin) { cellEditingPlugin.cancelEdit(); } } /**************************************************************************************************/ /********************* Ext.button.Button *******************************************************/ // Bug 1545638: Image Viewer's enabled buttons don't have hints // Bug 1595147: There is no tooltips in wcc activity if icons in active state (after page imported/loaded) // Sencha ticket #52382 Button tooltip is missing after enabling the button Ext.override(Ext.button.Button, { setTooltip: function (tooltip, initial) { var me = this, targetEl = me.el; if (me.rendered) { if (!initial || !tooltip) { me.clearTip(); } // BEGIN OF THE FIX /* if (me.disabled) { targetEl = me.tooltipEl; }*/ // END OF THE FIX if (tooltip) { if (Ext.quickTipsActive && Ext.isObject(tooltip)) { Ext.tip.QuickTipManager.register(Ext.apply({ target: targetEl.id }, tooltip)); me.tooltip = tooltip; } else { targetEl.dom.setAttribute(me.getTipAttr(), tooltip); } me.currentTooltipEl = targetEl; } } else { me.tooltip = tooltip; } return me; } }); /**************************************************************************************************/