0

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>

1

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.

  • 1
    This is a powerful example that is not obvious to many users (me included in years past) as to why it works. Although I know the answers, typical questions: (1) Opps is never referenced again on the page, why? (2) {!Opportunity.OwnerId} - what is it bound to if this references multiple Opportunities? (3) {!selected}, what is this bound to? (4) Where do the records come from to populate the page? – cropredy Dec 9 '16 at 18:48
  • @sfdcfox , I ran into a snag with the solution. I ran some testing and the system changes the account owner but not the contact owner under the account. Is there a local way to change this here? or in other words a solution that wouldn't involve a global change such as workflow or a trigger for example. Or in other words is there a way to take the inputfield value and assign it to the contacts underneath? Thank you again for your help! – greenSloth Dec 12 '16 at 15:51
  • @greenSloth Yes, you can write an extension class that queries the contacts and moves them as well. – sfdcfox Dec 12 '16 at 16:11
  • @sfdcfox awesome! I need to read up on extensions. I apologize I am really new to apex. Would you write an extension class for the "contacts" ie: "public class myControllerExtension { private final Contact cont; " – greenSloth Dec 12 '16 at 16:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.