Unsupported content This version of the documentation is no longer supported. However, the documentation is available for your convenience. You will not be able to leave comments.

Using JavaScript to customize the My Cloud Services console


To customize the My Cloud Services console, you can use the JavaScript API to interact with the console. The customPanelsConfig.json file defines the panel, including the panel name and the location where the panel appears (on the Catalog details page or the Checkout page). The entry point function is also specified. Perform the following steps to create JavaScript files to customize the My Cloud Services console:

Step1:

Create a new JavaScript file anywhere in the custom directory or any subdirectory under it. You can use any name for the JavaScript file.

Step2 :

Implement an Entry point function. The custom code will implement the entry point function in the JavaScript file as follows:

/**
 * This is the entry point function. The CLM End User Portal console will call
 * this method and pass the context which will provide access to the customization API.
 * This is the place where the custom code will use the API to register the callback
 * methods for the event handlers. Other information like the user info can also be
 * obtained using the API.
 * @param clmContext - the CLM API context. will contain the common and the requestDetails APIs
 * @param panelObj - a JavaScript object that represents the panel (an instance of clmContext.panels.RequestCustomPanel)
 */
mycompany.clmui.request.projectInfoEntryPointFn = function(clmContext, /*clmContext.panels.RequestCustomPanel*/ panelObj) {
    
    if (!clmContext|| clmContext.requestDetails == undefined) return;

    // Register event handlers
    .....
}

Step 3:

Register call back events in the Entry point function. If you want the custom code to be notified when an action occurs in the UI, you can register it for those events in this entry point function as well. For example, the following code shows an example of registering for the onLoad event so that it is notified when the custom panel is loaded:

mycompany.clmui.request.projectInfoEntryPointFn = function(clmContext, /*clmContext.panels.RequestCustomPanel*/ panelObj) {
    
    if (!clmContext || clmContext.requestDetails == undefined) return;
    
    // save for later use
    mycompany.clmui.request.clmContext = clmContext;
    mycompany.clmui.request.projectInfoPanelObj = panelObj;
    
    // Register for the onLoad event of the panel so that we know when the panel is loaded.
    // It will also give access to the custom field values, if any
    if (panelObj) {
        panelObj.addEventListener("onLoad", mycompany.clmui.request.projectInfoPanelOnLoadHandler);
    }
    // Register for the onBeforeSave, onAfterSave and onResetToBaseline events
    clmContext.requestDetails.addEventListener("onBeforeSave", mycompany.clmui.request.InfoPanelOnBeforeSaveHandler);
    clmContext.requestDetails.addEventListener("onAfterSave", mycompany.clmui.request.InfoPanelOnAfterSaveHandler);
    clmContext.requestDetails.addEventListener("onResetToBaseline", mycompany.clmui.request.InfoTROPanelOnResetToBaselineHandler);
       
    ...
 };

Step 4: 

Create and link data source in the onLoad handler. The following examples describe specific scenarios for customizing the fields by linking data source to the fields:


    • Adding default data to the text field
    • Populating the list options
    • Making the fields inter-dependent
    • Selecting the check box by default

The following sample code shows an example to call data source and attach its values to the fields that will be handled in onLoad handler defined in Step 3.

/**
* This is the handler for the onLoad event of the custom panel. Console will call this method
* once the panel is loaded in the console and pass the custom field values, if any.
* @param event - the event object of type "onLoad". The detail property will have other data.
*/
mycompany.clmui.request.InfoPanelOnLoadHandler =  function(event) {
    var clmContext = mycompany.clmui.request.clmContext;

    // initialize the custom fields here
    if (event && event.detail && event.detail.customFieldsNameValueMap) {
        // editing
        $('#snapshot_operation_id').val(event.detail.customFieldsNameValueMap.snapshotoperation);
    } else {
        // initialize the custom fields for new request
        $('#snapshot_operation_id').val('');
    }
               
                if (event && event.detail && event.detail.customFieldsNameValueMap) {
        // editing
        $('#snapshot_name_id').val(event.detail.customFieldsNameValueMap.snapshotname);
    } else {
        // initialize the custom fields for new request
        $('#snapshot_name_id').val('');
    }
                var callback_fn = function(result){
                                var resArray =[];
                                result.forEach(function(item){
                                                var tempArray = [];
                                                tempArray = item.value.split(",");
                                                resArray = resArray.concat(tempArray);
                                });
                                var $select = $('#snapshot_operation_id');  
                                var listitems;
                                $.each(resArray, function(key, value){
                                                listitems += '<option value=' + value + '>' + value + '</option>';
                                });
                                $select.append(listitems);
                };

                //This is the error callback function
                var errorcallback_fn = function (error) {
                                console.log("Error while retrieving the external data");
                };
               
                var callback_fn1 = function(result){
                                var resArray =[];
                                result.forEach(function(item){
                                                var tempArray = [];
                                                tempArray = item.value.split(",");
                                                resArray = resArray.concat(tempArray);
                                });
                                var $select = $('#snapshot_name_id');  
                                var listitems;
                                var previousVal = "";
                                $.each(resArray, function(key, value){
                                    listitems += '<option value=' + previousVal + value.split(":",1) + '>' + previousVal + value.split(":",1) + '</option>';
                                                window.data.push(value);
                                                if(previousVal != ""){
                                                                previousVal = previousVal +value.split(":",1) + "-"+"&gt";
                                                }else{
                                                                previousVal = value.split(":",1) + "-"+"&gt";
                                                }
                                });
                                $select.append(listitems);
                };
               
                //Invoke the fetchAllowableValues API. Pass the Data source name(mandatory)
    // keyword(Optional) - search term entered by user
    // and filterCriteria(Optional) - name value object to pass context from current request ex: {"Company":"Calbro Services","Department":"R&D"}
    // callback_fn(mandatory) - Name of the callback function which is invoked with the result
    // errorcallback_fn(optional) - Name of the error callback function
  
                clmContext.externalData.fetchAllowableValues("<DatasourceName>","<keyword>",{}, callback_fn1, errorcallback_fn);
                clmContext.externalData.fetchAllowableValues("<DatasourceName>","",{}, callback_fn, errorcallback_fn);        
               
};

Step 5:

Implement other call back functions.

* This is the handler for the requestDetails.onBeforeSave event. Console will call this method
* when the "Add To Cart" or "Update" button is clicked. This is the place where we need to collect the
* custom fields data from the panel and pass to the console.
* Console will continue with the save operation only if this function returns true.
* @param event - the event object of type "OnBeforeSave".
* @returns true, if the console should continue adding/updating the request; false, otherwise
*/
mycompany.clmui.request.InfoPanelOnBeforeSaveHandler =  function(event) {
    var clmContext = mycompany.clmui.request.clmContext;
           
    // get the custom field values from the controls.
    var newCustomFieldsNameValueMap = {
                                "snapshotOperation": $("#snapshot_operation_id").val(),
                                "snapshotName": $("#snapshot_name_id").val().split("-&gt").join("/"),
                                "name": $("#snapshot_name_id").val(),
                                "snapshotId": snapshotidfn($("#snapshot_name_id").val()),
                                "targetserver": window.hostname
    };
   
    // update the custom fields data
    //in case of day 1 customization: updateCustomFieldsData
    //in case of day 2 customization: updateCustomFieldsDataDay2
    clmContext.requestDetails.updateCustomFieldsDataDay2(newCustomFieldsNameValueMap);
   
    return true; // ok to continue adding to cart or update
};

/**
* This is the handler for the requestDetails.onAfterSave event. Console will call this method
* once the request has been added to cart or updated.
 * @param event - the event object of type "OnAfterSave".
*/
mycompany.clmui.request.InfoPanelOnAfterSaveHandler =  function(event) {
    // do something, if needed.
};

/**
* This is the handler for the requestDetails.onResetToBaseline event. Console will call this method
* when the user clicks "Reset to baseline configuration" link. Reset all the fields in this custom panel
* to default values.
* @param event - the event object of type "onResetToBaseline".
*/
mycompany.clmui.request.InfoPanelOnResetToBaselineHandler =  function(event) {
     // do something, if needed.
};

Step 6:

Add an entry for this JavaScript file in the custom/customResourcesToInclude.txt file.  Reference the JavaScript file in the custom/customResourcesToInclude.txt file so that the console will load the JavaScript file. 

<script type="text/javascript" src="custom/<directoryname1>/<javascriptfilename1.js>"></script>
<script type="text/javascript" src="custom/<directoryname2>/<javascriptfilename2.js>"></script>

Tip

Edit the customResourcesToInclude.txt file carefully. If it contains any errors, the browser window might be blank (with no error message) when a user tries to open the BMC My Cloud Services console.

Step 7:

Create/update an entry in the customPanelsConfig.json file for entry point function defined in the JavaScript file. The following sample code shows an example how a custom panel might define the entry point function in the customPanelsConfig.json file.

[
    {
        "panel_name": "myCartCheckoutPanel",
        "title": "",
        "title_i18nkey": "",
        "url": "custom/cartcheckout.html",
        "location": "cart.checkout"
    },
    {
        "panel_name": "myAdditionalDisksPanel",         // REQUIRED. A unique name for this panel. In case of custom operator action, this should match with workflow name.
        "title": "Additional Disks",                    // OPTIONAL. If given, then it will be displayed as the title for the panel.
        "title_i18nkey": "cust_panel_addtldisks",       // OPTIONAL. This is the i18nkey for the title. If given, then the localized string will be looked up.
        "header": "Disk1, Disk2",                       // OPTIONAL. This is the string displayed as the header of the panel.
        "header_i18nkey": "addtldisk_header",           // OPTIONAL. This is the i18nkey for the header string.
        "panel_icon": "panelIcon",                      // OPTIONAL. If given, then this will add a new custom class to panel icon. Default icon is __icon-list
        "url": "custom/additionaldisks.html",           // REQUIRED. The html file to display in the custom panel embedded. This is not required for custom operator actions.
        "location": "catalog.offering.servergroup",     // REQUIRED. Where to embed this panel. See also location_data below.
        "location_data": {                                // OPTIONAL. Additional data that is needed to place the panel correctly. Content varies based on the location property
            "offerings": ["offering1", "offering2"],  // OPTIONAL. List of offerings (comma-separated offering names) for which to add the panel.
            "servergroup_tags": "<tags>",             // OPTIONAL. Server group tags that identifies which server groups to include.
            "panel_index": 1,                         // OPTIONAL. 0-based index of where to place.
            "servergroup_names" : ["servergroup1", "servergroup2"],  // OPTIONAL. List of server group names to include.
"transaction_requestable_offerings" : [tro1, tro2]       // OPTIONAL. Required for advanced configuration options. Should match with option name.

        },
        "entry_point_function": "mycompany.clmui.request.addtlDisksPanelEntryPointFn",  // REQUIRED unless the panel is just read-only information. Console will call this method and pass the API context.
        "roles": ["CLOUD ADMIN", "CLOUD ORGANIZATION ADMIN", "CLOUD END USER"], // OPTIONAL. Roles for which the panel should appear.
        "tenants": ["calbro", "widgetsinc"]                                      // OPTIONAL. List of tenants for which this panel should appear. If left out, then all tenants will see.
    }
]

Select appropriate value of the location property based on where to display the custom panel:

  • For Custom Operator Actions: "server.list.actions"
  • For Catalog Service Details page (Day 1): "catalog.offering.servergroup"  
  • For Server Details page (Day 2): "server.config"
  • For Advanced configurations page (Day 2 advanced): "server.config.tro"

For complete details about using these json files to customize the My Cloud Services console, see these topics:

See also the SAMPLE json files in the custom directory.

Associated APIs

The following APIs are available. They all use clmuiapi.clmContext base namespace. Click the links below for more details about each API.

Name

Description

Use the clmContext.common API to get generic information about the console (for example, information about the user who is logged in).

Use the clmContext.panels API to interact with the custom panels.

Use the clmContext.requestDetails API to get information from the service offering details or request editor page like the details of the offering being edited.

Use the clmContext.checkout API to get information about the items that are being checked out and information related to the checkout process. For example, you might use this API on the Cart Checkout customization page.

Use the clmContext.externalData API to read data from external sources such as BMC AR System forms and BMC Atrium Orchestrator workflow. This can be used for Adding-dynamic-lists-to-fields.

 

Tip: For faster searching, add an asterisk to the end of your partial query. Example: cert*