Leverage StandardSetController in Apex and Visualforce


Published on

1 Like
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Leverage StandardSetController in Apex and Visualforce

  1. 1. Leverage StandardSetController inApex and VisualforceDeveloper Track 2012Nebojsa (Nash) Zgonjanin, CRM DeveloperOnPath Ottawa, Ontario, Canada (www.onpath.com)Nebojsa.zgonjanin@onpath.com@Nzgonca.linkedin.com/in/nashzgonjanin
  2. 2. Abstract• Do you use list view filters?• Would you like to use that same logic in your Visualforce pages?• Don’t reinvent the wheel• Save time, and make your admin happier as well
  3. 3. Nebojsa (Nash) Zgonjanin CRM Developer • Salesforce MVP (winter 2012), • Salesforce developer more than 6 years, • Senior developer (MS .NET) more than 15 years, • Work for www.OnPath.com, Ottawa, Ontario, Canada
  4. 4. Session Objectives• StandardSetController and List View Filter Criteria (logic)• jQuery Table Sort and Visualforce page• Hierarchy Custom Setting used to control functionality per org (profile or user level)• Demo ”Add to Campaigns” of implemented technology
  5. 5. Session Objectives• Short live demo of application to familiarize audience with topic• Use of Eclipse to browse code and point to key moments• Code in PPT presentation is used as reference
  6. 6. Solution Intro I• StandardSetController and List View Filter Criteria• Define StandardSetController (SOQL query)• Apply Filter Criteria from List View to StandardSetController• Execute SOQL and use in Apex code
  7. 7. Solution Intro IIjQuery Table Sort and Visualforce Page• jQuery Setting • Static resources • <apex:includeScript>• Mash up of: • standard HTML table tags • <apex:repeat> tag • jQuery <script> code
  8. 8. Solution Intro IIIHierarchy Custom Settings (Levels of use)• Org default• Profile (group of users)• User (individual)• Use of setting values in Apex code• Use of setting values in Visual Force page• Demo: User (Serbian) vs. Org Default (English)
  9. 9. Nash Code sample (package) available here:https://github.com/nzgonjanin/Dreamforce2012 Thank You
  10. 10. Nebojsa (Nash) Zgonjanin, CRM DeveloperOnPath Ottawa, Ontario, Canada (www.onpath.com)Nebojsa.zgonjanin@onpath.com@Nzgonca.linkedin.com/in/nashzgonjanin
  11. 11. Solution intro I always wanted to leverage platform functionality and addmore of client side functionality that browser bring in game. Combination of APEX controller extension and standardcontrollers (ApexPages.StandardController andApexPages.StandardSetController) give me option to leverage standardplatform functionality and add more flexibility and user interfacefunctionality to Visual Force page using jQuery Table sorter(jquery.tablesorter.min.js) add on, that enable sorting of multiplecolumns. Using Custom setting I made available different set ofparameters to be used per Org; Profile or User (labels, list views forfiltering, Error Messages…) that enable easy internationalization ifneeded.
  12. 12. Objectives and Solution I What is the Add to Campaigns app Salesforce.com provides features for adding many people to asingle campaign, but what about an organization that managesmultiple, ongoing campaigns like newsletters, customer programs,annual events, and even holiday card lists? Manually adding a single person to multiple campaigns one byone is a pain, and contributes to poor adoption, and incomplete orunusable data. This app application in salesforce.com allows users to add asingle contact or lead to multiple campaigns with as few clicks aspossible.
  13. 13. Objectives and Solution II There are two portions to this application: end-user and administrator (non-developer). NOTE: Custom Settings, Standard List View filter, Standard Controller,StandardSetController are used to give end user (administrator) flexibility to manage dataset used for app in combination with visual force pageADDTOCAMPAIGNS_LISTVIEWFILTER or using standard List View management underCampaigns tab. The end-user portion of the application works the same for both contacts andleads. Add a custom button to the Campaign History related list for both Leads andContacts called "Add to Campaigns". When the end-user clicks this button display a list ofcampaigns with check boxes and a "check all" option. (The query for the list of campaignswill be determined in the administrator portion of the application.) When the end-usersubmits the form, insert the contact/lead to the campaign as member with the defaultstatus for that campaign and return the user back to the standard contact/lead detailspage.
  14. 14. APEX controller extension (addtocampaigns_Extension.cls I )public with sharing class addtocampaigns_Extension {//variables used on Visual force page for interaction with end userpublic Lead ParticipantLead {get; set;} //Lead record returned based on Id (pid) query parameter from custom buttonpublic Contact ParticipantContact {get; set;} //Contact record returned based on Id (pid) query parameter from custombuttonpublic string ParticipantId {get;set;} //Value of Query parameter pidpublic list<addtocampaigns_Wrapper> Campaign_List=new list<addtocampaigns_Wrapper>(); //List of campaign recordsto be used for selectionpublic Boolean SubmitDisabled {get;set;} //[Submit] button and [Select All] button can be used just onespublic AddtoCampaignsSetting__c mySetting {get; set;} //Custom Setting for logged userpublic addtocampaigns_Extension(ApexPages.StandardController controller) { //Standard controller extensin used to add custom functionality to visual force page ParticipantId=System.currentPageReference().getParameters().get(pid); mySetting=AddtoCampaignsSetting__c.getInstance();//Custom Setting Definitions getParticipant(); //get Participant data from Lead or Contact getCampaign_List();//get list for campaign selection}
  15. 15. APEX controller extensionpublic ApexPages.StandardSetController con { (addtocampaigns_Extension.cls II) //Standard Set controller used to add custom functionality to visual force page //and leverage standard behavior of List View filters get { if(con == null) { //Standard set controller query used to retrieve data from Campaign object //used on visual force page to select potential campaigns integer myLimit=integer.valueOf(mySetting.RecordSet_Limit__c); if (myLimit==null){ myLimit=200; } con = new ApexPages.StandardSetController(Database.getQueryLocator( [Select Id, Name, StartDate,EndDate, Type, Status, ParentId, RecordTypeId FROM Campaign order By Name,StartDate limit :myLimit])); //in order to use it again you need to refresh page or go back to participant and start again //set filter id that is applied for Hierarchy setting Org/Profile/User if (mySetting.ListViewId__c!=null){ //Filter Magic is heppening here con.setPageSize(myLimit); con.setFilterID(mySetting.ListViewId__c); } } return con; } set;}
  16. 16. APEX controller extension//Queried data set is used to laverage data set (addtocampaigns_Extension.cls III)public List<addtocampaigns_Wrapper> getCampaign_List() { //get list for campaign selection if (Campaign_List.Size()==0){ //Load campign list just ones on first page load //(List<Campaign>)con.getRecords()) will execute query and //apply defined mySetting.ListViewId__c as filter to set of records for (Campaign camp: (List<Campaign>)con.getRecords()){ Campaign_List.add(new addtocampaigns_Wrapper(camp)); //check if participant is already part of campaign and disable it for selection if (ParticipantId.startsWith(00Q)){ //process lead campaign member records for (CampaignMember CM :ParticipantLead.CampaignMembers){ if (CM.CampaignId==camp.Id && Campaign_List.Size()>0){ //disable check box on visual force page Campaign_List[Campaign_List.size()-1].disabled=true; break; } } }else{ //process contact campaign member records for (CampaignMember CM :ParticipantContact.CampaignMembers){ if (CM.CampaignId==camp.Id && Campaign_List.Size()>0){ //disable check box on visual force page Campaign_List[Campaign_List.size()-1].disabled=true; break; } } } } } return Campaign_List;}
  17. 17. Addtocampaigns_Wrapper.cls (used in APEX controller extension to support app functionality)public with sharing class addtocampaigns_Wrapper { //variables used for creating add to Campaigns record public String message{ get; set; } //success message public Boolean checked{ get; set; } //check box for selection public Boolean disabled {get; set;} //if member is alread part of campaign selection check box is disabled public Campaign camp { get; set;} //Campaign record returned as part of data set driven by listView filter public addtocampaigns_Wrapper(){ //constructor without passed parameters camp = new Campaign(); checked = false; disabled = false; message=; } public addtocampaigns_Wrapper(Campaign c){ //constructor with passed parameters camp = c; checked = false; disabled = false; message=; }}//end of class
  18. 18. Visual Force Page code overview (addtocampaigns_ListViewFilter.page)<apex:page standardController="Campaign" tabStyle="Campaign" standardStylesheets="true"> <apex:sectionHeader title="Cloudspokes" subtitle="{!$Setup.AddtoCampaignsSetting__c.Header_Subtitle__c}"/> <apex:enhancedList height="300" rowsPerPage="100" listId="{!$Setup.AddtoCampaignsSetting__c.ListViewId__c}" id="CampaignsList" customizable="True" /></apex:page>
  19. 19. Visual Force Page code overview (addtocampaigns.page I)<apex:page standardController="Campaign" extensions="addtocampaigns_Extension" tabStyle="Campaign" standardStylesheets="true"> <!-- jQuery plug in for table sort my multiple columns --> <apex:includeScript value="{!URLFOR($Resource.jQuery_TableSort, jquery-latest.js)}" /> <apex:includeScript value="{!URLFOR($Resource.jQuery_TableSort, jquery.tablesorter.min.js)}" /> <apex:stylesheet value="{!URLFOR($Resource.jQuery_TableSort , /themes/blue/style.css)}" /><script>$j = jQuery.noConflict();$j(document).ready(function() { $j("#myTable").tablesorter( {sortList: [[1,0], [2,1]]} ); } );</script> <apex:sectionHeader title="Cloudspokes" subtitle="{!$Setup.AddtoCampaignsSetting__c.Header_Subtitle__c}"/> <apex:form > <apex:pageBlock id="CampaignMember" mode="detail"> <apex:pageBlockButtons > <apex:commandButton id="Back" action="{!GoToParticipant}“ value="{!$Setup.AddtoCampaignsSetting__c.button_Back_Label__c}" /> <apex:commandButton id="SelectAll" action="{!SelectAll}" value="{!$Setup.AddtoCampaignsSetting__c.button_SelectAll_Label__c}" disabled="{!SubmitDisabled}"/> <apex:commandButton id="Submit" action="{!Submit}" value="{!$Setup.AddtoCampaignsSetting__c.button_Submit_Label__c}" styleClass="btnImportant" disabled="{!SubmitDisabled}"/> <apex:commandLink id="FilterSetting" action="{!FilterSetting}" target="_blank" value="Filter Settings" />
  20. 20. Visual Force Page code overview (addtocampaigns.page II)//Lead Section <apex:pageBlockSection title="{!$Setup.AddtoCampaignsSetting__c.pageBlockSection_Lead__c}" columns="2" showHeader="true" collapsible="false" rendered="{!if(ParticipantLead.Id==null,false,true)}"> <apex:outputField id="LeadFirstName" value="{!ParticipantLead.FirstName}" /> <apex:outputField id="LeadCompany" value="{!ParticipantLead.Company}" /> <apex:outputField id="LeadLastName" value="{!ParticipantLead.LastName}" /> <apex:outputField id="LeadEmail" value="{!ParticipantLead.Email}" /> </apex:pageBlockSection>//Contact section <apex:pageBlockSection title="{!$Setup.AddtoCampaignsSetting__c.pageBlockSection_Contact__c}" columns="2" showHeader="true" collapsible="false“ rendered="{!if(ParticipantContact.Id==null,false,true)}"> <apex:outputField id="ContactFirstName" value="{!ParticipantContact.FirstName}" /> <apex:outputField id="ContactCompany" value="{!ParticipantContact.Account.Name}" /> <apex:outputField id="ContactLastName" value="{!ParticipantContact.LastName}" /> <apex:outputField id="ContactEmail" value="{!ParticipantContact.Email}" /> </apex:pageBlockSection>//Select campaigns section that mix jQuery (client side) and APEX server side functionality <apex:pageBlockSection title="{!$Setup.AddtoCampaignsSetting__c.pageBlockSection_Campaigns__c}" columns="1" showHeader="true" > {!$Setup.AddtoCampaignsSetting__c.Note__c} </apex:pageBlockSection>
  21. 21. Visual Force Page code overview (addtocampaigns.page III)//standard HTML table tags used with apex:repeat tag to obtain data set<table id="myTable" class="tablesorter"> <thead> //table headers <tr> <th>{!$Setup.AddtoCampaignsSetting__c.column_Select_Header__c}</th> <th>{!$Setup.AddtoCampaignsSetting__c.column_Name_Header__c}</th> <th>{!$Setup.AddtoCampaignsSetting__c.column_StartDate_Header__c}</th> <th>{!$Setup.AddtoCampaignsSetting__c.column_EndDate_Header__c}</th> <th>{!$Setup.AddtoCampaignsSetting__c.column_Type_Header__c}</th> <th>{!$Setup.AddtoCampaignsSetting__c.column_Status_Header__c}</th> <th>Parent</th> <th>Record Type</th> </tr> </thead> <tbody> //table rows (data set from list view) <apex:repeat value="{!Campaign_List}" var="Camp" id="theRepeat"> <tr> <td> <apex:inputCheckbox id="Selected" value="{!Camp.checked}" disabled="{!Camp.disabled}"/></td> <td> <apex:outputField id="Name" value="{!Camp.Camp.Name}"/></td> <td> <apex:outputField id="StartDate" value="{!Camp.Camp.StartDate}"/></td> <td> <apex:outputField id="EndDate" value="{!Camp.Camp.EndDate}"/></td> <td> <apex:outputField id="Type" value="{!Camp.Camp.Type}"/></td> <td><apex:outputField id="Status" value="{!Camp.Camp.Status}"/></td> <td><apex:outputField id="Parent" value="{!Camp.Camp.ParentId}"/></td> <td><apex:outputField id="RecordType" value="{!Camp.Camp.RecordTypeId}"/></td> </tr>
  22. 22. Custom Setting Hierarchy type overviewHierarchy Custom Settings: A type of custom setting that uses a built-in hierarchical logic that lets you “personalize” settings for specific profiles or users. The hierarchy logicchecks the organization, profile, and user settings for the current user and returns the most specific, or “lowest,” value. In the hierarchy, settings for an organization areoverridden by profile settings, which, in turn, are overridden by user settings.https://na14.salesforce.com/help/doc/user_ed.jsp?loc=help&target=cs_manage_data.htm&section=integrate