+ Start a Discussion
MJ09MJ09 

Override Save button by overriding Edit page with detail component

I'd like to override the standard Save button for Account objects. I know I can't do that directly, so I thought I'd override the Account Edit page, going to a Visualforce page instead, and then override the standard save action in a controller extension.

 

So I created a new VF page that looks like this:

 

 

<apex:page standardController="Account" extensions="AccountEditController">
<apex:detail subject="{!id}" relatedList="true"/>
</apex:page>

Then I overrode the Account Edit button to go to this page.

 

My first problem is that this page displays in view mode, not edit mode. If I click the Edit button, it (of course) just loads the same page again. How do I get the <apex:detail> component to display in edit mode?

 

My second problem is overriding the standard Save action. I think I can do it with the following in my controller extension:


public class AccountEditController {
private final Account acct;
private ApexPages.StandardController stdController;

public AccountEditController(ApexPages.StandardController stdController) {
this.acct = (Account)stdController.getRecord();
this.stdController = stdController;
}

public PageReference save() {
// Put my own stuff here

// Do the standard save action
return this.stdController.save();
}
}

 

Is that correct?

 

Thanks!

 

MJ.

 

 

 

 

 

 

 

Ron HessRon Hess

1. You will need two pages, one for view and one for edit.  The page itself does not know which button it came from if you have two overrides pointing to one page.

 

 

2. Yes, that is correct.  During development i put a few system.debug(); statements in the save() action to check that my code is executed.

MJ09MJ09

Ron,

 

Thanks for the very prompt reply!

 

So what should the code for the edit page look like? My Account object has several page layouts, and I want to leverage them without having to re-define them individually in Visualforce.

 

Thanks!

Ron HessRon Hess

sorry, that will be very complex if you have to write each page layout edit screen.

 

there is no way to leverage the existing page layouts unless you read the layout object and arrange your input fields based on the returned values.

 

Why do you need to override the edit?  can your function be performed by a trigger or validation ? 

MJ09MJ09

What I *really* want to do is this: when the user clicks Save, if they have modified the Account's address, ask if they want to copy the new address to the Account's Contacts. If they say yes, display a VF page that lists the Contacts, with checkboxes next to each one. Allow them to select the Contacts they want to copy the Account's address to, and then do the copy.

 

There's user interaction involved, so a trigger won't work.

 

Is somebody working on providing an edit mode for the <apex:detail> component? I can't believe this is an uncommon request.

 

You wrote "unless you read the layout object and arrange your input fields based on the returned values." I assume you mean that I can do that in Apex. Is there an example of how to do that? I just did a quick search, and didn't see anything. If that's the only way to leverage existing page layouts in Visualforce, it seems like it would make for a really good blog or wiki article....

kzmpkzmp

Hi MJ Kahn,

I have the exact same problem.

Did you find a solutin for this?

 

Thanks,

kzmp

 

MJ09MJ09

Unfortunately, no.

 

The apex:detail component is view-only. There's no way to display an editable VF page that's modeled after what's defined in a standard page layout. And we can't override the standard Save action on a non-VF page.

 

The only way to accomplish what I want is to use VF to create an ediable page, placing each field on the page myself, and to completely ignore the standard page layout definition.

 

You might want to vote for this idea:

  Allow VisualForce Detail Page to be an edit form:

  https://sites.secure.force.com/ideaexchange//apex/ideaview?id=08730000000BrQtAAK

kzmpkzmp

Thanks for the reply.

I will vote for the idea .

 

Regards,

kzmp

ylandraylandra

I would vote for this too, but the link appears to be broken.

MJ09MJ09

With the re-work of the Ideas site, it looks like old links to Ideas don't work any more. Here's hoping that gets addressed soon! In the meantime, here's a new link to the old Idea:

 

https://sites.secure.force.com/success/search?type=Idea&keywords=%22Allow%20VisualForce%20Detail%20Page%20to%20be%20an%20edit%20form%22

emmadiemmadi

Can some one finds the solution to Override the save button 

AmbujAmbuj

I implemented the suggested  save() method but does not seem to be working. In my case, I already have a visualforce page on the standard Contact object. I need to ensure that there are no duplicate email Ids on contact. 

 

For this, I tried to use apex trigger on a before insert/update operation but after clicking on save button it is redirecting me to the visualforce page without displaying any error. However, the url has the error message.

 

Can this be implemented?

 

The save button is not on the visualforce page though.

 

MJ09MJ09

Sounds like you have a Before Insert (and maybe Update) trigger on Contact that verifies that the Contact's email address isn't assigned to another Contact. A trigger is the right place to put that, so good.

I'm not clear from what you wrote on the order in which you expect things to happen. When you click Save on the New Contact page (or when you perform any other action that saves the Contact), your trigger should fire and detect the duplicate. If you're seeing that the Contact is being saved with a duplicate, then your trigger isn't working as you expect it to. You'll want to trace through the code, maybe monitoring it with the Developer Console, to see what it's doing.

 


PureFactsPureFacts

Did anyone get a answer to this cause I am trying to do exactly the same thing.

 

Basically I have a SOAP endpoint in an external system and would like to call that SOAP end-point on Contact save without having to completely override the current page.

 

I tried using a trigger but unfortuantely you are not allowed to make an external callout from a trigger.

 

I believe I am going to be forced to use messaging but can't seem to figure out how to call my SOAP endpoint via messaging since it seems to be more geared towards a REST-ful like interface.

 

Whatty

 

MJ Kahn / OpFocusMJ Kahn / OpFocus

You can make a callout from a trigger, but you have to use an @future call to do it. There are issues with @future calls -- your org can have only so many @future calls active at a time, for example. Still that might work for you.

 

An alternative is to have your trigger set a flag in a field on that record, and then have a Scheduled Apex process that runs once an hour to process all records that have that flag set. Of course, that processing will be delayed, but other than a callout via @future, that may be your only alternative.

__sandra____sandra__

@PureFacts :  I have the same requirement, I need to call a synchronious web service before saving, and it might require user validation before saving the record, so I am interested by your solution, but what do you mean by 'messaging' ?

MJ Kahn / OpFocusMJ Kahn / OpFocus

Wow, a follow-on to a post that was created over 4 years ago! :) You might do better to start your own thread re the callout issue.

 

Having said that, unfortunately, there's still no way to override the standard Save button on an Edit page. And the apex:detail component still doesn't work in edit mode (although it does support some inline editing now).

 

If you want the callout to happen every time you save the Contact, regardless of whether it's from the UI or through other means, then a trigger or workflow action is the way to go. If your external service is REST-ful, then workflow Outbound Messaging isn't going to work for you, so you're left with a trigger. You can create an @future method that does the callout, and then have your trigger call that.

 

Using @future methods introduces another set of potential issues, including:

 

  • Governor limits on the number of @future methods that can be running at any one point in time.
  • Because they run asynchronously, and because your web service could take up to 2 minutes to respond, you can't rely on getting the results to show to the user in a timely manner.
  • If something fails in the @future method (like a timeout), there's no good way to tell the user that an error occured.

Depending on what your web service does and how promptly you need the results, an alternative might be to schedule a job to run periodically, to find all of the records that need to have the web service called for them, and call it. That would at least help with the governor limits concern, although it doesn't so much help with the other concerns.

Morris WinklerMorris Winkler
@future is asynchronous and therefore can not be used to get a response from Http callout. Keep in mind it is fire and forget.