Abstract
So, as luck would have it, there’s this wonderful thing called Salesforce Labs. According to their description on the AppExchange, SF Labs helps “solve tough business challenges fast with Labs apps, free, customizable solutions built by Salesforce employees.” I don’t know about you, but I think that all sounds pretty dang fantastic!
You mean there are times when SFDC employees realize there’s a (common) tough business challenge out there that they can provide a solution for… they just do it?? And… and they give it away for free??
*insert “mind blown” meme here*
One of the best parts about SF Labs offerings, is that they’re delivered as un-managed packages. This means, that you can open them up, monkey with their moving parts and put them back together in order to meet your specific use case requirements. Excuse me, but I think that’s just effin’ neat.
Sleeves Up. Let’s Go
In this post, I’m going to show you how to customize SF Labs’ “Mass Update and Mass Edit From List View” offering. As described on the app’s page “Mass update and mass edit selected records from any filter view or related list. You get two easy to use tools designed for both admins and standard users. Your users will thank you for this.” Frankly, I tend to agree with them on that last part. If you have a User base that’s used to using Excel, I think you will too!
In a nutshell:
- You’ll install the Mass Edit and Mass Update app from the AppExchange (To your SANDBOX please! Although this one’s pretty safe to deploy, it’s a best practice to always make changes in Sandbox, verify they work as intended and THEN move them into production… the choice is yours though… just sayin’…)
- You’ll add a custom button to the List View of a specific Object.
- When Users have generated a set of Records (i.e. hit “Go!” or otherwise selected a View), they’ll have the ability to check boxes next to those they’d like to edit in mass.
- Once they’ve selected the Records, they’ll click the custom button
- All selected Records will be brought into a Visualforce page
- Every field that’s to be editable via this page, is shown in a column
- Because Salesforce Labs is completely awesome, we can control which fields can be edited on this Visualforce page by editing the available columns.
Although the app installs 55 components, for now, the only part we’re going to pay attention to (read: monkey with) is the Visualforce Page for mass editing Accounts. Thankfully, they’ve aptly named this page “MassEditAccount” which makes it easy to track down.
Before any monkey business, let’s install the package. It can be found here. Once you’ve installed it, return to this page and continue.
Now that that’s out of the way, let’s customize some Visualforce pages! In this example I’m going to show you how to add/remove fields from the MassEditAccount page. To start, navigate to:
Setup | Build | Develop | Installed Packages | Mass Update And Edit
Once here:
- Hit CTRL + F (find) on your keyboard to do a quick search for “MassEditAccount”. Once it’s found…
- Right click on the link and select “Open in New Tab” as shown below.
Once you’ve followed the link, you should see the Page Details of the MassEditAccount Visualforce page. The top part’s pretty simple to understand. The block of code below that part is what typically frightens people away.
To make this a bit easier to read, I’m going to do some simple indenting and add some numbering and a few spaces before/after specific groups of lines.
1. <apex:page standardController="Account" recordSetVar="unused" sidebar="false"> 2. <apex:includeScript value="{!$Resource.UtilJS}" /> 3. <apex:form > 4. <apex:pageBlock > 5. <apex:pageMessages /> 6. <apex:pageBlock > 7. Note: All modifications made on the page will be lost if Return button is clicked without clicking the Save button first. 8. </apex:pageBlock> 9. <apex:pageBlockButtons > 10. <apex:commandButton value="Save" action="{!save}"/> 11. <apex:commandButton value="Return" action="{!cancel}"/> 12. </apex:pageBlockButtons> 13. 14. 15. <apex:pageBlockTable value="{!selected}" var="acc" id="table"> 16. 17. 18. <apex:column headerValue="Name"> 19. <apex:inputField value="{!acc.name}"/> 20. </apex:column> 21. 22. 23. <apex:column headerValue="Annual Revenue"> 24. <apex:inputField value="{!acc.AnnualRevenue}"/> 25. </apex:column> 26. 27. 28. <apex:column headerValue="Rating"> 29. <apex:inputField value="{!acc.Rating}"/> 30. </apex:column> 31. 32. 33. <apex:column headerValue="Industry"> 34. <apex:inputField value="{!acc.Industry}"/> 35. </apex:column> 36. 37. 38. <apex:column headerValue="Phone"> 39. <apex:inputField value="{!acc.Phone}"/> 40. </apex:column> 41. 42. 43. <apex:column headerValue="Type"> 44. <apex:inputField value="{!acc.type}"/> 45. </apex:column> 46. 47. 48. <apex:column headerValue="Description"> 49. <apex:inputField value="{!acc.Description}"/> 50. </apex:column> 51. 52. 53 </apex:pageBlockTable> 54. </apex:pageBlock> 55. </apex:form> 56. </apex:page>
Let’s touch on the parts you may want to modify.
Please note, I’m keeping this pretty simple on purpose. There are, of course, innumerable things we could change/add. That’s for another time, though.
Line 7: This is a message that will be displayed across the top of your Visualforce page. By default it says “All modifications made on the page will be lost if Return button is clicked without clicking the Save button first.” I’m going to replace mine with “Remember, if you don’t hit Save, it doesn’t happen.”
Lines 18-50: Meat and potatoes time! You may have noticed that when I reformatted the Visualforce page’s code, I broke these lines out into groups of three. That’s because, every group of three is the: Opening, Detail and Closing of (what I’ll call) a blueprint for building a column. Think of the overall page like an Excel worksheet with lots of columns.
For example:
18. <apex:column headerValue="Name"> 19. <apex:inputField value="{!acc.name}"/> 20. </apex:column>
Line 18: This is what’s called an Opening Tag. Stripped down, it would simply be <apex:column>. In this scenario, however, we need to insert a column label. That’s where “headerValue=”Name” comes in. Changing “Name” will change this column’s label.
Line 19: This is where we designate a field that’s to be included in this specific column. What you see here translates into “This is going to be the place where you can enter a value for the Name field on the Account Record.”
When evaluating the snippet of line 19 that says {!acc.name}, we’ll find that by changing everything that comes after the “.” and before the “}”, we can change what field is being made available for editing. For example, if I wanted to change this from a column where the Name field could be edited, to one where the Account Site field could be edited, I’d simply replace “Name” with the API name for the Account Site field (Site). Line 19 would then look like this:
<apex:inputField value=”!acc.Site}/>
Line 20: This is what’s called a Closing Tag. Every opening tag must have a closing tag. How do we know it’s a closing tag? Let’s look at an opening tag and a closing tag right next to each other.
Opening: <apex:column headerValue="Name"> Closing: </apex:column>
The closing tag has a “/” just after the “<“.
If you haven’t gathered this already, the only reason the Visualforce page’s code is so long, is because it’s creating the blueprint for seven editable fields (columns):
- Account Name
- Annual Revenue
- Rating
- Industry
- Phone
- Type
- Description
Using what we’ve gone through already, look to see how I’ve modified the Visualforce page below. You should see that I’ve changed the editable fields (columns) to:
- Website
- Account Name
- Account Site
- Owner
- Record Type
- Fax
- Parent Account
1. <apex:page standardController="Account" recordSetVar="unused" sidebar="false"> 2. <apex:includeScript value="{!$Resource.UtilJS}" /> 3. <apex:form > 4. <apex:pageBlock > 5. <apex:pageMessages /> 6. <apex:pageBlock > 7. Note: All modifications made on the page will be lost if Return button is clicked without clicking the Save button first. 8. </apex:pageBlock> 9. <apex:pageBlockButtons > 10. <apex:commandButton value="Save" action="{!save}"/> 11. <apex:commandButton value="Return" action="{!cancel}"/> 12. </apex:pageBlockButtons> 13. 14. 15. <apex:pageBlockTable value="{!selected}" var="acc" id="table"> 16. 17. 18. <apex:column headerValue="Website"> 19. <apex:inputField value="{!acc.Website}"/> 20. </apex:column> 21. 22. 23. <apex:column headerValue="Account Name"> 24. <apex:inputField value="{!acc.Name}"/> 25. </apex:column> 26. 27. 28. <apex:column headerValue="Account Site"> 29. <apex:inputField value="{!acc.Site}"/> 30. </apex:column> 31. 32. 33. <apex:column headerValue="Account Owner"> 34. <apex:inputField value="{!acc.Owner}"/> 35. </apex:column> 36. 37. 38. <apex:column headerValue="Record Type"> 39. <apex:inputField value="{!acc.RecordType}"/> 40. </apex:column> 41. 42. 43. <apex:column headerValue="Fax"> 44. <apex:inputField value="{!acc.Fax}"/> 45. </apex:column> 46. 47. 48. <apex:column headerValue="Parent Account"> 49. <apex:inputField value="{!acc.Parent}"/> 50. </apex:column> 51. 52. 53 </apex:pageBlockTable> 54. </apex:pageBlock> 55. </apex:form> 56. </apex:page>
Alright, click Edit and see what kind of damage you can do! You are, after all, in your sandbox or dev environment, right?
Need more columns? Add another group of three lines!
Need fewer columns? Get rid of one or more groups of three lines!
Once you have the fields (columns) you need in place on your Visualforce page, it’s time to put it to action. And please… PLEASE hit Save before you navigate away from it.
- Add the Mass Edit button to your List View for Accounts.
- Navigate to your Accounts tab
- Verify the Mass Edit button it there
- Select a View
- Check the boxes next to a few rows
- Click Mass Edit
The next screen you see should show all fields (columns) from all selected Records.
In closing… don’t forget to make sure that all those that need to use this handy dandy new bit of functionality have been given permission to do so. Depending on the selections you made during the installation process, you may need to create a Permission Set in order to grant access to this functionality.
Good luck!
Thanks,
Ben
While I hope all who end up on this page can take away from it something truly useful… implementing the functionality detailed herein is done at your own risk. I’m happy to help out as always, but won’t be held accountable for any negative outcomes that may be associated with your experimentation. On the other hand, please let me know if this helped you out 🙂
Clear and informative, not everything worked. But the end results was achieved. Thank you for making me smart.
Hi ,
Can you explain what does line 15 do? And how do I process the selected records in the backend. For my business requirements I need those values in the Apex controller. I have customized the page and added picklist on the page. Need your help on this. Thanks!!
Hi Maggie,
Sorry for the delayed response to your question. I had to step away from my site for a while and focus on other things.
Line 15 is a tag for the body of the page being rendered. Here’s what Salesforce’s documentation says:
The body of the contains one or more column components that specify what information should be displayed for each item of data, similar to a table. Unlike the component, the default styling for matches standard Salesforce styles. Any additional styles specified with attributes are appended to the standard Salesforce styles.
Regarding your question about how to reference the selected List View items in a different controller, that I can be of little help with as I’m not a developer. Two things:
1.) Post this same question, along with your modified page code, to the Developer Community. They’re awesome. They’re brilliant. They’re more than willing (and able) to help!
2.) If I were to take a stab at this… I’d say the values that get populated in the pageBlockTable are generated by the script referenced in line 2.
If you’re able to get the answers you’re looking for, if you would, please come back and drop a link to the Developer Community forum page containing them. I’m sure you’re not the only one who would be able to benefit from them 🙂