Create custom editors
An editor is a special Dojo container widget that contains the logic to open a task in the application. The editor contains some UI components, which provide consistent appearance for similar tasks. For example, order modification tasks.
<Editor Name.js>- The JS file corresponding to the editor. You can define all your behavior logic in this file.templates/<Editor name>.html- The HTML file that contains all the UI information.<Editor name>BehaviorController.js- The JS file that contains themashuprefsdetails that are called on some action or behavior on the editor.<Editor name>InitController.js- The JS file that contains themashuprefsdetails that are called when you start the editor.
In addition to JavaScript files, ensure that the <Editor
name>BehaviorController.xml and <Editor name>InitController.xml Controller
XML files are also present.
For more information about creating the <Editor name>BehaviorController.js, <Editor
name>InitController.js, <Editor name>BehaviorController.xml,
and <Editor name>InitController.xml, see Customize controllers.
setScreenTitle- This event is raised to set the title and subtitle on the Editor Title panel. For example, in the Create Order wizard, the title is Create Order and subtitle is Customer Search, which is the first screen in the wizard page.setEditorInput- This event is raised to update the editor input, which is used for opening a wizard or screen in the existing editor. For example, in the create order wizard, on selecting a customer, thesetEditorInputevent is raised by the Customer identification page to update the customer information in the editor input.
Create the <Editor name>.js file
Ensure
that the <Editor name>.js file syntax adheres
to Dojo version 1.8 standards. The custom editor must extend sc/plat/dojo/widgets/Editor.
Additionally, you can use the following application-provided standards:
- You can use
scDefineinstead ofdefine. - You can precede the imported JavaScript modules with
scbase/loader!string. Thescbase/loaderstring is a Dojo loader plug-in that is provided by the application. Precede an html file path with adojo/text!string according to the Dojo syntax.
Sample MyOrderEditor.js file
scDefine(["dojo/text!./templates/MyOrderEditor.html",
"scbase/loader!dojo/_base/declare",
"scbase/loader!idx/layout/ContentPane",
"scbase/loader!sc/plat",
"scbase/loader!sc/plat/dojo/binding/CurrencyDataBinder",
"scbase/loader!sc/plat/dojo/binding/ImageDataBinder",
"scbase/loader!sc/plat/dojo/layout/AdvancedTableLayout",
"scbase/loader!sc/plat/dojo/widgets/Editor",
"scbase/loader!sc/plat/dojo/widgets/Image",
"scbase/loader!sc/plat/dojo/widgets/Label",
"scbase/loader!sc/plat/dojo/widgets/Link"], function(
templateText, _dojodeclare, _idxContentPane, _scplat, _scCurrencyDataBinder, _scImageDataBinder, _scAdvancedTableLayout,
_scEditor, _scImage, _scLabel, _scLink) {
return _dojodeclare("extn.editors.MyOrderEditor", [_scEditor], {
templateString: templateText,
uId: "MyOrderEditor",
packageName: "extn.editors",
className: "MyOrderEditor",
namespaces: {
targetBindingNamespaces: [],
sourceBindingNamespaces: [{
description: 'Holds the initial editor input passed into the editor on open.',
value: 'InitialEditorInput'
}]
},
// comparisonAttributes are used to create a model object (JSON Object), which is used for
// comparing two different instances for the editor. If the model object that is created by using
// comparisonAttributes for two instances of the editor are similar, they are identified as the
// matching editor. This is mainly used to determine whether the new instance of the editor
// must be opened in a new tab or focused on the matching editor.
// This is used when using the sc.plat.dojo.utils.ControllerUtils.openScreenInEditor utility
comparisonAttributes: ["Order.OrderHeaderKey"],
hotKeys: [],
events: [ {
name: 'setEditorInput'
}],
subscribers: {
local: [ {
eventId: 'setEditorInput',
sequence: '25',
handler: {
methodName: "setEditorInput"
}
}],
},
getScreenTitle: function() {
},
showOrHideRelTask: function(
event, bEvent, ctrl, args) {
var isWizardinitialized = null;
var isRTscreeninitialized = null;
isWizardinitialized = _scBaseUtils.getAttributeValue("isWizardinitialized", false, args);
isRTscreeninitialized = _scBaseUtils.getAttributeValue("isRTscreeninitialized", false, args);
if (!(
_scBaseUtils.isVoid(
isRTscreeninitialized))) {
this.isRTscreeninitialized = isRTscreeninitialized;
}
if (!(
_scBaseUtils.isVoid(
isWizardinitialized))) {
this.isWizardinitialized = isWizardinitialized;
}
if (!(
_isccsWidgetUtils.isWizardInstance(
_scEditorUtils.getScreenInstance(
this)))) {
_isccsBaseTemplateUtils.hideRelatedTask(
this);
} else {
if (
_scBaseUtils.and(
_scBaseUtils.equals(
this.isWizardinitialized, "true"), _scBaseUtils.equals(
this.isRTscreeninitialized, "true"))) {
_isccsBaseTemplateUtils.hideRelatedTask(
this);
}
}
},
updateScreenWithEditorInput: function(
model) {
},
onScreenInit: function(
event, bEvent, ctrl, args) {
},
setInitialEditorInput: function(
screenInput) {
},
setScreenTitle: function(
event, bEvent, ctrl, args) {
},
setEditorInput: function(
event, bEvent, ctrl, args) {
}
});
});Create the templates/<Editor name>.html file
The templates/<Editor
name>.html file renders the UI for an editor. It contains
all the widgets present in the editor and adheres to Dojo 1.8 syntax.
It is used for creating widgets declaratively by using an HTML file.
Sample MyOrderEditor.html file
<div class="sc-platform-screen-default myordereditor">
<div data-dojo-type="idx/layout/ContentPane" data-dojo-props="spanLabel : true ,
'class' : 'screenTitleContainer',
uId : 'titleMessagePanel'
">
<div data-dojo-type="idx/layout/ContentPane" data-dojo-props=" spanLabel : true ,
'class' : 'screenTitlePanel' ,
uId : 'pnlTitleBar'
">
<div data-dojo-type="sc/plat/dojo/layout/AdvancedTableLayout" data-dojo-props=" showLabels : false ,
cols : 2 ,
customClass : 'screenTitleTableContainer'
">
<div data-dojo-type="sc/plat/dojo/widgets/Image" data-dojo-props=" 'class' : 'icon-screen-order screenTitleImage' ,
uId : 'lb_titleImage'
"></div>
<div data-dojo-type="idx/layout/ContentPane" data-dojo-props=" spanLabel : true ,
uId : 'pnlTitleContainer'
">
<div data-dojo-type="sc/plat/dojo/widgets/Label" data-dojo-props=" spanLabel : true ,
'class' : 'screenTitle' ,
uId : 'lb_screenTitle'
"></div>
<div data-dojo-type="sc/plat/dojo/widgets/Label" data-dojo-props=" spanLabel : true ,
'class' : 'screenSubTitle' ,
uId : 'lb_screenSubTitle'
,scParamDataFn :
function() {
return {
title : this.getSimpleBundleString('blank')
,
value : this.getSimpleBundleString('blank')
}
}
"></div>
</div>
</div>
</div>
<div data-dojo-type="idx/layout/ContentPane" data-dojo-props=" 'class' : 'enterpriseHolder' ,
uId : 'pnlEnterpriseHolder' ,
'aria-label' : 'Current Enterprise'
" role='region'>
<div data-dojo-type="sc/plat/dojo/widgets/Image" data-dojo-props=" 'class' : 'icon-enterprise' ,
uId : 'imgEnterprise'
"></div>
<div data-dojo-type="sc/plat/dojo/widgets/Label" data-dojo-props=" 'class' : 'icon-image-label groupHeader' ,
uId : 'lblEnterprise'
,scParamDataFn :
function() {
return {
bindingData : {
sourceBinding : {
path : 'Order.EnterpriseName'
,
namespace : 'enterpriseContext'
}
}
}
}
"></div>
</div>
</div>
<div data-dojo-type="idx/layout/ContentPane" data-dojo-props=" spanLabel : true ,
'class' : 'csrMessagePanel' ,
uId : 'customerMessagePanel'
" role='alert'>
<div data-dojo-type="idx/layout/ContentPane" data-dojo-props=" spanLabel : true ,
'class' : 'customerMessageBox' ,
uId : 'lb_customerMessageBox' ,
renderHidden : true
">
<div data-dojo-type="sc/plat/dojo/widgets/Image" data-dojo-props=" 'class' : 'customer-message' ,
uId : 'imgCustomer'
,scParamDataFn :
function() {
return {
title :this.getSimpleBundleString('CUST_ImageAlt')
,
imageAlt :this.getSimpleBundleString('CUST_ImageAlt')
}
}
"></div>
<div data-dojo-type="sc/plat/dojo/widgets/Link" data-dojo-props="imageStyleClass : 'idxMessageCloseIcon' ,
hasImage : true ,
'class' : 'idxMessageRightAligned' ,
uId : 'linkclose'
,scParamDataFn :
function() {
return {
title : this.getSimpleBundleString('CUST_closeAlt')
,
imageAlt : this.getSimpleBundleString('CUST_closeAlt')
}
}
"></div>
<div data-dojo-type="idx/layout/ContentPane" data-dojo-props=" 'class' : 'customerMessageText' ,
uId : 'pnlCustomerMessageText'
">
<div data-dojo-type="sc/plat/dojo/widgets/Label" data-dojo-props=" uId : 'messageDescriptionText'
"></div>
</div>
</div>
</div>
<div data-dojo-type="idx/layout/ContentPane" data-dojo-props=" spanLabel : true ,
uId : 'systemMessagePanel' ,
renderHidden : true
"></div>
<div data-dojo-type="idx/layout/ContentPane" data-dojo-props=" spanLabel : true ,
'class' : 'editorContent' ,
uId : 'editorContent'
" role='main'>
<div data-dojo-type="idx/layout/ContentPane" data-dojo-props=" spanLabel : true ,
uId : 'scScreenHolder'
" role='main'></div>
<!--The following div element is required to embed the Related Task screen -->
<div data-dojo-type="sc/plat/dojo/widgets/ControllerWidget" data-dojo-props="
uId: 'RelatedTaskScreenHolder',
packageName: 'wsc.editors',
className: 'HomeEditorRT',
handleInit: false,
'class': 'relatedTaskHolder',
dynamicLoading: true,
renderHidden: true,
scParamDataFn: function() {
return {
}
}">
</div>
<!--End of code to embed the Related Task screen -->
</div>
<div data-dojo-type="idx/layout/ContentPane" data-dojo-props=" spanLabel : true ,
resourceId : 'WSCFO0TER001' ,
'class' : 'footer' ,
uId : 'scFooterHolder'
" role='main'>
<div data-dojo-type="sc/plat/dojo/widgets/Link" data-dojo-props=" uId : 'siteMapLink'
,scParamDataFn :
function() {
return {
value : this.getSimpleBundleString('SiteMap')
}
}
"></div>
</div>
</div>According to the application standard, data-dojo-props contain
the scParamDataFn function attribute. This attribute
returns a JSON object with any dynamically evaluated values such as
label, title, or bindingData for the widget.
Embed the related tasks screen
- If the custom editor does not have a wizard, add the related tasks
screen in the editor by following these instructions:
- Set the value of
showRelatedTaskattribute totruefor the screen that is opened in the custom editor. For more information about theshowRelatedTaskattribute, see Sample MyOrderScreen.js file. - In the screen that is opened in the editor, add a subscriber to
the
afterScreenLoadevent. In the event handler, raise an event for the parent, which is the editor. In the corresponding event handler of the editor, which is based on the value ofshowRelatedTaskattribute, the Related Task screen is created dynamically by calling theshowOrHideRelatedTaskScreenmethod ofEditorRelatedTaskUtils. - In the Related Task screen, add a subscriber to the
afterParentScreenStartupevent. In the event handler, raise an event for the parent, which is the editor. In the corresponding event handler of the editor, show the related task by calling theshowRelatedTaskScreenHoldermethod ofEditorRelatedTaskUtils. Pass the editor instance as the argument. For example,isccseditorRelatedTaskUtils.showRelatedTaskScreenHolder(this).
For an application-provided editor, in the event handler of the
afterScreenLoadevent, raise theshowOrHideRelatedTaskevent from the screen that is opened in the editor. In the Related Task screen, raise theafterRTScreenStartupevent in the event handler of theafterParentScreenStartupevent. - Set the value of
- If the custom editor has a wizard, add the related tasks screen
in the editor as follows:
- Set the value of
showRelatedTaskInWizardattribute totruein the wizard. For more information about theshowRelatedTaskInWizardattribute, see Sample CustomWizard.js file. - In the wizard, add a subscriber to the
startevent. In the event handler, raise an event for the editor as shown in the following sample code.var eventDefn = null; eventDefn = _scBaseUtils.getNewBeanInstance(); _scEventUtils.fireEventToParent(this, "showOrHideRelatedTask", eventDefn); - In the corresponding event handler of the editor, which is based
on the value of
showRelatedTaskInWizardattribute, the Related Task screen is created dynamically by calling theshowOrHideRelatedTaskScreenmethod ofEditorRelatedTaskUtils. - In the Related Task screen, add a subscriber to the
afterParentScreenStartupevent. In the event handler, raise an event for the parent, which is the editor. In the corresponding event handler of the editor, show the related task by calling theshowRelatedTaskScreenHoldermethod ofEditorRelatedTaskUtils. Pass the editor instance as the argument. For example,isccseditorRelatedTaskUtils.showRelatedTaskScreenHolder(this).
For an application-provided editor, in the event handler of the
startevent, raise theshowOrHideRelatedTaskevent from the wizard that is opened in the editor. In the Related Task screen, raise theafterRTScreenStartupevent in the event handler of theafterParentScreenStartupevent. - Set the value of
The procedure to create related tasks screen is same as creating custom screen. Embed the related tasks screen in the corresponding editor HTML file.
After
you embed the related tasks screen, you can hide or unhide the related
tasks. To hide or unhide related tasks, in the custom screens add
a subscriber and handler for the afterScreenLoad event.
For example, in the custom screen, the updateEditorHeader event
handler contains the updateTitle method that enables
to hide or unhide related tasks.
Reuse an editor
To reuse an editor, select the appropriate editor from the<war_dir>/wsc/editors folder, and pass the comparison
attributes as input to the editor. For example, in the OrderEditorUI.js file,
the Order.OrderHeaderKey is the comparison attribute.
Pass OrderHeaderKey as input to the Order editor.
For more information about the comparison attribute, see Sample MyOrderEditor.js file.- Browse to
<INSTALL_DIR>/wsc/editors. - Open the appropriate BehaviorController.js file.
For example, to determine the list of mashups applicable for the Item
Search editor, open theItemSearchBehaviorController.js file.
All the mashups are present under the
mashupRefsobject.