Thursday, April 16, 2015

[Salesforce / Apex / VisualForce] Getting rid of the "Save & New" button

In some circumstances the "Save & New" button on the standard layout is not desired.

This is an idea (there are others of this kind) to make this optional on layouts, but unfortunately it's been freezed for years.

The simpler solution was to execute some javascript on a hone page component in order to hide every button that has the "save_new" name:
Remove Save & New button of the standard edit page.

With Summer '15 you cannot use anymore custom home page components that contains script tags, so the hack is not valid anymore: if you try to create/edit an HTML Area Custom Component you get this info message:

This component contains code that is no longer supported. For security reasons, in Summer '15 we will start removing non-supported code from HTML Area home page components. As a result, this component may stop working properly.

If you want to use JavaScript or other advanced HTML elements in your home page component, we recommend that you create a Visualforce Area component instead.

I had to find a solution for a client, and the "New" button override was the way.

The button I'm talking about is this one (on the Editing standard layout):

You simply have to override the "New" button on your selected objects, creating for each object a Visual Force page with a standard Controller and the following extension:

<apex:page standardController="Account" extensions="SObjectNewActionOverrideController" action="{!onLoadPage}">

public class SObjectNewActionOverrideController {
    public String debug{get;Set;}
    private String SObjectPrefix = null;
    public SObjectNewActionOverrideController(ApexPages.StandardController controller){
        this.SObjectPrefix = controller.getRecord().getSObjectType().getDescribe().getKeyPrefix();
    public PageReference onLoadPage(){
        this.debug = JSON.serializePretty(ApexPages.currentPage().getParameters());
        String retURL = ApexPages.currentPage().getParameters().get('retURL');
        //these are the conditions to understand that this is actually a "new" page
        //that comes from a previously "save" page in which the user clicked on "Save & New"
           && retURL != null
           && retURL.startsWith('/'+SObjectPrefix)
           && retURL.indexOf('/', 4) < 0
           && !retURL.contains('?')
           && retURL.length() >= 15){
               PageReference pg = new PAgeReference(retURL);
               return pg;
               PageReference pg = new PAgeReference('/'+this.SObjectPrefix+'/e');
               for(String key : ApexPages.currentPage().getParameters().keyset()){
                   if(key == 'save_new' || key == 'sfdc.override') continue;
                   pg.getParameters().put(key, ApexPages.currentPage().getParameters().get(key));
               return pg;

The code simply does a redirect to the "previously" edited record if we are coming from a save operation (and user clicks on "Save & New"), getting rid to the "New" action of the "Save & New", or simply goes to the standard edit page (the retURL is evaluated: if it is not an object ID then goes to the New action).

As stated in the code, there are other places in which the user clicks on a "New" button but the "save_new" parameter is still passed by Salesforce (I don't understand the reason though), but this time the user should see the "New" page.

These buttons are the "New" button on the Sobject main page (e.g. /001/o page):

And the related lists:

Comments and alternative solutions are really appreciated!