I often wondered if there is simple way of adding popup without converting whole standard page to VF and use JavaScript and Remote actions to update records.
I have found solution for that, it is not that visually pretty but it is easy and can be implemented in short time.

My requirements:
- make possible to open popup from custom button on standard SF detail page
- inside we can display standard SF page in view or edit mode, VF page or even Flow
- after save or cancel popup is closed and main record is refreshed so in case that you were adding child object they are displayed in related list.

Button - opens new window with parameters described by window.open and set timer for 0,5s (500ms) which is checking if window was closed. After popup close the caller window is reloaded.

Display Type: Detail Page Button
Behavior: Execute JavaScript
Content Source: OnClick JavaScript

var win = window.open('/apex/addOppItems?oppId={!Opportunity.Id}&retURL=/apex/ForceWindowClose', 'Popup Name' ,"width=600, height=550, scrollbars=yes");
var timer = setInterval(function() {
    if(win.closed) {
}, 500);

it can be also used with Visualforce button.

<apex:commandbutton onclick="/apex/addOppItems?oppId={!Opportunity.Id}&retURL=/apex/ForceWindowClose', 'Popup Name','width=600, height=550, scrollbars=yes');
var timer = setInterval(function() { if(win.closed) { clearInterval(timer); window.location.reload(); } }, 500);" Value="Add Line Item" reRender="LineItemsBlock"/> 

ForceWindowClose page is used to force closing popup window. It is called after succesfull save or cancel.

<apex:page showChat="false" showHeader="false" sidebar="false" applyBodyTag="false" applyHtmlTag="false">
        <title>Closing Popup</title>
            function closeWindow() {
    <body onload="closeWindow()">

In case that you will use standard controller save() and close() it is required to have "&retURL=/apex/ForceWindowClose'" in button code.
Things get complicated when you will use the same page as override for standard Edit action. For example page is adding child new record as well as it allows to edit those records. Then we need smarter solution.

New/Edit VF Page with controller extension will help us to call logic depended on state.

<apex:page standardcontroller="ObjectName__c" extensions="ObjectName_Ext">
    <apex:pagemessages />
    <apex:form >
        <apex:pageblock mode="edit" title="{!$ObjectType.ObjectName__c.label} Edit">

            <apex:pageblockbuttons >
                <apex:commandbutton value="Save" action="{!doSave}"/>
                <apex:commandbutton value="Cancel" action="{!doCancel}"/>

            <apex:pageblocksection title="Line item details" showheader="true" columns="2">



Controller need to be smart enough to check if this is new record (which is added in popup) or it is edit (which is done by standard related list edit link) then close popup or go back to page defined it retURL as standard controller save() and cancel() do that.

public with sharing class ObjectName_Ext {

    private Apexpages.StandardController stdController;
    ObjectName__c record;

    public ObjectName_Ext(ApexPages.StandardController apStdController) {
        this.stdController = apStdController;
        record = (ObjectName__c)stdController.getRecord();

    public PageReference doCancel() {
        PageReference cancelRef = stdController.cancel();
        if (record.Id == null) { // This is new record creation in PopUp
            return Page.ForceWindowClose;
        } else { // This is existing record Edit from related list
            return cancelRef;

    public PageReference doSave() {
        PageReference saveRef = stdController.save();
        if (saveRef == null) {// We have error message on page
            return null;
        } else {
            if (record.Id == null) { // This is new record creation in PopUp
                return Page.ForceWindowClose;
            } else { // This is existing record Edit from related list
                return saveRef;

Last step is to set override on Edit action to our new/edit page.

Controlling Finish actions outside of a VFP
visualforce page popup on button click

© Paweł Woźniak