[SalesForce] Mass Owner Id Edit: List view button, User selects certain records new VF page populates

I'm having a tricky time thinking about how to implement this problem. My org wants a user, from an account list view, be able to select multiple rows or accounts and change the owner (from a search field preferably).

My thoughts were I have created an example list view button that mass deletes those objects via the onclick javascript.

Is there a way to capture the selected accounts and populate a new visual force page with those selected accounts? From there I am imagining there can be some error control or checking so the user knows which accounts were selected and what actions you are performing.

so workflow: Manager(User) goes to a custom list view, selects an X amount of accounts they would wish to assign to the Rep(User). [simple version being, prompt for a search field of which user they would like to owner to be] This then transistions into a new screen that populates the selected accounts and selecting and performing operations on them.


Update: Thank you @sfdcfox for helping me! This worked great, Here is the code I ended up implementing. I just changed it to a Account list view button.

<apex:page standardController="Account" recordSetVar="accounts">
<apex:form>
    <apex:pageBlock>
        <apex:pageBlockSection>
            <apex:inputField value="{!Account.OwnerId}" />
        </apex:pageBlockSection>
        <apex:pageBlockTable value="{!selected}" var="Acct" >
            <apex:column value="{!Acct.Name}" />
            <apex:column value="{!Acct.OwnerId}"/>
        </apex:pageBlockTable>
        <apex:pageBlockButtons>
            <apex:commandButton action="{!save}" value="Save" />
        </apex:pageBlockButtons>
    </apex:pageBlock>
</apex:form>

Best Answer

Generally speaking, you use the StandardSetController. Here's a simple example of how you'd do this:

<apex:page standardController="Opportunity" recordSetVar="Opps">
    <apex:form>
        <apex:pageBlock>
            <apex:pageBlockSection>
                <apex:inputField value="{!Opportunity.OwnerId}" />
            </apex:pageBlockSection>
            <apex:pageBlockTable value="{!selected}" var="opp">
                <apex:column value="{!Opp.Name}" />
            </apex:pageBlockTable>
            <apex:pageBlockButtons>
                <apex:commandButton action="{!save}" value="Save" />
            </apex:pageBlockButtons>
        </apex:pageBlock>
    </apex:form>
</apex:page>

Create a new button, type List (with Multi-select buttons), then add it to a list view. Afterwards, users can click boxes in the list, use the button, and select a new owner. Up to 200 records can be modified at once this way.


As per the comments, here's some additional info.

The recordSetVar, here called Opps, is used to list all of the opportunities from a query or list view. This isn't practical here, because we're only interested in showing the user the records they've selected. We could use this to provide an interactive session where the user selects records they want to use (via the record's selected attribute). In this case, we're simply using recordSetVar to switch from the StandardController to the StandardSetController, so we can leverage some of its features.

This leads us to the next point. Unlike the StandardController, in the StandardSetController, the main record variable refers to a "prototype" object. When we specify {!Opportunity.OwnerId}, we're specifying that we want to set all of the selected records to the value specified by this field. In this case, when we set the Owner field, all selected records will be set to the new value. You can have up to 200 records selected, and they will all be affected by this new value.

The actual merge field {!selected} is bound to the StandardSetController's getSelected method, which just returns a list of the selected elements. If you're using the selected attribute on records, you can dynamically modify this list. We're not using that technique though, because the values are set by the user's selections in the list view.

Finally, the values for the selected list come from the built-in feature that allows users to check boxes on a list view or related list. The platform automatically injects the correct values that were selected from the prior screen. This feature allows Professional Edition users to code mass actions without Apex Code, which is definitely a powerful feature.

You could also choose to expose a list of List Views via getListViewOptions, which can be bound to the filterId attribute of the StandardSetController, allowing users to change views and select records they wish to modify on-the-fly. This is another advanced use case for the StandardSetController for a mass action page that does not require any custom Apex Code.

Related Topic