+ Start a Discussion
KelseyBKelseyB 

redirect after save or cancel button

I created a Visualforce page and Apex controller to clone a record. What I need now is to have the Save and Cancel button redirect back to the originating record. I have no experience with Apex or VF and was able to create this with the help of this developer forum. Can anyone help me with what code to add and where to put it, to get the Save Button and Cancel Button to redirect back to the original record? 

Here's the vf page code: 

<apex:page standardController="OpportunityLineItem" extensions="customcloneOpportunityLineItem">
<apex:form >
<apex:pageBlock title="Opportunity Product details">
<apex:pageBlockSection title="Opportunity Prodcut Edit" columns="1">
<apex:inputfield value="{!OpportunityLineItem.OpportunityId}"/>
<apex:inputField value="{!OpportunityLineItem.Product2Id}" />
<apex:inputField value="{!OpportunityLineItem.Quantity}" />
<apex:inputField value="{!OpportunityLineItem.Unit_List_Price__c}" />
<apex:inputfield value="{!OpportunityLineItem.Unit_Sales_Price__c}"/>
<apex:inputfield value="{!OpportunityLineItem.Unit_Cost__c}"/>
<apex:inputfield value="{!OpportunityLineItem.ProductCode}"/>
<apex:inputfield value="{!OpportunityLineItem.Product_Family__c}"/>
</apex:pageBlockSection>
<apex:pageBlockButtons >
<apex:commandButton action="{!cloneopportunitylineitem}" value="Save" />
<apex:commandButton action="{!cloneopportunitylineitem}" value="Cancel" />
</apex:pageBlockButtons>
        </apex:pageBlock>
</apex:form>
</apex:page>

Here's the Apex Class: 

public class customcloneOpportunityLineItem
{private opportunitylineitem l;
public customcloneOpportunityLineItem(apexpages.standardcontroller std){
this.l = (opportunitylineitem)std.getrecord();
}

public void cloneOpportunityLineItem(){
opportunitylineitem l1 = new OpportunityLineItem();
l1 =l.clone();
insert l1; 
}
}
 
Best Answer chosen by KelseyB
Martha VMartha V
try this
 
<apex:page standardController="OpportunityLineItem" extensions="customcloneOpportunityLineItem">
<apex:form >
<apex:pageBlock title="Opportunity Product details">
<apex:pageBlockSection title="Opportunity Prodcut Edit" columns="1">
<apex:inputfield value="{!OpportunityLineItem.OpportunityId}"/>
<apex:inputField value="{!OpportunityLineItem.Product2Id}" />
<apex:inputField value="{!OpportunityLineItem.Quantity}" />
<apex:inputField value="{!OpportunityLineItem.Unit_List_Price__c}" />
<apex:inputfield value="{!OpportunityLineItem.Unit_Sales_Price__c}"/>
<apex:inputfield value="{!OpportunityLineItem.Unit_Cost__c}"/>
<apex:inputfield value="{!OpportunityLineItem.ProductCode}"/>
<apex:inputfield value="{!OpportunityLineItem.Product_Family__c}"/>
</apex:pageBlockSection>
<apex:pageBlockButtons >
<apex:commandButton action="{!cloneopportunitylineitem}" value="Save" />
<apex:commandButton action="{!cancel}" value="Cancel" />
</apex:pageBlockButtons>
        </apex:pageBlock>
</apex:form>
</apex:page>

Here's the Apex Class: 

public class customcloneOpportunityLineItem{
    private opportunitylineitem l;
    public customcloneOpportunityLineItem(apexpages.standardcontroller std){
        this.l = (opportunitylineitem)std.getrecord();
    }

    public PageReference cloneOpportunityLineItem(){
        opportunitylineitem l1 = new OpportunityLineItem();
        l1 =l.clone();
        insert l1; 
        //go back to the original lineItem page
        PageReference result= new PageReference('/'+l.Id);
        result.setRedirect(true); 
        return result;
    }

    public PageReference cancel(){
        opportunitylineitem l1 = new OpportunityLineItem();
        l1 =l.clone();
        insert l1; 
        //go back to the original lineItem page
        PageReference result= new PageReference('/'+l.Id);
        result.setRedirect(true); 
        return result;
    }
}

 

All Answers

Martha VMartha V
try this
 
<apex:page standardController="OpportunityLineItem" extensions="customcloneOpportunityLineItem">
<apex:form >
<apex:pageBlock title="Opportunity Product details">
<apex:pageBlockSection title="Opportunity Prodcut Edit" columns="1">
<apex:inputfield value="{!OpportunityLineItem.OpportunityId}"/>
<apex:inputField value="{!OpportunityLineItem.Product2Id}" />
<apex:inputField value="{!OpportunityLineItem.Quantity}" />
<apex:inputField value="{!OpportunityLineItem.Unit_List_Price__c}" />
<apex:inputfield value="{!OpportunityLineItem.Unit_Sales_Price__c}"/>
<apex:inputfield value="{!OpportunityLineItem.Unit_Cost__c}"/>
<apex:inputfield value="{!OpportunityLineItem.ProductCode}"/>
<apex:inputfield value="{!OpportunityLineItem.Product_Family__c}"/>
</apex:pageBlockSection>
<apex:pageBlockButtons >
<apex:commandButton action="{!cloneopportunitylineitem}" value="Save" />
<apex:commandButton action="{!cancel}" value="Cancel" />
</apex:pageBlockButtons>
        </apex:pageBlock>
</apex:form>
</apex:page>

Here's the Apex Class: 

public class customcloneOpportunityLineItem{
    private opportunitylineitem l;
    public customcloneOpportunityLineItem(apexpages.standardcontroller std){
        this.l = (opportunitylineitem)std.getrecord();
    }

    public PageReference cloneOpportunityLineItem(){
        opportunitylineitem l1 = new OpportunityLineItem();
        l1 =l.clone();
        insert l1; 
        //go back to the original lineItem page
        PageReference result= new PageReference('/'+l.Id);
        result.setRedirect(true); 
        return result;
    }

    public PageReference cancel(){
        opportunitylineitem l1 = new OpportunityLineItem();
        l1 =l.clone();
        insert l1; 
        //go back to the original lineItem page
        PageReference result= new PageReference('/'+l.Id);
        result.setRedirect(true); 
        return result;
    }
}

 
This was selected as the best answer
KelseyBKelseyB
Thank you Martha Vance, this is almost perfect! The Save button completes the clone and returns back to the original page. But the cancel button also clones the record. Any ideas on how to stop that from happening? 
TylerBrooksTylerBrooks
Kelsey,

In the controller for cancel, it is creating a clone. Replace the Controler code with this
 
public class customcloneOpportunityLineItem{
    private opportunitylineitem l;
    public customcloneOpportunityLineItem(apexpages.standardcontroller std){
        this.l = (opportunitylineitem)std.getrecord();
    }

    public PageReference cloneOpportunityLineItem(){
        opportunitylineitem l1 = new OpportunityLineItem();
        l1 =l.clone();
        insert l1; 
        //go back to the original lineItem page
        PageReference result= new PageReference('/'+l.Id);
        result.setRedirect(true); 
        return result;
    }

    public PageReference cancel(){
        //go back to the original lineItem page
        PageReference result= new PageReference('/'+l.Id);
        result.setRedirect(true); 
        return result;
    }
}

Regards,

Tyler​​​​​​​
KelseyBKelseyB
Thank you both so much! The combination of redirect code and the cancel code from each of you worked perfectly. Really appreciate the help!
Martha VMartha V
Sorry about that Kelsy, I guess I answered to late last night and forgot to delete the lines to clone it when I copy and pasted. I'm glad you got this solved :)
 
KelseyBKelseyB
Guys, my inexperience is showing! I went to deploy my Apex class to production, but I only have 70% code coverage. I did some googling and realized I need to create a test class(?) and figure out how to up my coverage. I know that I have to add @isTest at the beginning but that can't be it. Do I create a new Apex Class to test or do I just add code to the existing one? Any help would be appreciated. Thanks!
TylerBrooksTylerBrooks
Kelsey,

Yes all Apex Classes, controllers, and triggers need to have a test class to ensure the code won't break in your org.
Here is the documentation for testing controllers: https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_controller_error_handling.htm

You will need to create a separate class similar to what the documentation shows to test against the controller.

I've constructed a test class for you that gave me 100% coverage so it should work for you, will only need to change the visualforce page name
 
@isTest 
public class ControllerTestClass 
{
 static testMethod void testMethod1() 
 {
 	Account acc = new Account(Name = 'Test Account');
		insert acc;
		
		//get standard pricebook
		// This is how we get the Standard PriceBook Id.  Prior to Summer '14, we needed
		// to use SeeAllData=true, so this is a big improvement
		Id pricebookId = Test.getStandardPricebookId();

		Product2 prd1 = new Product2 (Name='Test Product Entry 1',Description='Test Product Entry 1',productCode = 'ABC', isActive = true);
		insert prd1;
		
		PricebookEntry pbe1 = new PricebookEntry (Product2ID=prd1.id,Pricebook2ID=pricebookId,UnitPrice=50, isActive=true);
		insert pbe1;
		
		Opportunity opp1 = new Opportunity (Name='Opp1',StageName='Stage 0 - Lead Handed Off',CloseDate=Date.today(),Pricebook2Id = pbe1.Pricebook2Id, AccountId = acc.id);
		insert opp1;

		OpportunityLineItem lineItem1 = new OpportunityLineItem (OpportunityID=opp1.id,PriceBookEntryID=pbe1.id, quantity=4, totalprice=200);
		insert lineItem1;

 Test.StartTest(); 

  PageReference pageRef = Page.opplineitemclone; // Add your VF page Name here
  pageRef.getParameters().put('id', String.valueOf(lineitem1.Id));
  Test.setCurrentPage(pageRef);

  ApexPages.StandardController sc = new ApexPages.StandardController(lineitem1);   
  customcloneOpportunityLineItem ccopp = new customcloneOpportunityLineItem(sc);
  ccopp.cloneOpportunityLineItem();
  ccopp.cancel();
 Test.StopTest();
 }
}

 
KelseyBKelseyB
TylerBrooks I can't thank you enough. This worked perfectly. Now that this big rush for this button is done, I promise to do more research and learning so I won't have to keep asking for help! Let me know if I can venmo you (and Martha, you too!) for a cup of coffee on me. :)
Martha VMartha V
no worries, Kelsey. I've gotten a lot of help here too, it's my turn to pay it forward :)
Manju VenkatManju Venkat
@Martha V, you rock!! :)