> For the complete documentation index, see [llms.txt](https://docs.prebilt.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.prebilt.com/prebilt-for-im-wm-strm/enhancing-prebilt/making-changes-to-the-frontend-javascript-ui5.md).

# Making changes to the Frontend (Javascript/UI5)

## Naming conventions &#x20;

When creating the apps there are many naming conventions for the different elements within the code, in the following sections the main elements will be covered where XXXX is the page number. Where possible, the naming conventions should follow the following logic.

### Apps

The PreBilt apps are all assigned a catalogue number when they are created which is used in the naming conventions of many pages, classes, configuration etc. The range 100-800 is saved for TCT library applications and the 900-999 range is for custom applications.

### Functions&#x20;

The functions in the apps have naming conventions for those functions that are standard to the apps.

### Page initialisation functions&#x20;

When calling the setupListPage or setupDetail functions to create the page, we put this inside an initialise function which can also include any other functionality that is to be executed on the setup of the page. The naming for this is initialiseXXXX e.g.&#x20;

`oCtrl.initialise1000 = function () {`&#x20;

### Action functions&#x20;

When setting the action callback function from within functions such as the setupDetailPage function, these are created with the name actionCBXXXX  e.g.&#x20;

`actionCB: function actionCB1000(act, butId) {`&#x20;

Within this function multiple actions are created and given return functions which are created with the name actButtonXXXX, where ‘Button’ would be replaced with the type of button e.g.&#x20;

`return function actBack1000(oEvent) {`&#x20;

It should be noted that these functions do not require a named function for them to work, but it is done this way so that when an error occurs, we can see them in the failed call stack. That way we can see if the failure is in one of these functions or if the code has run these functions which is highly beneficial when debugging the apps and saves time searching for where the issue is.&#x20;

### Additional page functions

When setting up the pages within the app, there are standard functions that should also be added. For example, on a selection screen there will usually be a ‘Select’ button. The press event for this action should be named selectXXXX, e.g.&#x20;

`oCtrl.select1000 = function () {`&#x20;

Similarly List Pages will usually have a press event for the list items. The naming convention for this is onSelectXXX e.g.&#x20;

`oCtrl.onSelect2000 = function (oEvent) {`&#x20;

With list screens there will be a search field to allow users to search the lists, the functionality behind this search bar should be in a function called onSearchXXX e.g.&#x20;

`oCtrl.onSearch2000 = function (oEvent) {`&#x20;

### AJAX calls&#x20;

The functions used to call the methods in SAP should be in individual functions called ajaxMethodName e.g.&#x20;

`oCtrl.ajaxGetSetup = function () {`&#x20;

Within this function a success callback function is referenced. These success callback functions should have the name methodNameSuccess e.g.,

```
successCB: function (data) { 
gc().getSetupSuccess(data); 
} 
```

### Additional Functions&#x20;

Another function that is common among the apps is the function where a call to open another app is made. This function will be called callAppName e.g.&#x20;

`oCtrl.callDocCapture = function (p) {`&#x20;

### Variables&#x20;

As the apps have different functionality there aren’t variables that are always common and so there aren’t many standard naming conventions for these, however the variables should be names that are short and meaningful and if they are specific to one page then the page number can be included.

### Models

Models are used in all the apps and so have common naming conventions for them. All models start with ‘model’ at the start of the name. For page models the naming convention is modeloPageXXX e.g.&#x20;

gc().modeloPage0100 = new sap.ui.model.json.JSONModel();&#x20;

For models that will hold response data from the calls to SAP they have the naming convention modeloMethodNameResp e.g.&#x20;

`gc().modeloGetSetupResp = new sap.ui.model.json.JSONModel();`&#x20;

Some other standard models throughout the apps include: &#x20;

`gc().modelTCode = new sap.ui.model.json.JSONModel();`&#x20;

`gc().modelTexts = new sap.ui.model.json.JSONModel();`&#x20;

`gc().modelPostData = new sap.ui.model.json.JSONModel();`&#x20;

`gc().modelRespData = new sap.ui.model.json.JSONModel();`&#x20;

### Object IDs&#x20;

In the App\_XXX.view\.js many objects are created to be used for the page setup, these are referenced to using the IDs that have been set for them.

### Pages

For the sap.m.Page that is created for each page in the app the naming should be oPageXXX e.g.,

```
var oPage0100 = new sap.m.Page(this.createId("oPage0100"), { 
visible: false 
});
```

Other objects on the page include the header; headerXXX e.g.,

```
var header0100 = new sap.m.Bar(this.createId("header0100")); 
The text objects for the headers back button, txtAppXXX e.g. 
var txtApp0100 = new sap.m.Text(this.createId("txtApp0100"), { 
text: "%TEXT-001%" 
}); 
```

The text object for the page Title, txtTitleXXX e.g.,

```
var txtTitle0100 = new sap.m.Text(this.createId("txtTitle0100"), { 
text: "%TEXT-100%" 
});
```

The panel that holds the content on the page, oPanelXXX e.g.,

```
var oPanel0100 = new sap.m.Panel(this.createId("oPanel0100"), { 
backgroundDesign: "Solid" 
})
```

The panel that displays the list on a list screen, oPanelXXXX\_List e.g.,

```
var oPanel3000_List = new sap.m.Panel(this.createId("oPanel3000_List"), { 
backgroundDesign: "Solid" 
});
```

The search file on list screens, oSearchFieldXXx e.g.,

```
var oSearchField3000 = new sap.m.SearchField(this.createId("oSearchField3000"), { 
placeholder: "%TEXT-302%", 
showSearchButton: false, 
liveChange: gc().onSearch3000 
});
```

The list on a list screen, oItemsListXXX e.g.,

```
var oItemsListItem3000 = new sap.m.CustomListItem(this.createId("oItemsListItem3000"), { 
type: "Navigation", 
press: gc().onSelect3000 
}); 
```

The list item on a list screen, oItemsListItemXXX e.g.,

```
var oItemsListItem3000 = new sap.m.CustomListItem(this.createId("oItemsListItem3000"), { 
type: "Navigation", 
press: gc().onSelect3000 
}); 
```

The footer of the page, footerXXX e.g.,

```
var footer0100 = new sap.m.Bar(this.createId("footer0100"));
```

## Custom Shorthand functions&#x20;

### Go

‘go’ is used to get the object by it’s ID. When creating objects in the app’s view file, the objects should be given an ID with a relevant name so that they can easily be referred to in the controller. The shorthand function is defined in the onInit function:

```
go = function (id) {  
return oThis.byId(id); 
}; 
```

The function is then used in the controller in other functions e.g.,

```
go("oShell").addStyleClass(data.tcode);
```

where ‘oShell’ is the object’s ID.&#x20;

### Gc

‘gc’ is used to get the controller and is defined in the onInit function in the controller:&#x20;

```
gc = function () {  
return oThis; 
};
```

&#x20;To create functions in the controller we store the functions in the oCtrl class object that has been defined:&#x20;

```
oCtrl.select1000 = function () { 
// function code here 
}
```

Then we can call these functions using our shorthand function: &#x20;

```
gc().setupPage(p);
```

We can also use this to store/retrieve global variables:&#x20;

```
gc().setModelPostData({ 
"IM_WM": gc().selectedIM_WM, 
"LQNUM": gc().selectedKey 
}); 
```

### Gm

‘gm’ is used to get the model and is defined in the onInit function in the controller:&#x20;

```
gm = function (id) {  
return oThis["model" + id]; 
}; 
```

&#x20;To create models in the controller we store them in the oCtrl class object that has been defined:&#x20;

```
let oCtrl = { 
... 
modelPostData: new sap.ui.model.json.JSONModel(), 
... 
}; 
```

Then we can call these functions using our shorthand function: &#x20;

```
gm("PostData").getData()
```

### Folder structure in TCTM\_WM\_UI <a href="#toc214462454" id="toc214462454"></a>

The following table details the folder structure for each PreBilt™ app and a description of the files where XXX is the app number for releases prior to 5.8.

<table data-header-hidden><thead><tr><th width="187" valign="top"></th><th valign="top"></th><th></th><th></th></tr></thead><tbody><tr><td valign="top">File/Folder name </td><td valign="top"> </td><td></td><td>Description of file </td></tr><tr><td valign="top">TCTM_WM_UI </td><td valign="top">apps </td><td>tctm_wm_app_XXX </td><td>This folder is an example folder, ach of the apps within PreBilt™ will have its own folder structure. See section below. </td></tr><tr><td valign="top">controller </td><td valign="top">App_Base.controller.js </td><td>This file is the main controller for the menu, the menu is an app and this file contains the functionality for this app. </td><td></td></tr><tr><td valign="top">css </td><td valign="top">App_Base.css </td><td>This file contains all the specific CSS styling for the base app. </td><td></td></tr><tr><td valign="top">fundamental-styles.css </td><td valign="top">This file contains all the standard SAP fundamental library styles to be used in the PreBIlt™ apps. </td><td></td><td></td></tr><tr><td valign="top">tctm_global.css </td><td valign="top">This file contains all the global styles that are shared across all the apps. </td><td></td><td></td></tr><tr><td valign="top">extensions </td><td valign="top">App_Base.extensions.css </td><td>This extensions file allows for the CSS of the base app to be extended. </td><td></td></tr><tr><td valign="top">App_base.extensions.js </td><td valign="top">This extensions file allows for the base app functionality to be extended. </td><td></td><td></td></tr><tr><td valign="top">tctm_extensions.js </td><td valign="top">This file allows for the global tctm functionality to be extended. </td><td></td><td></td></tr><tr><td valign="top">fontawesome </td><td valign="top">... </td><td>Fontawesome library to be used across the PreBilt™ apps. </td><td></td></tr><tr><td valign="top">js </td><td valign="top">signature_pad.min.js </td><td>Signature pad js library to allow us to use signature pad functionality with the PreBilt™ apps. Used in app 602. </td><td></td></tr><tr><td valign="top">tctm_apps.js </td><td valign="top">This file defines anything in the sap.tctm.apps namespace and defines specific functionality for the apps, this is not needed for all platforms. See more information in the Methods(tctm_apps.js) section. </td><td></td><td></td></tr><tr><td valign="top">tctm_core.js </td><td valign="top">This file contains the global functionality that can be accessed by all the PreBilt apps. See more information in the Methods(tctm_core.js) section.  </td><td></td><td></td></tr><tr><td valign="top">tctm_settings.js </td><td valign="top">This file contains the global settings to control the main execution of the app. </td><td></td><td></td></tr><tr><td valign="top">ui5_std.js </td><td valign="top">This file contains standard SAPUI5 functionality. </td><td></td><td></td></tr><tr><td valign="top">sapui5 </td><td valign="top">... </td><td>The standard SAPUI5 folder. </td><td></td></tr><tr><td valign="top">view </td><td valign="top">App_Base.view.js </td><td>The view for the base app containing the objects to be used such as the sap.m.Shell and sap.m.App etc.  </td><td></td></tr><tr><td valign="top">.gitignore </td><td valign="top"> </td><td>The git ignore file, only needed when using this project linked to gitlab. </td><td></td></tr><tr><td valign="top">getting_statred.md </td><td valign="top"> </td><td>Read me file, only needed when using this project linked to gitlab. </td><td></td></tr><tr><td valign="top">index.html </td><td valign="top"> </td><td>HTML file needed to link to add stylesheets, apply onLoad settings, add the body information for the SAPUI5 application etc. </td><td></td></tr><tr><td valign="top">README.md </td><td valign="top"> </td><td>Read me file, only needed when using this project linked to gitlab. </td><td></td></tr></tbody></table>

### Folder structure of tctm\_wm\_app\_XXX&#x20;

The following table details the folder structure for each PreBilt™ app and a description of the files where XXX is the app number.

<table data-header-hidden><thead><tr><th valign="top"></th><th valign="top"></th><th></th><th></th></tr></thead><tbody><tr><td valign="top">File/Folder name </td><td valign="top"></td><td></td><td>Description </td></tr><tr><td valign="top">tctm_wm_app_XXX </td><td valign="top">controller </td><td>App_XXX.controller.js </td><td>This file is the main controller for app XXX, this file contains the functionality for this app. </td></tr><tr><td valign="top"> </td><td valign="top">css </td><td>App_XXX.css </td><td>This file contains all the specific CSS styling for app XXX. </td></tr><tr><td valign="top"> </td><td valign="top">extensions </td><td>App_XXX.extensions.css </td><td>This extensions file allows for the CSS of app XXX to be extended. </td></tr><tr><td valign="top"> </td><td valign="top">App_XXX.extensions.js </td><td>This extensions file allows for app XXX’s functionality to be extended. </td><td></td></tr><tr><td valign="top"> </td><td valign="top">view </td><td>App_XXX.view.js </td><td>The view for app XXX containing the objects to be used such as the sap.m.Shell and sap.m.App etc. </td></tr></tbody></table>

## File structures&#x20;

This section will detail the general structures for the files within each app. Each file includes regions that separate out the different sections of code, more details can be found in the section ‘Comments’.

### Controller&#x20;

The structure of the controller file for each app usually has the following order to the sections. Sections will be commented with the section name and there will also be regions for each sub section:&#x20;

* Global Data&#x20;
* Initialisation&#x20;
* Global Functions&#x20;
* Pages – This will contain regions such as oPage1000, oPage2000 etc.&#x20;
* AJAX Calls - This will contain regions such as ajaxGetSetup&#x20;
* Additional Functions - This will contain regions such   as callDocCapture&#x20;
* Extensions &#x20;

### View&#x20;

The structure of the view file for each app usually has the following order to the sections. Sections will be commented with the section name and there will also be regions for each sub section:&#x20;

* Overview Details&#x20;
* Shell&#x20;
* App&#x20;
* Pages - This will contain regions such as oPage1000, oPage2000 etc.&#x20;
* Page Hidden&#x20;
* Extensions&#x20;

### CSS

Each app has its own CSS file however, this rarely contains too much styling as this is mostly controlled by the global styling or the styling sent from the backend based on the values in config. Therefore, the structure of this file should just be grouped logically.

&#x20;

## JS files&#x20;

### tctm\_apps.js

This file defines everything within the sap.tctm.apps namespace. The contents of this file may vary between platforms as some platforms have their own versions of the following methods, however the actual functionality remains the same between the different platforms. For example Neptune does not have a ‘tctm\_apps.js’ file and TCT does not explicitly define code within all of the following functions as the platform itself already has some of these functions defined.

### App\_Base.controller.js

The contents of this file may vary between platforms as some platforms have their own versions of the following methods, however the actual functionality remains the same between the different platforms. For example Neptune does not have a ‘App\_Base.controller.js’ file and TCT does not explicitly define code within all of the following functions as the platform itself already has some of these functions defined. Each app will also have many of these functions defined, unless the platform already defines them.&#x20;

&#x20;The functions in this file, and in the individual app controllers, are defined using ‘oCtrl’ e.g.,

```
oCtrl.attachInit = function () { 
// function code 
} 
```

In some of the functions the platform is checked where it requires custom processing e.g.,

```
if (sap.tctm.core.platform === "Movilizer") { 
movilizer.triggerBackEvent(); 
} 
if (sap.tctm.core.platform === "Neptune") { 
sap.n.Shell.closeTile(sap.n.Launchpad.currentTile); 
} 
```

Although the code is different, the functionality is the same. In this case both sections of code are closing the PreBilt application, however the different platforms do this in different ways.

### tctm\_core.js&#x20;

The following sections detail the functions that are globally available in the PreBilt ™ apps. The following functions can be accessed in the apps by calling sap.tctm.core.function\_name(p) e.g. sap.tctm.core.setupDetailPage(p).&#x20;

All functions take a single JSON object containing the parameters, allowing for the functions parameters to be easily extended in the future.&#x20;

For example, when calling a function which has a single JSON object as a parameter:&#x20;

```
let page_data = sap.tctm.core.setupDetailPage({ 
             tCode: gm("TCode").getData(), 
             page: go("oPage7000"), 
             panel: go("oPanel7000"), 
             data: gm("oPage7000").getData().BASKET_INPUT, 
             pageData: gm("oPage7000").getData(), 
             header: go("header7000"), 
             footer: go("footer7000"), 
             actionCB: function actionCB7000(act, butId) { 
                            //actions go here 
             } 
});   
```

### tctm\_settings.js

Within this file we can define the settings to control the main execution of the app. tctm\_settings\_templ.js is a base template that holds the parameters we use such as:

<figure><img src="https://3149936122-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2CkvzIq48sLzTY4bfcWl%2Fuploads%2FGTwSXFKkSSAFyzzFEKWz%2Fimage.png?alt=media&amp;token=b9faf49e-ad08-4de7-bae0-8581af614cf6" alt=""><figcaption></figcaption></figure>

We can use the template file to setup tctm\_settings.js and define parameters such as platform, SAPUI5 settings, the system, client and path information as well as the base transaction code and languages amongst others.

## Extensions&#x20;

Extensions are made available in all PreBilt applications to allow for code to be enhanced and functionality to be extended when customers require custom processing in the apps.&#x20;

The reason for doing this in extensions rather than directly changing the code in the apps is to allow for customers to upgrade to newer releases in the future without the custom code being overwritten. To upgrade to newer versions of apps, the code can be cloned from the PreBilt app library and then deployed into their system and then the code in the extensions will not be replaced but can be tweaked to work with these new versions of the apps rather than requiring the custom code to be redeveloped.&#x20;

### Extension examples&#x20;

There are standard extension points within the apps, however it is possible to overwrite any of the functions in the apps using the zRenderApp extension.&#x20;

It is also possible to create new functions in the extensions by extending the controller&#x20;

The standard layout of the extensions file would look something like this:&#x20;

The start of the file defines the necessary variables needed for the extensions to work and to be able to use the shorthand functions like in the app controller. (See more in the section ‘Custom Shorthand Functions’).&#x20;

```
sap.ui.define([], function () { 
"use strict"; 
var go; 
var gc; 
var gm; 
var gmz; 
return { 
zRenderApp: function (p) { // Start of zRenderApp 
// Store Controller context 
var oThis = this; 
go = function (id) { // Get Object 
return oThis.byId(id); 
} 
gc = function () { // Get Controller 
return oThis; 
} 
gm = function (id) { // Get Model 
return oThis["model" + id]; 
} 
gmz = function (id) { // Get Model from Z 
return oThis.z["model" + id]; 
} 

```

The next part of the file then allows for new functions to be added, rather than change existing ones. Any functions created here must be referenced gc().z.newFunction, we add this so that we can ensure the function will not be overwritten in the future by any new standard functionality that may have the same naming.

```
// Extend Controller 
gc().z = { 
moveStockDialog: undefined, 
modeloGetSlocsResp: new sap.ui.model.json.JSONModel(), 
modeloMoveStockResp: new sap.ui.model.json.JSONModel(), 
ajaxGetSlocs: function () { 
sap.tctm.core.postAJAX({ 
tCode: gm("TCode").getData().tcode, 
method: "GET_SLOCS", 
postData: gm("PostData").getData(), 
successCB: function (data) { 
gc().z.getSlocsSuccess(data); 
}, 
errorCB: function (result) { 
sap.tctm.core.handleAjaxError({ 
tCode: gm("TCode").getData(), 
result: result, 
control: go("oApp") 
}); 
} 
}); 
}, 
} //End of controller extension 

```

As you can see in the above example a new function ajaxGetSlocs has been created, this function also calls `gc().z.getSlocsSuccess(data)` which would also need to be defined in this extension of the controller.&#x20;

Next in the file you can add in any functions to overwritten/extended. Note: this is still inside the zRenderApp and is part of this extension. &#x20;

```
gc().addZebraFormatting = function (zebraColor) { 
if (zebraColor !== "") { 
sap.tctm.core._addCSSClass("div[data-ul-key~='IM-			LIST'] 	li:nth-child(odd)", '{ background-color: ' 			+ zebraColor 	+ '; }'); 
} 
} 
}, // End of zRenderApp 

```

This function above will overwrite any of the functionality in `addZebraFormatting()` function in the app controller.&#x20;

Then in the rest of the file you can add the other extension functionality e.g. the zProcessCustomScreenAction extension which allows you to add custom actions to the page without overwriting the whole initialiseXXX function:&#x20;

```
zProcessCustomScreenAction: function (p) { 
let pageNo = p.page.getId().split("--")[1]; 
if (pageNo === "oPage3000" && p.action.ACTION === 	"MOVE_STOCK") { 
// Return function to handle IM Move Stock 
return function (oEvent) { 
sap.tctm.core.setBusy({ control: go("oApp"), busy: 			true }); 
gc().z.ajaxGetSlocs(); 
} 
} 
}, //End of zProcessCustomScreenAction 

```

## BSP application – transferring FE code changes to SAP

We make code changes in VScode as it is the preferred development environment and allows easier access to GitLab. However, any changes to the frontend aren’t live until they have been updated into the SAP system.

If we are using a PSE client, we can skip this step as the Frontend files will be built into the APK.

In the Object Navigator (transaction *SE80*) click the drop-down menu and select BSP Application, then enter ZTCTM\_WM\_UI. This is where our Frontend code is being stored in the SAP system and when we access PreBilt using a URL this is the frontend being used.

Within ZTCTM\_WM\_UI there are 3 subfolders

<figure><img src="https://3149936122-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2CkvzIq48sLzTY4bfcWl%2Fuploads%2FqZdK3d55xMv2mQSDRlgJ%2Fimage.png?alt=media&amp;token=f787bf4c-6e39-45b0-a219-5646a0295783" alt=""><figcaption></figcaption></figure>

* Pages with Flow Logic holds our index.html file which rarely needs to be edited.
* Page Fragments holds our main code files which have the same file structure as before.
* MIMEs hold other libraries we use such as fontawesome and the SAP UI5 folder.

We can than access PreBilt directly from a URL, rather than hosting it locally.
