Created
November 21, 2012 21:28
-
-
Save ralphcallaway/4127887 to your computer and use it in GitHub Desktop.
Massive Internal View State (file extensions changed to assist with language auto-detection) See http://salesforce.stackexchange.com/questions/4537/how-to-reduce-a-large-internal-view-state-what-is-in-the-internal-view-state for related discussion
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* NB: Class has been edited for brevity and may not compile initially */ | |
public with sharing class AccountView { | |
// Input Properties | |
public String filter1 { get; set; } | |
public String grouping1 { get; set; } | |
public String grouping2 { get; set; } | |
// Select Lists | |
public List<SelectOption> filter1Options { get; private set; } | |
public List<SelectOption> groupingOptions { get; private set; } | |
// Results | |
public List<Result> results { get; set; } { results = new List<Result>(); } | |
/* Constructor */ | |
public AccountView() { } | |
/* Action Functions */ | |
public PageReference doSelect() { | |
List<String> accountIds = getSelected(results); | |
/* Pass ids to the next page, section edited for brevity */ | |
return nextPage; | |
} | |
public void doUpdate() { | |
buildResults(getAccounts()); | |
} | |
/* Support Functions */ | |
private void buildResults(List<Account> accounts) { | |
// collect groupings | |
List<Grouping> groupings = new List<Grouping>(); | |
if(grouping1 != NONE_OPTION) | |
groupings.add(new Grouping(grouping1)); | |
if(grouping2 != NONE_OPTION) | |
groupings.add(new Grouping(grouping2)); | |
// group results | |
results = groupResults(groupings, accounts, existing); | |
} | |
private List<Account> getAccounts() { | |
String queryString = 'select **** from account where id != null'; | |
/* Build up query string based on selected filters */ | |
return Database.query(queryString); | |
} | |
// recursive get selected | |
private List<String> getSelected(List<Result> input) { | |
List<String> accountIds = new List<String>(); | |
for(Result row : input) { | |
if(!row.isGrouping && row.selected) { | |
accountIds.add(row.recordId); | |
} else if(row.isGrouping) { | |
accountIds.addAll(getSelected(row.children)); | |
} | |
} | |
return accountIds; | |
} | |
/* Grouping Functions */ | |
// recurse starter | |
private static List<Result> groupResults(List<Grouping> groupings, List<Account> inputList, Set<Id> existing) { | |
List<Result> outputList = new List<Result>(); | |
for(Account input : inputList) { | |
Result output = new Result(input); | |
if(existing.contains(input.id)) { | |
output.disabled = true; | |
output.selected = true; | |
} | |
outputList.add(output); | |
} | |
return groupResults(groupings, outputList); | |
} | |
// recursive processes selected grouping | |
private static List<Result> groupResults(List<Grouping> groupings, List<Result> inputList) { | |
// base case, just return the list without doing anything | |
if(groupings.isEmpty()) return inputList; | |
// pop next grouping | |
Grouping grouping = groupings[0]; | |
groupings.remove(0); | |
// group results | |
Map<String, Result> resultMap = new Map<String, Result>(); | |
for(Result input : inputList) { | |
Account account = input.record; | |
String label; | |
if(grouping.isLookup) { | |
label = (String) DynamicDMLHelper.recursiveGet(account, grouping.labelField); | |
} else { | |
label = (String) account.get(grouping.labelField); | |
} | |
if(label == null) { | |
label = BLANK_VALUE; | |
} | |
label = grouping.displayLabel + GROUP_NAME_SEPARATOR + label; | |
String value = (String) account.get(grouping.valueField); | |
if(value == null) { | |
value = BLANK_VALUE; | |
} | |
if(!resultMap.containsKey(value)) { | |
resultMap.put(value, new Result(label)); | |
} | |
resultMap.get(value).children.add(input); | |
} | |
// flatten into grouping results | |
List<Result> outputList = new List<Result>(); | |
List<String> sortedGroupings = new List<String>(); | |
sortedGroupings.addAll(resultMap.keySet()); | |
sortedGroupings.sort(); | |
for(String sortedGrouping : sortedGroupings) { | |
outputList.add(resultMap.get(sortedGrouping)); | |
} | |
// recurse on remaining groupings | |
for(Result output : outputList) { | |
output.children = groupResults(groupings.clone(), output.children); | |
} | |
// return result | |
return outputList; | |
} | |
/* Inner Classes */ | |
private class Grouping { | |
// valueField = labelField for non lookup fields | |
String valueField; // field to look for value of grouping (e.g. parentId for parent account) | |
String labelField; // field to look for the label of the grouping (e.g parent.name for parent account) | |
String displayLabel; // label of the field for grouping (e.g. "Ownership Company" for ownership_company__c) | |
Boolean isLookup; // true if an id field | |
Grouping(String fieldApiName) { | |
fieldApiName = fieldApiName.toLowerCase(); // make the field api name case-insensitive | |
valueField = fieldApiName; | |
Schema.DescribeFieldResult fieldDescribe = accountFields.get(fieldApiName).getDescribe(); | |
displayLabel = fieldDescribe.getLabel(); | |
isLookup = fieldDescribe.getSOAPType() == Schema.SOAPType.ID; | |
if(isLookup) { | |
// "parentId" => "parent.name" | |
// "brand__c" => "brand__r.name" | |
labelField = fieldApiName.replaceAll('__c$','__r.name').replaceAll('id$','.name'); | |
} else { | |
labelField = fieldApiName; | |
} | |
} | |
} | |
public Class Result { | |
public List<Result> children { get; private set; } | |
public Boolean disabled { get; private set; } { disabled = false; } | |
public Id recordId { get; private set; } | |
public Boolean isGrouping { get; private set; } | |
public String name { get; private set; } | |
public transient Account record { get; private set; } | |
public Boolean selected { get; set; } { selected = false; } | |
public Result(String name) { | |
this.name = name; | |
children = new List<Result>(); | |
isGrouping = true; | |
} | |
public Result(Account record) { | |
this(record.name); | |
this.record = record; | |
recordId = record.id; | |
isGrouping = false; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<apex:page controller="AccountView" tabstyle="Account" title="Account View"> | |
<apex:form > | |
<apex:pageBlock > | |
<!-- Filters for selecting accounts --> | |
<apex:facet name="header"> | |
<apex:outputPanel layout="block"> | |
<apex:panelGrid columns="3"> | |
<apex:panelGroup > | |
<apex:outputLabel for="filter1" value="Filter 1: "/> | |
<apex:selectList id="filter1" value="{!filter1}" size="1"> | |
<apex:selectOptions value="{!filter1Options}"/> | |
</apex:selectList> | |
</apex:panelGroup> | |
<!-- Additional Filters Excluded for Brevity --> | |
<!-- Results can be grouped in up to twol levels to better organize results and simplify selecting large numbers of accounts --> | |
<apex:panelGroup > | |
<apex:outputLabel for="grouping1" value="Grouping 1: "/> | |
<apex:selectList id="grouping1" value="{!grouping1}" size="1"> | |
<apex:selectOptions value="{!groupingOptions}"/> | |
</apex:selectList> | |
</apex:panelGroup> | |
<apex:panelGroup > | |
<apex:outputLabel for="grouping2" value="Grouping 2: "/> | |
<apex:selectList id="grouping2" value="{!grouping2}" size="1"> | |
<apex:selectOptions value="{!groupingOptions}"/> | |
</apex:selectList> | |
</apex:panelGroup> | |
</apex:panelGrid> | |
<apex:outputPanel layout="block" style="padding-top: 10px;"> | |
<apex:commandButton value="Update Filters" action="{!doUpdate}" /> | |
<apex:commandButton value="Select Accounts" action="{!doSelect}"/> | |
</apex:outputPanel> | |
</apex:outputPanel> | |
</apex:facet> | |
<apex:outputPanel layout="block"> | |
<table class="list" style="border-collapse: collapse; width: 99%;"> | |
<tr class="headerRow"> | |
<td>Select</td> | |
<td>Name</td> | |
<td>Field 1</td> | |
<!-- Additional Fields excluded for brevity --> | |
</tr> | |
<!-- Level 1 Repeat --> | |
<apex:repeat value="{!results}" var="resLev1"> | |
<tr> | |
<!-- Level 1 Group --> | |
<apex:outputPanel rendered="{!resLev1.isGrouping}"> | |
<apex:outputPanel layout="none"> | |
<td><input type="checkbox" onclick="javascript:(stuff to check all boxes in group)"/></td> | |
</apex:outputPanel> | |
<td colspan="3" class="grouping">{!resLev1.name} ({!resLev1.children.size})</td> | |
</apex:outputPanel> | |
<!-- Level 1 Results (displayed if no grouping) --> | |
<apex:outputPanel rendered="{!NOT(resLev1.isGrouping)}"> | |
<apex:outputPanel layout="none" rendered="{!displaySelection}"> | |
<td><apex:inputCheckbox value="{!resLev1.selected}"/></td> | |
</apex:outputPanel> | |
<td> | |
<apex:outputLink value="{!URLFOR($Action.Account.View, resLev1.record.id)}" target="_blank"> | |
{!resLev1.name} | |
</apex:outputLink> | |
</td> | |
<td><apex:outputField value="{!resLev1.record.field1__c}"/></td> | |
<!-- Additional Fields excluded for brevity --> | |
</apex:outputPanel> | |
</tr> | |
<!-- Level 2 Repeat --> | |
<apex:repeat value="{!resLev1.children}" var="resLev2"> | |
<tr> | |
<!-- Level 2 Group --> | |
<apex:outputPanel rendered="{!resLev2.isGrouping}"> | |
<td colspan="3" class="grouping">{!resLev2.name} ({!resLev2.children.size})</td> | |
</apex:outputPanel> | |
<!-- Level 2 Results (displayed if only one grouping) --> | |
<apex:outputPanel rendered="{!NOT(resLev2.isGrouping)}"> | |
<td><apex:inputCheckbox value="{!resLev2.selected}"/></td> | |
<td> | |
<apex:outputLink value="{!URLFOR($Action.Account.View, resLev2.record.id)}" target="_blank"> | |
{!resLev2.name} | |
</apex:outputLink> | |
</td> | |
<td><apex:outputField value="{!resLev2.field1__c}"/></td> | |
<!-- Additional Fields excluded for brevity --> | |
</apex:outputPanel> | |
</tr> | |
<!-- Level 3 Repeat --> | |
<apex:repeat value="{!resLev2.children}" var="resLev3"> | |
<tr> | |
<!-- Level 3 Result (can only group to two levels) --> | |
<td><apex:inputCheckbox value="{!resLev3.selected}"/></td> | |
<td> | |
<apex:outputLink value="{!URLFOR($Action.Account.View, resLev3.record.id)}" target="_blank"> | |
{!resLev3.name} | |
</apex:outputLink> | |
</td> | |
<td><apex:outputField value="{!resLev3.field1__c}"/></td> | |
</tr> | |
</apex:repeat> | |
</apex:repeat> | |
</apex:repeat> | |
</table> | |
</apex:outputPanel> | |
</apex:pageBlock> | |
</apex:form> | |
</apex:page> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment