[SalesForce] Looking to open new subtab from a button on Contact; current subtab replaced instead

I am trying to do a similar thing to How to open a subtab, opening a Case subtab from a button on the Contact detail, and I don't believe that the javascript is firing at all. The page controller is creating a new Case, but I am also seeing the 'External Page' as the subtab heading, and the Case detail is overwriting the Contact's subtab.

I'm creating and saving the Case rather than using the standard [New] because I need the Case.Id for the controller extensions that display additional details to support the Case edit.

Here is the controller:

public class NxConsoleCaseCreationController {

public String contactId {get;set;}
public String caseId {get;set;}

public NxConsoleCaseCreationController() {
    // Retrieve the Contact.Id passed in to the controller
    if(ApexPages.currentPage().getParameters().containsKey('ci') &&
       ApexPages.currentPage().getParameters().get('ci').length() > 0) {
        contactId = ApexPages.currentPage().getParameters().get('ci');
        System.debug('Controller called with Contact.Id ' + contactId);            
    }
}

// activate creates a Case 'shell' so that the Case detail's controller
// extensions have access to the Case.Id
public void activate() {

if(contactId == null) {
    System.debug('activate() method, contact.Id is null.');
    ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 
        'Contact.Id is blank.'));
}

// so far, so good - create a Case shell
try {
    caseId = createConsoleCase(contactId);
    System.debug('returning from createConsoleCase() with ' + caseId);
    if(caseId == null) {
        System.debug('activate() method, case.Id is null.');
        ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR,
            'Unable to create Console Case with id provided'));
    }
} catch (Exception e) {
    System.debug('activate() exception ...');
    ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 
        'Case could not be created for this Contact.'));
}

}

'// createConsoleCase returns the Case.Id of the Case shell that was created'

public String createConsoleCase(String contactId) {
    System.debug('inside createConsoleCase() ...');
    String result;
    try {
        Contact tmpC = [Select Id, AccountId from Contact where Id = :contactId];
        Case tmpCs = new Case(ContactId = tmpC.Id, AccountId = tmpC.AccountId, RecordTypeId=Utils.getRecordTypeId('Case', 'Console Shell'),
            Status='Open', Case_Issue__c='** Please Select Case Issue **');
        insert tmpCs;
        result = tmpCs.Id;
        System.debug('Case creation successful; case.Id = ' + result);      
    } catch (Exception e) {
        Ayarwm.debug('createConsoleCase() exception ...');
        ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR,
            'Case could not be created for this Contact/Account pair'));
    }
    return result;
}
}

And the page:

apex:page showHeader="false" sidebar="false" cache="false" controller="NxConsoleCaseCreationController" action="{!activate}" 
apex:includeScript' value="/soap/ajax/27.0/connection.js" 
apex:includeScript' value="/support/console/29.0/integration.js" 
script type="text/javascript"


// caseId = Case.Id of new Case created by NxConsoleCaseCreationController.activate()
// Use caseId to open a new subtab off of the current Contact(/Account) detail with the 
// page layout assigned to the new Case.recordtype

// openNewSubTab retrieves the current sessionId and the primary tab id
function openNewSubTab(result) {
    // retrieve the sessionId (thank you, @amatorVitae!)
    sforce.connection.sessionId = '{!$Api.Session_ID}';
    if(sforce.console.isInConsole()) {
        sforce.console.getEnclosingPrimaryTabId(openSubTabs);
    }
}

var openSubTabs = function openSubTabs(result) {
    // use the caseId from the controller extension to determine the URL
    sforce.console.openSubTab(result.id, '/' + '{!caseId}', true, 'Select Case RecordType', null);
}

var previousOnload = window.onload;

window.onload = function() {
    if(previousOnload) {
        previousOnload();
    }
    openNewSubTab();
}

Best Answer

After struggling with a combination of a JavaScript button launching a VF page using more JavaScript to open a subtab, it's now been boiled down to the single JavaScript button, which looks like this:

// Require the Salesforce Console Integration Toolkit  
{!REQUIRESCRIPT("/support/console/33.0/integration.js")}

// Require the AJAX Toolkit  
{!REQUIRESCRIPT("/soap/ajax/33.0/connection.js")}

// Verify sforce.console now exists  
console.log("sforce: %o", sforce); 

// Get the enclosing tab's ID, so that openSubtab() 
can be called with the correct parameter*/ 
sforce.console.getEnclosingPrimaryTabId(function(response) {

// Remember the primary tab ID for openSubtab()  
var primaryTabId = response.id; 
console.log("primaryTabId: %o", primaryTabId); 

// Create Case using AJAX toolkit  
var cs = new sforce.SObject("Case"); 
cs.RecordTypeId = "012L000000090fq"; 
cs.Subject = "Subject required"; 
cs.Case_Issue__c = "** Please Select Case Issue **"; 
cs.ContactId = "{!Contact.Id}"; 
cs.AccountId = "{!Contact.Account_ID__c}"; 
cs.Status = "Open"; 

// Create the Case  
var result = sforce.connection.create([cs]); 
cs.Id = result[0].id; 
if(result[0].getBoolean("success")) { 
console.log("new case created with id " + result[0].id); 
} else { 
console.log("failed to create case " + result[0]); 
} 

// Define the target URL using a dummy Case ID  
var url = "{!URLFOR($Action.Case.View, '500')}"; 

// Replace the dummy Id with the actual Case.Id  
url = url.replace("500", cs.Id); 

// Define other parameters for openSubtab()  
var isActive = true; 
var tabLabel = null; 
var subtabId = null;

// Call openSubtab()  
sforce.console.openSubtab( 
primaryTabId, url, isActive, tabLabel, subtabId); 
});

The url.replace() feels kludgy, and if I can go straight to using 'cs.Id' in future iterations I will.

The reason that I want to create the Case in this manner is to leverage the new Case.Id to pull in additional details in the Case page's associated Console Components, which are blank when the Case is first loaded via the standard [New] button.

Thanks Marty C.!

Related Topic