1

On MVP Office Hours (For those interested, the success community group is here: https://success.salesforce.com/_ui/core/chatter/groups/GroupProfilePage?g=0F9300000001oXH), there was a question regarding a Visualforce page using a Standard Set Controller. When the next button was clicked on the Visualforce page, it would throw a Visualforce exception if one or more of the current 20 records had been modified, but not saved to Salesforce.

The question was whether there was a better way of handling this using as little or no controller code if possible.

2 Answers 2

2

The reasoning for this is similar to when you see a "concurrent modification exception" in Java, or a "Performed a save on these records, but they weren't committed to the database" on a SQL platform. Essentially, you have modified some records, but haven't committed those results yet.

The only way to handle this that I can think of is writing a Visualforce extension class, that uses the StandardSetController (or SSC) and enhances the next method.

Using the following example from Salesforce docs (http://www.salesforce.com/us/developer/docs/pages/Content/pages_custom_list_controller.htm), here's what your visualforce page and extension may look like.

Visualforce:

<apex:page standardController="Account" recordSetVar="accounts" extensions="AccountExtCtrl">
    <apex:pageBlock title="Viewing Accounts">
        <apex:form id="theForm">
            <apex:pageBlockSection >
                <apex:dataList value="{!accounts}" var="acct" type="1">
                    {!acct.name}
                    <!-- probably want some input fields here for editing -->
                </apex:dataList>
            </apex:pageBlockSection>
            <apex:panelGrid columns="2">
                <apex:commandLink action="{!previous}">{!$Label.Previous}</apex:commandlink>
                <!-- Instead of calling the standard set controller next method, I am calling my extension's next method, essentially overriding the SSC next method -->
                <apex:commandLink action="{!extensionNextMethod}">{!$Label.Next}</apex:commandlink>
            </apex:panelGrid>
        </apex:form> 
    </apex:pageBlock>
</apex:page>

Extension controller:

public with sharing class AccountExtCtrl {
    private ApexPages.StandardSetController ctrl {get;set;}

    public AccountPagination(ApexPages.StandardSetController controller) {
        ctrl = controller;
    }    

    public PageReference extensionNextMethod(){

        //You could simply just display another, friendlier error like this
        PageReference pageRef = null;
        try{
            ctrl.Next();
        }catch(Exception e){
            ApexPages.addMessage(new ApexPages.Message(ApexPages.SEVERITY.WARNING,Label.COULD_NOT_SAVE_MODIFIED_RECORDS));
        }

        // - OR - You could catch the modified records exception, update those records, and then call next again, based on your business process / UX desire.
        try{
            ctrl.Next();
        }catch(Exception e){
            //If current page contains modified records,
            //Update the current page of records, and get the next page.
            update ctrl.getRecords();
            ctrl.Next();
        }
    }

    public ApexPages.StandardSetController accountRecords {
        get {
            if(accountRecords == null) {
                accountRecords = new ApexPages.StandardSetController(
                    Database.getQueryLocator([SELECT Name FROM Account WHERE Id NOT IN 
                        (SELECT AccountId FROM Opportunity WHERE IsClosed = true)]));
            }
            return accountRecords;
        }
        private set;
    }
    public List<Account> getAccountPagination() {
         return (List<Account>) accountRecords.getRecords();
    }  
}

Note, I'm using the super Exception class here, and I'm not sure if there's a way to distinguish the "Modified Record" exception versus other exceptions your Visualforce may encounter.

2

Unfortunately, since I just joined stack exchange, I can't comment yet so starting a new answer. Instead of adding a warning message when catching the exception, couldn't you add the specific message to the visualforce page? I think adding the system warning to the page, as opposed to the generic label, would let you know if it was a modify record exception as opposed to any other exception. For instance:

catch (Exception e) {ApexPages.addMessage(new ApexPages.Message(ApexPages.SEVERITY.ERROR, e.getMessage()));}

1
  • Sure you could. This may be more desirable, just depends on requirements or preference. Feb 18, 2014 at 15:19

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .