A client recently wanted to add a "Save and New" command button to a Visualforce page that was using a controller extension overriding the new button. The users should be able to save the current sObject that was being created and then transition straight to adding another instance.
Creating a custom save method in Apex wasn't difficult as I could just keep a reference to the StandardController and then call save on that. However, creating a PageReference that would create the required StandardController was a bit more difficult.
My first attempt was more or less as follows. Note that this doesn't work in practice.
public with sharing class CustomExtensionController {
Foo__c foo;
ApexPages.StandardController sController;
public CustomExtensionController (ApexPages.StandardController controller) {
sController = controller;
foo = (Opportunity)controller.getRecord();
}
public PageReference saveAndNew() {
// Custom Save code here...
PageReference pr = sController.save();
return (new ApexPages.StandardController(new Foo__c())).edit();
}
}
The results in the Exception:
Visualforce Error java.lang.UnsupportedOperationException: You cannot call edit() on a null object
It seems odd that there isn't a new() method on StandardController for such a scenario. Instead the PageReference can be built up manually using the schema.
public with sharing class CustomExtensionController {
private Foo__c foo;
private ApexPages.StandardController sController;
private String queryString;
public CustomExtensionController (ApexPages.StandardController controller) {
sController = controller;
foo = (Opportunity)controller.getRecord();
// Keep track of any inbound query string parameters so they can be passed along when creating a new record
List pageUrl = ApexPages.currentPage().getUrl().split('\\?');
queryString = pageUrl[1];
}
public PageReference saveAndNew() {
try {
// Save the current sObject
sController.save();
// Get the Meta Data for Foo__c
Schema.DescribeSObjectResult describeResult = sController.getRecord().getSObjectType().getDescribe();
// Create PageReference for creating a new sObject and add any inbound query string parameters.
PageReference pr = new PageReference('/' + describeResult.getKeyPrefix() + '/e?' + queryString);
// Don't redirect with the viewstate of the current record.
pr.setRedirect(true);
return pr;
} catch(Exception e) {
// Don't redirect if something goes wrong. May be a validation or trigger issue on save.
ApexPages.addMessages(e);
return null;
}
}
}
See also:
- Force.com Discussion Boards - apex:commandButton: "Save & New" action - how do I do this?