How to Override the Applet Method Invoked in IP2014's Presentation Model

Recently, we upgraded an environment from Siebel version 7.8.2 to IP2014.  As we were performing testing we noticed that some applets had ++ images while others had + images to add records to applets.  This was really confusing to the testing team.

We found the underlying cause was that the Aurora styling displays the + image for controls invoking the NewRecord method while it displays the ++ image for controls invoking the CreateRecord method.  We also noticed that the CTRL-N hotkey was not adding a new record to the applet for the controls that invoked CreateRecord.  

If you are not familiar with the CreateRecord method, then it is commonly used for applets where there is a M:M relationship between the parent business component and the child business component.  CreateRecord has the ability to associate a new child record by inserting the intersection record between that child and the parent.

After some research we found that the hotkey not working with the CreateRecord method was a commonly reported issue in previous versions of Siebel and that solutions have been identified.  This link provided a great solution utilizing browser script:

http://siebel.ittoolbox.com/groups/technical-functional/siebel-dev-l/how-to-avoid-invoking-associate-applet-in-a-view-based-on-mm-relationship-whiole-creating-a-new-record-in-the-child-applet-1299954

We took on the task of updating this solution to use the new standard of writing Javascript in the Physical Renderer or Presentation Model.  

Steps Taken:

  1. Tie an association applet to the child applet.  This allows the NewRecord method to be invoked on a child applet where there is a M:M relationship between the child and parent.
  2. Change the method invoked on the child applet from CreateRecord to NewRecord.  This allows the CTRL-N hotkey to work.
  3. Create Presentation Model Javascript that will recognize the invocation of the NewRecord method and invoke CreateRecord instead.

We always try to limit the amount of browser script in our configurations.  We try to avoid it as much as possible.  We do have to say that writing old fashioned browser script does appear to be a lot cleaner and straight forward than the new method of writing Javascript in the Physical Renderer and Presentation Model.  However, even though it doesn't look pretty this new method of writing Javascript in the Physical Renderer and Presentation Model is very powerful.

First, we took on the list applet's Presentation Model:

// Bloomspire provided example of capturing the NewRecord method invocation and handling that invocation
if( typeof( SiebelAppFacade.NewRecordOverrideListAppletPM ) === "undefined" )
{
    SiebelJS.Namespace("SiebelAppFacade.NewRecordOverrideListAppletPM");
    
    define("siebel/custom/NewRecordOverrideListAppletPM", 
        [], 
        function () 
        {
            SiebelAppFacade.NewRecordOverrideListAppletPM = ( function()
            {
                function NewRecordOverrideListAppletPM(proxy)
                {
                    SiebelAppFacade.NewRecordOverrideListAppletPM.superclass.constructor.call(this, proxy);
                }
                
                SiebelJS.Extend(NewRecordOverrideListAppletPM, SiebelAppFacade.ListPresentationModel);
                
                NewRecordOverrideListAppletPM.prototype.Init = function()
                {
                    SiebelAppFacade.NewRecordOverrideListAppletPM.superclass.Init.call( this );
                    
                    // When a method is invoked, OverwriteNewRecordMethod will be executed before the method is sent to the server
                    this.AddMethod( "InvokeMethod", OverwriteNewRecordMethod, { sequence : true, scope : this } ); 
                };
                
                function OverwriteNewRecordMethod(methodName, psInputArgs, lp, returnStructure)
                {
                    if(methodName === "NewRecord")
                    {
                        this.ExecuteMethod("InvokeMethod", "CreateRecord", psInputArgs);
                        returnStructure["CancelOperation"] = true;
                    }
                    else
                    {
                        returnStructure["CancelOperation"] = false;
                    }
                }
            
                return NewRecordOverrideListAppletPM; 
            } ());
                    
            return "SiebelAppFacade.NewRecordOverrideListAppletPM";
        });
}

Then, we took on form applet's Presentation Model:

// Bloomspire provided example of capturing the NewRecord method invocation and handling that invocation
if( typeof( SiebelAppFacade.NewRecordOverrideFormAppletPM ) === "undefined" )
{
    SiebelJS.Namespace("SiebelAppFacade.NewRecordOverrideFormAppletPM");
    
    define("siebel/custom/NewRecordOverrideFormAppletPM", 
        [], 
        function () 
        {
            SiebelAppFacade.NewRecordOverrideFormAppletPM = ( function()
            {
                function NewRecordOverrideFormAppletPM(proxy)
                {
                    SiebelAppFacade.NewRecordOverrideFormAppletPM.superclass.constructor.call(this, proxy);
                }
                
                SiebelJS.Extend(NewRecordOverrideFormAppletPM, SiebelAppFacade.PresentationModel);
                
                NewRecordOverrideFormAppletPM.prototype.Init = function()
                {
                    SiebelAppFacade.NewRecordOverrideFormAppletPM.superclass.Init.call( this );
                    
                    // When a method is invoked, OverwriteNewRecordMethod will be executed before the method is sent to the server
                    this.AddMethod( "InvokeMethod", OverwriteNewRecordMethod, { sequence : true, scope : this } ); 
                };
                
                function OverwriteNewRecordMethod(methodName, psInputArgs, lp, returnStructure)
                {
                    if(methodName === "NewRecord")
                    {
                        this.ExecuteMethod("InvokeMethod", "CreateRecord", psInputArgs);
                        returnStructure["CancelOperation"] = true;
                    }
                    else
                    {
                        returnStructure["CancelOperation"] = false;
                    }
                }
            
                return NewRecordOverrideFormAppletPM; 
            } ());
            
            return "SiebelAppFacade.NewRecordOverrideFormAppletPM";
        });
}

There is a subtle difference when writing the SiebelJS.Extend line of code for form applet versus list applets.

Finally, we saved the files in the siebel/custom directory, entered Manifest File entries, and created Manifest Administration records for the appropriate applets to tie them to the correct Presentation Model Javascript based on whether it was a form or list applet.

This solution is a small update to an already documented solution with at least one great benefit:  You don't have to regenerate browser scripts to get it to work!