Custom.js File

The first time you generate the Mobile Workflow package files, the Custom.js file is generated.

In subsequent file generations for the same Mobile Workflow package, this file will not be overwritten, so any customizations you make are preserved.

These touch points are available for customization: WorkflowLoad, Submit, NavigateForward, NavigateBackward, ShowScreen, MenuItemClick, and Save. At each touch point, a custom Before method is invoked and a customAfter method is invoked. The Before method returns a boolean. If it returns true, it continues to execute the default behaviour, for example, navigating to a new screen or performing an online request. If it returns false, it does not execute the default behavior, so you can override the default behavior by customizing these methods.

The Custom.js file contains these methods:
Method Description
customBeforeWorkflowLoad() Invoked when the application is first launched, before any data is loaded, or screens are opened.

Because workflow settings are not yet initialized at this point, you cannot call any SharedStorage functions here.

customAfterWorkflowLoad() Invoked when the application is first launched, after data is loaded and screens are opened.
customBeforeSubmit(screenKey, requestAction, workflowMessageToSend) Invoked before an operation or object query is about to be called as the result of the user clicking a Submit menuitem.

You can set this to return false to prevent the default behaviour from occurring.

customAfterSubmit(screenKey, requestAction) Invoked after an operation or object query is called as the result of the user clicking a Submit menuitem.
customBeforeNavigateForward(screenKey, destScreenKey) Invoked when another screen is about to be opened. Set to false to prevent the screen from being opened.
customBeforeNavigateBackward(screenKey, isCancelled) Invoked when another screen is about to be opened.

You can set to false to prevent the screen from being opened.

customAfterNavigateForward(screenKey, destScreenKey) Invoked after another screen has been opened.
customAfterNavigateBackward(screenKey, isCancelled) Invoked after a screen has been closed.
customBeforeShowScreen(screenToShow, screenToHide) Invoked when a screen is about to be shown.

User can return false to prevent the screen from being shown.

customAfterShowScreen(screenToShow, screenToHide) Invoked after a screen is shown.
customValidateScreen(screenKey, values) Invoked when the contents of a screen need to be validated.

User can return false to indicate that the contents of the screen are not valid.

customBeforeMenuItemClick(screen, menuItem) Invoked after a menuitem has been clicked. User can return false to prevent the default behavior (which might open a new screen, or perform a submit, and so on) from occurring.
customAfterMenuItemClick(screen, menuItem) Invoked after a menuitem has been clicked and the default behavior has occurred.
customBeforeSave(screen) Invoked before a screen’s contents are persisted to the Mobile Workflow message.

User can return false to prevent the default behaviour from occurring.

customAfterSave(screen) Invoked after a screen’s contents are persisted to the Mobile Workflow message through the default logic.
customConditionalNavigation(currentScreenKey, actionName, defaultNextScreen, conditionName, workflowMessage)

For online request menu items and custom actions, this method is invoked to evaluate the given condition after a given action is executed. If the screen associated with the condition should be navigated to, the condition is true.

