Legacy platform

Create custom screens

A screen is a special Dojo container widget that is used in the application. It manages the interaction of data between the UI and mashup layer that contains both UI and behavior logic.

To create custom screens, the following JavaScript files must be present that contains the JavaScript screen definition.
  • <Screen name>.js - The JS file corresponding to your screen. You can define all your behavior logic in this file.
  • templates/<Screen name>.html - The HTML file that contains all the UI information.
  • <Screen name>BehaviorController.js - The JS file that contains the mashuprefs details that are called on some action or behavior on the screen.
  • <Screen name>InitController.js - The JS file that contains the mashuprefs details that are called when you open a screen.

In addition to JavaScript files, ensure that the <Screen name>BehaviorController.xml and <Screen name>InitController.xml Controller XML files are also present in the <INSTALL_DIR>/extensions/wsc/webpages/controller/default directory. For more information about creating the <Screen name>BehaviorController.js, <Screen name>InitController.js, <Screen name>BehaviorController.xml, and <Screen name>InitController.xml, see Customize controllers.

Create the <Screen name>.js file

Ensure that the <Screen name>.js file syntax adheres to Dojo version 1.8 standards. The custom screen must extend sc/plat/dojo/widgets/Screen. Additionally, you can use the following application-provided standards:

  • You can use scDefine instead of define.
  • You can precede the imported JavaScript modules with scbase/loader! string. The scbase/loader string is a Dojo loader plug-in that is provided by the application. Precede an html file path with a dojo/text! string according to the Dojo syntax.

Ensure to create all the custom screen files in the <INSTALL_DIR>/extensions/wsc/webpages folder. In WAR, as the files are present in the extn folder, prefix the package with extn.

Note: To create a child screen, use BehaviorController instead of InitController. To run mashups of BehaviorController, use the afterScreenInit event subscribers. To display data on the screen, call the setModel method for a screen.

Sample MyOrderScreen.js file

scDefine([
	"dojo/text!./templates/MyOrderScreen.html",
	"scbase/loader!dijit/form/Button",
	"scbase/loader!dojo/_base/declare",
	"scbase/loader!idx/form/TextBox",
	"scbase/loader!idx/layout/ContentPane",
	"scbase/loader!sc/plat/dojo/utils/BaseUtils",
	"scbase/loader!sc/plat/dojo/utils/EventUtils",
	"scbase/loader!sc/plat/dojo/widgets/Label",
	"scbase/loader!sc/plat/dojo/widgets/Link",
	"scbase/loader!sc/plat/dojo/widgets/Screen"
],
function(
	templateText,
	_dijitButton,
	_dojodeclare,
	_idxTextBox,
	_idxContentPane,
	_scBaseUtils,
	_scEventUtils,
	_scLabel,
	_scLink,
	_scScreen
) {
    return _dojodeclare("extn.customScreen.MyOrderScreen", [_scScreen], {
		templateString: templateText,
		uId: "customScreen",
		packageName: "extn.customScreen",
		className: "MyOrderScreen",
     showRelatedTask: true,
		namespaces: {
			targetBindingNamespaces: [{
				description: 'The input to the getOrderList mashup.',
				value: 'getOrderList'
			}],
			sourceBindingNamespaces: [{
				description: 'Initial input to screen',
				value: 'screenInput'
			}, {
				description: 'The list of organizations the current user can search for orders with.',
				value: 'getOrganizationList_output'
			}, {
				description: 'The response from the getOrderList mashup',
				value: 'getOrderList_output'
			}]
		},
		staticBindings: [{
            targetBinding: {
                path: 'Order.ApplyQueryTimeout',
                namespace: 'getOrderList'
            },
            sourceBinding: {
                sourceValue: 'Y',
                path: 'Order.ApplyQueryTimeout'
            }
        }],
		events: [{
			name: 'onPopupConfirm'
		}, {
			name: 'openOrderListPage'
		}],
		subscribers: {
			local: [{
				eventId: 'saveCurrentPage',
				sequence: '25',
				handler: {
					methodName: "save"
				}
			}, {
                eventId: 'afterScreenLoad',
                sequence: '25',
                handler: {
                    methodName: "updateEditorHeader"
                }
            },
			{
				eventId: 'bFindOrder_onClick',
				sequence: '30',
				description: '',
				handler: {
					methodName: "orderSearchAction",
					description: ""
				}
			}],
		},
		
		save: function() {
			var eventDefinition = null;
			_scEventUtils.fireEventToParent(this, "onSaveSuccess", eventDefinition);
		},

	 updateEditorHeader: function(
        event, bEvent, ctrl, args) {
            _iasBaseTemplateUtils.updateCustomerMessage(
            this, "CUST_ItemBrowsing", true);
            _iasBaseTemplateUtils.updateTitle(
            this, "blank", null);
            _scScreenUtils.focusFirstEditableWidget(
            this);
            return true;
        },

		orderSearchAction: function(event, bEvent, ctrl, args) {
			this.orderSearch();
		},
		orderSearch: function() {
			var root = null;
			root = _scBaseUtils.getTargetModel(this, "getOrderList", null);
			var eventDefinition = null;
			_scEventUtils.fireEventToParent(this, "openOrderListPage", eventDefinition);
		}
	});
});
The ignoreStaticBindings method is defined in the ScreenUtils.js file. It can be called before getTargetModel in any screen, if you do not want to display data from some static bindings. For example, this method can be invoked from afterScreenInit event inside any screen that allows address capture.
ignoreStaticBindingsForAddressCapture:function(){
			var ignoreList = [{
				sourceBinding: {
					path: 'PersonInfo.AddressLine3',
					namespace: 'screenInput'
				},
n				targetBinding: {
					path: 'PersonInfo.AddressLine3',
					namespace: 'verifyAddress_input'
				}
			}];
			scScreenUtils.ignoreStaticBindings(this,ignoreList)
		}
This method ignores the static bindings for the AddressLine3 field.

The following table describes some important attributes of a screen.

Table 1. Screen Attributes
Screen attributes Description
templateString Mandatory. The html template file path that contributes the UI for the screen.
uId Mandatory. The unique identifier for the screen.
packageName Mandatory. Package name of the screen.
className Mandatory. Class name of the screen.
namespaces The object that contains all the source and target namespaces used on the screen. This attribute is mandatory, if you use namespaces on the screen.
staticBindings The object that lists all the source and target static binding namespaces and paths that are used on the screen. This attribute is mandatory, if you use static bindings on the screen.
events List of events that are published by the screen. This attribute is mandatory, if the screen publishes some events.
subscribers List of global and local events to which the screen listens to. This attribute is mandatory, if the screen listens to any events.

Create the templates/<Screen name>.html file

The templates/<Screen name>.html file renders the UI for a screen. It contains all the widgets present in the screen and adheres to Dojo 1.8 syntax. It is used for creating widgets declaratively by using an HTML file.

Ensure to create the screen HTML file under the templates folder relative to the custom screen JS file.

Sample MyOrderScreen.html file

<div class="sc-platform-screen-default myorderscreen">
	<div data-dojo-type="idx/layout/ContentPane" data-dojo-props="
		spanLabel: true,
		resourceId: 'WSCORD0001',
		'class': 'wscScreen portlet',
		colspan: 1,
		uId: 'portletPanel',
		layoutAlign: 'top',
		scParamDataFn: function() {
			return {
				'aria-label': this.getSimpleBundleString('Order')
			}
		}
	" role="region">
		<div data-dojo-type="idx/layout/ContentPane" data-dojo-props="
			spanLabel: true ,
			'class': 'contentSeparator portletHeader',
			uId: 'portletHeaderPanel'  
		">
			<div data-dojo-type="sc/plat/dojo/widgets/Label" data-dojo-props="
				'class': 'primaryInformation',
				uId: 'portletName',
				scParamDataFn: function() {
					return {
						value: this.getSimpleBundleString('Order')
					}
				}
			" role='heading'></div>
		</div>
		<div data-dojo-type="idx/layout/ContentPane" data-dojo-props="
			spanLabel: true,
			'class': 'PortletContent singlecolumntable',
			uId: 'findOrderPanel'
		">
			<div data-dojo-type="idx/form/TextBox" data-dojo-props="
				uId: 'txtOrderNo',
				scParamDataFn: function() {
					return {
						bindingData: {
							targetBinding: [{
								path: 'Order.OrderNo',
								namespace: 'getOrderList'
							}],
							sourceBinding: {
								path: 'Order.OrderNo',
								namespace: 'screenInput'
							}
						},
						label: this.getBundleString('OrderNo')
					}
				}
			"></div>
			<div data-dojo-type="idx/layout/ContentPane" data-dojo-props="
				'class': 'portletSearchBar',
				uId: 'pnlSearchBar'
			">
				<div data-dojo-type="dijit/form/Button" data-dojo-props="
					spanLabel: true,
					resourceId: 'WSCORD0001',
					showLabel: true,
					uId: 'bFindOrder',
					scParamDataFn: function() {
						return {
							label: this.getSimpleBundleString('FindOrder')
						}
					}
				"></div>
                <div data-dojo-type="sc/plat/dojo/widgets/Link" data-dojo-props="
					spanLabel: true,
					resourceId: 'WSCRTORD0001',
					'class': 'createLink',
					uId: 'bCreate',
					scParamDataFn: function() {
						return {
							value: this.getSimpleBundleString('CreateOrder')
						}
					}
				"></div>
            </div>
		</div>
	</div>
</div>
Note:
  • You can use any other Dojo supported widgets in the screen. However, binding and application-provided event framework is not supported for these widgets.
  • If a screen variable is an array, it does not reinitialize on reinitialization of a screen. Therefore, if you want to reinitialize the variable, it can be done afterScreenInit event by reinitialization of the array or emptying the array.

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.

As the following widgets are used in the application, it supports bindings and application-provided event framework:

Editable widgets

  • idx.form.CheckBox
  • idx.form.CheckBoxList
  • idx.form.DateTextBox
  • idx.form.FilteringSelect
  • idx.form.NumberTextBox
  • idx.form.RadioButtonSet
  • idx.form.Textarea
  • idx.form.TextBox
  • idx.form.CurrencyTextBox
Note: In the mobile version of the application, you cannot add editable widgets to list panels such as the "My Tasks in Progress" panel on the Home page and the panels within. However, as part of customization, if you want to add editable widgets to a panel, then you must stop the application-provided subscriber for the onClick event of the panel. For more information about stopping the application-provided subscriber for an event, see Events and subscribers.

Non-editable widgets

  • dijit.form.Button
  • sc.plat.dojo.widgets.DataLabel
  • dijit.form.TextBox (use as a hidden widget)
  • sc.plat.dojo.widgets.Image
  • sc.plat.dojo.widgets.Link
  • sc.plat.dojo.widgets.Label

Containers

  • idx.layout.ContentPane
  • idx.layout.MoveableTabContainer
  • idx.layout.TitlePane

Special widgets

  • sc.plat.dojo.widgets.Screen - the base screen widget
  • sc.plat.dojo.widgets.ControllerWidget - used to hold screens within a screen
  • sc.plat.dojo.widgets.IdentifierControllerWidget - used to hold screens within a screen
  • gridx.Grid - grid
  • sc.plat.dojo.widgets.IdentifierScreen - used for Address panels
  • sc.plat.dojo.widgets.IFrame - IFrame widget
  • sc.plat.dojo.widgets.Editor - Editor widget
  • sc.plat.dojo.widgets.Wizard - wizard
For custom screens, the following events are raised by a wizard:
  • saveCurrentPage - This event is raised to save any unsaved data on the current wizard page.
  • reloadScreen - This event is raised on click of Previous to reload the previous page in the wizard.
  • handleTabClose - This event is raised when an editor is closed. Before closing the wizard, a warning message is displayed prompting the user to save any unsaved data on the page. Ensure to define the handleTabClose event subscriber for new wizards, so that the user is prompted to save data on closing the editor.

Embed the related tasks screen

You can embed the related tasks screen in any of the following ways:
  • 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 showRelatedTask attribute to true for the screen that is opened in the custom editor. For more information about the showRelatedTask attribute, see Sample MyOrderScreen.js file.
    • In the screen that is opened in the editor, add a subscriber to the afterScreenLoad event. 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 of showRelatedTask attribute, the Related Task screen is created dynamically by calling the showOrHideRelatedTaskScreen method of EditorRelatedTaskUtils.
    • In the Related Task screen, add a subscriber to the afterParentScreenStartup event. 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 the showRelatedTaskScreenHolder method of EditorRelatedTaskUtils. Pass the editor instance as the argument. For example, iaseditorRelatedTaskUtils.showRelatedTaskScreenHolder(this).

    For an application-provided editor, in the event handler of the afterScreenLoad event, raise the showOrHideRelatedTask event from the screen that is opened in the editor. In the Related Task screen, raise the afterRTScreenStartup event in the event handler of the afterParentScreenStartup event.

  • If the custom editor has a wizard, add the related tasks screen in the editor as follows:
    • Set the value of showRelatedTaskInWizard attribute to true in the wizard. For more information about the showRelatedTaskInWizard attribute, see Sample CustomWizard.js file.
    • In the wizard, add a subscriber to the start event. 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 showRelatedTaskInWizard attribute, the Related Task screen is created dynamically by calling the showOrHideRelatedTaskScreen method of EditorRelatedTaskUtils.
    • In the Related Task screen, add a subscriber to the afterParentScreenStartup event. 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 the showRelatedTaskScreenHolder method of EditorRelatedTaskUtils. Pass the editor instance as the argument. For example, iaseditorRelatedTaskUtils.showRelatedTaskScreenHolder(this).

    For an application-provided editor, in the event handler of the start event, raise the showOrHideRelatedTask event from the wizard that is opened in the editor. In the Related Task screen, raise the afterRTScreenStartup event in the event handler of the afterParentScreenStartup event.

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.

Add and view the customized screen in the application

You can add and view the customized screen in the application either in an editor, wizard, pop-up window, and others. Usually, utilities that are used to add and view the customized screens are ControllerUtils, BaseUtils, and WizardUtils. For example, to open screens in an editor use the methods that are provided in ControllerUtils. To open wizards in an editor, use WizardUtils, and to open a screen in pop-up window, use BaseUtils. The most commonly used methods are openScreenInEditor, openWizardInEditor, continueOpeningInEditor, and UIUtils.openSimplePopup. For more information about using other methods, see the JavaScript documentation.

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.
To determine the list of mashup calls present in an existing editor, do the following steps:
  1. Browse to <INSTALL_DIR>/WSC/editors.
  2. 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 mashupRefs object.