For server-initiated starting points, the judgement condition is if((currentScreenKey === SERVERINITIATEDFLAG).

This method is different from the others in two of its attributes:
  • It returns true or false – the custom code used to implement this method can peer into the workflow message and execute logic. This routine generally does not modify the HTML or anything else.
  • There is no before or after behavior – this function is executed after the workflow message is received from the server, but before the screen is opened. Therefore, this is executed before the "customBeforeShowScreen()" because this function is used to help decide what screen to show next.

Conditions set by the user in the designer are executed serially, and the first one that returns true determines what the start screen is. As soon as a true condition is found, evaluation stops and the screen is executed.

customBeforeReportErrorFromNative(errorString) Invoked when a native error is reported on. Return false to prevent the default behavior from executing (bringing up an alert dialog)
customAfterReportErrorFromNative(errorString) Invoked after a native error is reported.
customAfterDataReceived(incomingWorkflowMessage) Invoked after data is received from the server. This allows you to view and manipulate the data.
customGetPictureURIFromCamera() Use this method to get a picture URI from the camera for submission to the workflow message.
customGetPictureURIFromLibrary() Use this method to get a picture URI from the photo library for submission to the workflow message.
customGetPictureURISuccess(fileName, imageURI) Handles success from one of the URI calls.
customGetPictureDataFromCamera() Use this method to get picture data from the camera for submission to the workflow message.
Note: The picture data length should not be too long.
customGetPictureDataFromLibrary() Use this method to get picture data from the photo library for submission to the workflow message.
Note: The picture data length should not be too long.
customGetPictureDataSuccess(fileName, imageData) Handles success from one of the "Data" calls.
customGetPictureError(result) Invoked after an error is reported.
getMimeType(fileName) A helper method that allows you to include the MIME data type in the workflow message.
Note: You can delegate the implementation of these functions to different functions supplied in other custom JavaScript files. It is not necessary to include all of your customization logic in the single Custom.js file.

Example 1

//Use this method to add custom html to the top or bottom of a form
function customBeforeWorkflowLoad() {

	var form = document.forms[curScreenKey + "Form"];
	   if (form) {
	      // header
	      var topOfFormElem = document.getElementById("topOf" + curScreenKey + "Form");
	      
	      if (topOfFormElem) {
	         topOfFormElem.innerHTML = "<img id='ImgSylogo' src='./images/syLogo.gif'/><br/>";

	         // footer
	         var bottomOfFormElem = document.getElementById("bottomOf" + curScreenKey + "Form");
	         bottomOfFormElem.innerHTML = "<p>Copyright 2010, Sybase Inc.</p>";
	      }
	   }
    return true;
}

Example 2

When using the customBeforeNavigateForward(screenKey, destScreenKey) { } function, if you want to create your own JQuery Mobile style listview, remember that JQueryMobile does not allow duplicate ID attributes. So if there is an existing listview with the same ID attribute, you must:
  1. Delete the existing listview with the same ID attribute.
  2. Re-create the listview.
  3. Call refresh for your listview.

For example:

//Use this method to add custom code to a forward screen transition. If you return false, the screen
//transition will not occur.
function customBeforeNavigateForward(screenKey, destScreenKey) {


..
try {
		if (destScreenKey == 'Personal_Work_Queue') {
			
			//grab the results from our object query
			var message = getCurrentMessageValueCollection();
			var itemList = message.getData("PersonalWorkQueue");
			var items = itemList.getValue();
			var numOfItems = items.length;
			var i = 0;
						
			//iterate through the results and build our list
			var htmlOutput = '<div id="CAMSCustomViewList"><ul data-role="listview" data-filter="true">';
			var firstOrder = '';
	
			while ( i < numOfItems ){
				var currItem= items[i];
				var opFlags = currItem.getData("PersonalWorkQueue_operationFlags_attribKey").getValue();
				var orderId = currItem.getData("PersonalWorkQueue_orderId_attribKey").getValue();
				var operationNumber = currItem.getData("PersonalWorkQueue_operationNumber_attribKey").getValue();
				var description = currItem.getData("PersonalWorkQueue_description_attribKey").getValue();
				try {
					var promDate = currItem.getData("PersonalWorkQueue_datePromised_attribKey").getValue();				
				} catch (err) {
					var promDate = "";
				}
	
				try {
					var planDate = currItem.getData("PersonalWorkQueue_dateStartPlan_attribKey").getValue();
				} catch (err) {
					var planDate = "";
				}
				
				var onHold = currItem.getData("PersonalWorkQueue_onHold_attribKey").getValue();
				
				htmlOutput += '<li><a id ="' + currItem.getKey() + '" class="listClick">';
				htmlOutput += '<p><b>Flags: </b>' + opFlags + '</p>';
				htmlOutput += '<p><b>Order Id: </b>' + orderId + '</p>';
				htmlOutput += '<p><b>Operation No: </b>' + operationNumber + '</p>';
				htmlOutput += '<p><b>Title: </b>' + description + '</p>';
				htmlOutput += '</a></li>';	
				
				i++;
				
			}
			
			htmlOutput += '</ul></div>';
		
			//append the html to the appropriate form depending on the key
			if (destScreenKey == 'Personal_Work_Queue') {

				var listview = $('div[id="CAMSCustomViewList"]');
				//Try to remove it first if already added
				if (listview.length > 0) {
					var ul = $(listview[0]).find('ul[data-role="listview"]');
					if (ul.length > 0) {
						htmlOutput = htmlOutput.replace('<div id="CAMSCustomViewList"><ul data-role="listview" data-filter="true">','');
						ul.html(htmlOutput);
						ul.listview('refresh');
					}
				} else {
					$('#Personal_Work_QueueForm').children().eq(2).hide();
					$('#Personal_Work_QueueForm').children().eq(1).after(htmlOutput);
				}
			}	
			//add the listener based on the class added in the code above
			$(".listClick").click(function(){
				currListDivID = $(this).parent().parent();
				$(this).parent().parent().addClass("ui-btn-active");
				
				//special case for bb
				navigateForward("Shop_Display",  this.id );
				
				if (isBlackBerry()) { 
					return;
				}		
			});		
		}