SlideShare uma empresa Scribd logo
1 de 33
Baixar para ler offline
Building multi-page data entry
Controllers
Beyond Oz What to do when a simple Wizard is not enough
Stuart Greenberg, OppenheimerFunds, Inc., Technical Lead
@Stu_GuiGumdrops
All about OppenheimerFunds, Inc.
Since the original Oppenheimer fund was first offered to the public in 1959, OppenheimerFunds,
Inc. (OFI) has grown into one of the largest and most reputable investment management firms in
Click to Today, a subsidiary of Massachusetts Mutual Life Insurance Company
the country. add brief company overview here. Lorem ipsum
(MassMutual), OFI and its subsidiaries adipiscing elit. Sed lectusservices to individuals,
dolor sit amet, consectetur offer a broad array of products and tortor,
institutional investors and corporations worldwide. OFI provides advisory services to the
Oppenheimer mutual funds and OFI Global Asset Management provides services to institutional
pulvinar sit amet blandit ac, bibendum vitae sapien.
clients. OFI, including subsidiaries, managed more than $222 billion in assets for more than 12
million shareholder accounts, including sub-accounts, as of September 30, 2013.

▪ Click to add implementation highlights; no more than four
For more than 50 years, OFI has embraced an investment culture that has produced results, is
sustainable, and reflects its commitment to being effective stewards of capital. A high conviction
▪ Click to add implementation highlights; no more than four. Lorem
asset manager, OFI has a history of providing innovative investment strategies to its investors.
Fouripsum dolor sit amet, consecteturinvestment culture: active management can deliver
core beliefs lie at the heart of the OFI adipiscing elit.
better outcomes, independent investment boutiques lead to better ideas, a global perspective is
critical, and knowing the difference between risk & no more than four
▪ Click to add implementation highlights; risky.
OFI’s investment professionals are a collection of distinct, yet collaborative, teams built to enable
▪ Click to add implementation highlights; no more than four
a free exchange of ideas and to uncover opportunity wherever it lies; even where others see a
disparate set of facts, events or trends. OFI is redefining what the world can expect from an asset
manager, and stands united on its mission to turn its unconventional wisdom into value for
investors.
Who’s who and what’s what
Stuart Greenberg
▪
▪
▪
▪

Professional programmer since 1975
Past Senior Programmer, PC Magazine Labs
Currently Tech Lead, OppenheimerFunds, Inc.
Pennsylvania Railroad engineer

And you?
▪ Visualforce developer?
▪ Written wizards or multi-page data entry?
▪ It’s late, all the other sessions were full
and I just wanted to sit down?
Single vs. wizard vs. multi-page data entry
Single page
▪ Enter data / click save
Single vs. wizard vs. multi-page data entry
Wizard
▪ Enter data for step 1 / click next
▪ Enter data for step 2 / click next
▪ Etc.
Single vs. wizard vs. multi-page data entry
Multi-page
▪ Enter data on main page / click option
▪ Select option / Enter data on new page / click return
▪ Select option / Enter data on another page / click return
▪ Click save
The problem
▪ Break the limit of one Contact/Lead and/or one other object
attached to Events and Tasks (Multi-Who / Multi-What)
▪ Allow users to select objects in any order and skip selection of
objects they don’t want
▪ Do not require the saving of Events and Tasks prior to
selecting objects
The solution
▪ Custom object (ActivitySidecar) connected to Events and
Tasks using the WhatId
▪ Selection pages for all associated objects
▪ Multi-page data entry to keep all data in memory and save at
the end
Object structure
Overall structure
Controllers must be the
same across pages.

Classes instantiated as needed.

Interfaces allow
polymorphic
functionality
DEMO
Gottas
Wachagottadew…
▪ Selections must be queued
▪ All queued data must be saved at the same time
▪ Page code must be setup correctly
Selectable Object
public class OFI_SelectableObject {
public Boolean isSelected {set;get;}
public Boolean isEnabled {set;get;}
public Boolean isInactive {set;get;}
public Boolean isPrimary {set;get;}
public String tag

{set;get;}

public Object obj

{set;get;}
Queueing selections
// Lists Selectable Objects of the related objects
// The tag property is used to indicate:
// an existing object (tag = '')
// an object to be added (tag = 'A')
// an object to be deleted (tag = 'D')
public List<OFI_SelectableObject> selProducts {get;set;}
public List<OFI_SelectableObject> selContacts {get;set;}
public List<OFI_SelectableObject> selFirms {get;set;}
public List<OFI_SelectableObject> selUsers {get;set;}
public List<OFI_SelectableObject> selFinancialAccounts {get;set;}
public List<OFI_SelectableObject> selOpportunities {get;set;}
public List<OFI_SelectableObject> selCampaigns {get;set;}
public List<OFI_SelectableObject> selCases {get;set;}
Selecting items
public PageReference selectItems() {
Integer i;
for (OFI_SelectableObject record: recordsToDisplay) {
if (record.isSelected) {
if (!existingContactIds.contains(record.getContact().Id)) {
// Not an existing selection
for (i = 0; i < currentSelections.size(); i++) {
// Check for undelete
if (currentSelections[i].getActivityContact().Contact__c == record.getContact().Id && currentSelections[i].tag == 'D') {
currentSelections[i].tag = '';
break;
}
}
if (i == currentSelections.size()) {
// Add new selection
Activity_Contact__c actContact = new Activity_Contact__c();
// Set the Contact Id and Object. The Sidecar will be set when the Activity is saved.
actContact.Contact__c = record.getContact().Id;
actContact.Contact__r = record.getContact();
OFI_SelectableObject selObj = new OFI_SelectableObject(actContact);
selObj.Tag = 'A';
currentSelections.add(selObj);
}
existingContactIds.add(record.getContact().Id);
}
}
}
return null;
}

// Add to existing Ids to enable checkmark
Saving
try {
upsert evt;
} catch (DMLException e) {
ApexPages.addMessage(new
ApexPages.Message(ApexPages.SEVERITY.ERROR,
e.getLineNumber() + e.getMessage()));
return false;
}
If (sidecarId == null) {
Activity_Sidecar__c sidecar = [SELECT Id FROM Activity_sidecar__c
WHERE Activity_Id__c = :evt.Id LIMIT 1];
evt.WhatId = sidecar.Id;
}

// Add / Delete Products
List<Activity_Product__c> delProds = new List<Activity_Product__c>();
List<Activity_Product__c> addProds = new List<Activity_Product__c>();
for (OFI_SelectableObject o : sidecarEditor.selProducts) {
if (o.tag == 'D') {
delProds.add(o.getActivityProduct
} else {
if (o.tag == 'A') {
o.getActivityProduct().Activity_Sidecar__c = evt.WhatId;
addProds.add(o.getActivityProduct());
}
}
}
if (delProds.size() > 0) {
delete(delProds);
}
if (addProds.size() > 0) {
insert(addProds);
}
Page code
Event Edit Page
<apex:page controller="ActivityEditPage2Controller" extensions="ActivityObjectSelController,VFFileUpload2"
title="Calendar Event Edit">

Task Edit Page

<apex:page controller="ActivityEditPage2Controller" extensions="ActivityObjectSelController,VFFileUpload2"
title="Calendar Task Edit">

Selection Page

<apex:page controller="ActivityEditPage2Controller" extensions="ActivityObjectSelController,VFFileUpload2"
action="{!initObjectSelector}" title="Activity Contact Selection">

▪ All controllers must be the same to keep their constructors
from being called when a new page is opened.
▪ An Action must be added if any initialization is necessary
when the page opens.
Force instantiation on new session
You need to use the following when you wish to start a new
multi-page session:
PageReference page = new PageReference('/apex/TaskEditPage');
page.setRedirect(true);
Gotchas
Gotchasgonnagetcha…
You can’t leave the page
The view state is maintained as long as the user doesn’t
navigate to a page that has a different set of controllers.
The solution: Javascript
Avoid the message on “Good” clicks
For example, the following was added to the Page Block Buttons:
<apex:pageBlockButtons location="top" >
<apex:commandButton value="Select and Return"
action="{!SelectAndReturn}"
onclick="setShowExitMessage(false);"/>
<apex:commandButton value="Select and Add More"
action="{!SelectItems}"
onclick="setShowExitMessage(false);" rerender="thePage"/>
<apex:commandButton value="Return" action="{!cancelSelection}"
onclick="setShowExitMessage(false);"/>
</apex:pageBlockButtons>
<script type="text/javascript">
var isExitMessageTurnedOn = true;
var showExitMessage = true;
var isChrome = false;
var isSafari = false;
var ua = navigator.userAgent.toLowerCase();
if (ua.indexOf('safari') != -1){
if(ua.indexOf('chrome') > -1){
isChrome = true;
} else {
isSafari = true;
}
}
function setShowExitMessage(val) {
showExitMessage = val;
}

function isJavascriptElement() {
if (isChrome || isSafari) return false;
Be careful using classes
▪ Classes called from the controllers can be instantiated
multiple times.
▪ Be sure to set the variables using the classes to null when
finished.
Example

Destroy Selectors after each access
Of a selection page.
Return URLs
▪ Do not use the Return URL to go back to the initial page.
▪ Use the URL of the page itself.
▪ For example:
// Cancel selection and return to the previous
page.
public pageReference cancelSelection() {
destroySelector();
if (mainController.isTask) {
return page.TaskEditPage2;
} else {
return page.EventEditPage2;
}
}
Fugetaboutits
Patient: Doc, it hurts when I do this.
Doctor: Don’t do that.
The View State size
▪ The View State is the data that is held between pages.
▪ Up to 135K of data.
▪ An exception is thrown if the limit is exceeded.
▪ Cannot hold attachments, for example.
Time outs
▪ Sessions sitting too long can be timed out and data lost.
▪ Use multi-page data entry only for quick tasks.
Alternatives
Use multi-page data entry when you really have to
Here are some alternatives:
▪ One page with hidden or collapsible sections
▪ A wizard flow based on initial selections
▪ Visual Workflow
▪ Dynamically generated search and select components
Conclusion
▪ Multi-page data entry is possible with the proper care
▪ Use multi-page data entry once you’ve exhausted more
mainstream options
▪ Nothing is impossible… Impossible just takes a bit longer
Contact info and links
Contact me at:
▪ Twitter: @Stu_GuiGumdrops
▪ Blog: http://www.guigumdrops.com

Useful links:
▪ View State:
http://wiki.developerforce.com/page/An_Introduction_to_Visualforce_View_State

▪ Visualforce and Visual Workflow:
http://wiki.developerforce.com/page/User_Interface
Stuart Greenberg
OppenheimerFunds, Inc.,
Technical Lead
@Stu_GuiGumdrops
Creating Multi-Page Data Entry Controllers

Mais conteúdo relacionado

Mais procurados

Adrotator in asp
Adrotator in aspAdrotator in asp
Adrotator in aspSireesh K
 
HTML5 Gaming Payment Platforms
HTML5 Gaming Payment PlatformsHTML5 Gaming Payment Platforms
HTML5 Gaming Payment PlatformsJonathan LeBlanc
 
Lyudmila Zharova: Developing Solutions for SharePoint 2010 Using the Client O...
Lyudmila Zharova: Developing Solutions for SharePoint 2010 Using the Client O...Lyudmila Zharova: Developing Solutions for SharePoint 2010 Using the Client O...
Lyudmila Zharova: Developing Solutions for SharePoint 2010 Using the Client O...SharePoint Saturday NY
 
Asp.net server controls
Asp.net server controlsAsp.net server controls
Asp.net server controlsRaed Aldahdooh
 
Offline strategies for HTML5 web applications - ConFoo13
Offline strategies for HTML5 web applications - ConFoo13Offline strategies for HTML5 web applications - ConFoo13
Offline strategies for HTML5 web applications - ConFoo13Stephan Hochdörfer
 
Presentation on asp.net controls
Presentation on asp.net controlsPresentation on asp.net controls
Presentation on asp.net controlsReshi Unen
 
Advanced SharePoint Web Part Development
Advanced SharePoint Web Part DevelopmentAdvanced SharePoint Web Part Development
Advanced SharePoint Web Part DevelopmentRob Windsor
 
The Chaos Tools Suite
The Chaos Tools SuiteThe Chaos Tools Suite
The Chaos Tools Suitemerlinofchaos
 
AtlasCamp 2015: Web technologies you should be using now
AtlasCamp 2015: Web technologies you should be using nowAtlasCamp 2015: Web technologies you should be using now
AtlasCamp 2015: Web technologies you should be using nowAtlassian
 
Adf performance tuning tips slideshare
Adf performance tuning tips slideshareAdf performance tuning tips slideshare
Adf performance tuning tips slideshareVinay Kumar
 
ADF - Layout Managers and Skinning
ADF - Layout Managers and SkinningADF - Layout Managers and Skinning
ADF - Layout Managers and SkinningGeorge Estebe
 
Introduction to the SharePoint 2013 REST API
Introduction to the SharePoint 2013 REST APIIntroduction to the SharePoint 2013 REST API
Introduction to the SharePoint 2013 REST APISparkhound Inc.
 
ADF Bindings & Data Controls
ADF Bindings & Data ControlsADF Bindings & Data Controls
ADF Bindings & Data ControlsRohan Walia
 
RichControl in Asp.net
RichControl in Asp.netRichControl in Asp.net
RichControl in Asp.netBhumivaghasiya
 
Salesforce Import Tools
Salesforce Import ToolsSalesforce Import Tools
Salesforce Import ToolsDoria Hamelryk
 
Tokyo React.js #3: Missing Pages: ReactJS/Flux/GraphQL/RelayJS
Tokyo React.js #3: Missing Pages: ReactJS/Flux/GraphQL/RelayJSTokyo React.js #3: Missing Pages: ReactJS/Flux/GraphQL/RelayJS
Tokyo React.js #3: Missing Pages: ReactJS/Flux/GraphQL/RelayJSKhor SoonHin
 
Building a custom Oracle ADF Component
Building a custom Oracle ADF ComponentBuilding a custom Oracle ADF Component
Building a custom Oracle ADF ComponentWilfred van der Deijl
 
Advanced SharePoint 2010 and 2013 Web Part Development by Rob Windsor - SPTec...
Advanced SharePoint 2010 and 2013 Web Part Development by Rob Windsor - SPTec...Advanced SharePoint 2010 and 2013 Web Part Development by Rob Windsor - SPTec...
Advanced SharePoint 2010 and 2013 Web Part Development by Rob Windsor - SPTec...SPTechCon
 

Mais procurados (20)

Adrotator in asp
Adrotator in aspAdrotator in asp
Adrotator in asp
 
HTML5 Gaming Payment Platforms
HTML5 Gaming Payment PlatformsHTML5 Gaming Payment Platforms
HTML5 Gaming Payment Platforms
 
Lyudmila Zharova: Developing Solutions for SharePoint 2010 Using the Client O...
Lyudmila Zharova: Developing Solutions for SharePoint 2010 Using the Client O...Lyudmila Zharova: Developing Solutions for SharePoint 2010 Using the Client O...
Lyudmila Zharova: Developing Solutions for SharePoint 2010 Using the Client O...
 
Asp.net server controls
Asp.net server controlsAsp.net server controls
Asp.net server controls
 
Offline strategies for HTML5 web applications - ConFoo13
Offline strategies for HTML5 web applications - ConFoo13Offline strategies for HTML5 web applications - ConFoo13
Offline strategies for HTML5 web applications - ConFoo13
 
Presentation on asp.net controls
Presentation on asp.net controlsPresentation on asp.net controls
Presentation on asp.net controls
 
Advanced SharePoint Web Part Development
Advanced SharePoint Web Part DevelopmentAdvanced SharePoint Web Part Development
Advanced SharePoint Web Part Development
 
The Chaos Tools Suite
The Chaos Tools SuiteThe Chaos Tools Suite
The Chaos Tools Suite
 
AtlasCamp 2015: Web technologies you should be using now
AtlasCamp 2015: Web technologies you should be using nowAtlasCamp 2015: Web technologies you should be using now
AtlasCamp 2015: Web technologies you should be using now
 
Adf performance tuning tips slideshare
Adf performance tuning tips slideshareAdf performance tuning tips slideshare
Adf performance tuning tips slideshare
 
Neo4j introduction
Neo4j introductionNeo4j introduction
Neo4j introduction
 
Controls in asp.net
Controls in asp.netControls in asp.net
Controls in asp.net
 
ADF - Layout Managers and Skinning
ADF - Layout Managers and SkinningADF - Layout Managers and Skinning
ADF - Layout Managers and Skinning
 
Introduction to the SharePoint 2013 REST API
Introduction to the SharePoint 2013 REST APIIntroduction to the SharePoint 2013 REST API
Introduction to the SharePoint 2013 REST API
 
ADF Bindings & Data Controls
ADF Bindings & Data ControlsADF Bindings & Data Controls
ADF Bindings & Data Controls
 
RichControl in Asp.net
RichControl in Asp.netRichControl in Asp.net
RichControl in Asp.net
 
Salesforce Import Tools
Salesforce Import ToolsSalesforce Import Tools
Salesforce Import Tools
 
Tokyo React.js #3: Missing Pages: ReactJS/Flux/GraphQL/RelayJS
Tokyo React.js #3: Missing Pages: ReactJS/Flux/GraphQL/RelayJSTokyo React.js #3: Missing Pages: ReactJS/Flux/GraphQL/RelayJS
Tokyo React.js #3: Missing Pages: ReactJS/Flux/GraphQL/RelayJS
 
Building a custom Oracle ADF Component
Building a custom Oracle ADF ComponentBuilding a custom Oracle ADF Component
Building a custom Oracle ADF Component
 
Advanced SharePoint 2010 and 2013 Web Part Development by Rob Windsor - SPTec...
Advanced SharePoint 2010 and 2013 Web Part Development by Rob Windsor - SPTec...Advanced SharePoint 2010 and 2013 Web Part Development by Rob Windsor - SPTec...
Advanced SharePoint 2010 and 2013 Web Part Development by Rob Windsor - SPTec...
 

Semelhante a Creating Multi-Page Data Entry Controllers

Making External Web Pages Interact With Visualforce
Making External Web Pages Interact With VisualforceMaking External Web Pages Interact With Visualforce
Making External Web Pages Interact With VisualforceSalesforce Developers
 
Scaling business app development with Play and Scala
Scaling business app development with Play and ScalaScaling business app development with Play and Scala
Scaling business app development with Play and ScalaPeter Hilton
 
Hi5 opensocial-code-lab-presentation-1203814696810018-3
Hi5 opensocial-code-lab-presentation-1203814696810018-3Hi5 opensocial-code-lab-presentation-1203814696810018-3
Hi5 opensocial-code-lab-presentation-1203814696810018-3Kunal Mittal
 
Lessons Learned: Migrating Tests to Selenium v2
Lessons Learned: Migrating Tests to Selenium v2Lessons Learned: Migrating Tests to Selenium v2
Lessons Learned: Migrating Tests to Selenium v2rogerjhu1
 
Opticon 2015 - Getting Started with the Optimizely Developer Platform
Opticon 2015 - Getting Started with the Optimizely Developer PlatformOpticon 2015 - Getting Started with the Optimizely Developer Platform
Opticon 2015 - Getting Started with the Optimizely Developer PlatformOptimizely
 
jQuery in the [Aol.] Enterprise
jQuery in the [Aol.] EnterprisejQuery in the [Aol.] Enterprise
jQuery in the [Aol.] EnterpriseDave Artz
 
Will your code blend? : Toronto Code Camp 2010 : Barry Gervin
Will your code blend? : Toronto Code Camp 2010 : Barry GervinWill your code blend? : Toronto Code Camp 2010 : Barry Gervin
Will your code blend? : Toronto Code Camp 2010 : Barry GervinBarry Gervin
 
Parsing in ios to create an app
Parsing in ios to create an appParsing in ios to create an app
Parsing in ios to create an appHeaderLabs .
 
Deck 8983a1d9-68df-4447-8481-3b4fd0de734c(1)
Deck 8983a1d9-68df-4447-8481-3b4fd0de734c(1)Deck 8983a1d9-68df-4447-8481-3b4fd0de734c(1)
Deck 8983a1d9-68df-4447-8481-3b4fd0de734c(1)Thinkful
 
Salesforce Admin Group-Barcelona-2022-07-05 In-person Meetup-BCN Admins Group
Salesforce Admin Group-Barcelona-2022-07-05 In-person Meetup-BCN Admins GroupSalesforce Admin Group-Barcelona-2022-07-05 In-person Meetup-BCN Admins Group
Salesforce Admin Group-Barcelona-2022-07-05 In-person Meetup-BCN Admins Groupanimuscrm
 
Week 8
Week 8Week 8
Week 8A VD
 
Hi5 Opensocial Code Lab Presentation
Hi5 Opensocial Code Lab PresentationHi5 Opensocial Code Lab Presentation
Hi5 Opensocial Code Lab Presentationplindner
 
JavaScript and DOM Pattern Implementation
JavaScript and DOM Pattern ImplementationJavaScript and DOM Pattern Implementation
JavaScript and DOM Pattern Implementationdavejohnson
 
Ditching JQuery
Ditching JQueryDitching JQuery
Ditching JQueryhowlowck
 
Tony Vitabile .Net Portfolio
Tony Vitabile .Net PortfolioTony Vitabile .Net Portfolio
Tony Vitabile .Net Portfoliovitabile
 
User Profiles: I Didn't Know I Could Do That?-Stacy Deere-Strole-SharePoint C...
User Profiles: I Didn't Know I Could Do That?-Stacy Deere-Strole-SharePoint C...User Profiles: I Didn't Know I Could Do That?-Stacy Deere-Strole-SharePoint C...
User Profiles: I Didn't Know I Could Do That?-Stacy Deere-Strole-SharePoint C...Stacy Deere
 
Effective Android Data Binding
Effective Android Data BindingEffective Android Data Binding
Effective Android Data BindingEric Maxwell
 

Semelhante a Creating Multi-Page Data Entry Controllers (20)

Making External Web Pages Interact With Visualforce
Making External Web Pages Interact With VisualforceMaking External Web Pages Interact With Visualforce
Making External Web Pages Interact With Visualforce
 
Scaling business app development with Play and Scala
Scaling business app development with Play and ScalaScaling business app development with Play and Scala
Scaling business app development with Play and Scala
 
Hi5 opensocial-code-lab-presentation-1203814696810018-3
Hi5 opensocial-code-lab-presentation-1203814696810018-3Hi5 opensocial-code-lab-presentation-1203814696810018-3
Hi5 opensocial-code-lab-presentation-1203814696810018-3
 
Lessons Learned: Migrating Tests to Selenium v2
Lessons Learned: Migrating Tests to Selenium v2Lessons Learned: Migrating Tests to Selenium v2
Lessons Learned: Migrating Tests to Selenium v2
 
Opticon 2015 - Getting Started with the Optimizely Developer Platform
Opticon 2015 - Getting Started with the Optimizely Developer PlatformOpticon 2015 - Getting Started with the Optimizely Developer Platform
Opticon 2015 - Getting Started with the Optimizely Developer Platform
 
jQuery in the [Aol.] Enterprise
jQuery in the [Aol.] EnterprisejQuery in the [Aol.] Enterprise
jQuery in the [Aol.] Enterprise
 
Will your code blend? : Toronto Code Camp 2010 : Barry Gervin
Will your code blend? : Toronto Code Camp 2010 : Barry GervinWill your code blend? : Toronto Code Camp 2010 : Barry Gervin
Will your code blend? : Toronto Code Camp 2010 : Barry Gervin
 
Playing With The Web
Playing With The WebPlaying With The Web
Playing With The Web
 
Parsing in ios to create an app
Parsing in ios to create an appParsing in ios to create an app
Parsing in ios to create an app
 
Deck 8983a1d9-68df-4447-8481-3b4fd0de734c(1)
Deck 8983a1d9-68df-4447-8481-3b4fd0de734c(1)Deck 8983a1d9-68df-4447-8481-3b4fd0de734c(1)
Deck 8983a1d9-68df-4447-8481-3b4fd0de734c(1)
 
Salesforce Admin Group-Barcelona-2022-07-05 In-person Meetup-BCN Admins Group
Salesforce Admin Group-Barcelona-2022-07-05 In-person Meetup-BCN Admins GroupSalesforce Admin Group-Barcelona-2022-07-05 In-person Meetup-BCN Admins Group
Salesforce Admin Group-Barcelona-2022-07-05 In-person Meetup-BCN Admins Group
 
Week 8
Week 8Week 8
Week 8
 
Count to 10 and Say Yes
Count to 10 and Say YesCount to 10 and Say Yes
Count to 10 and Say Yes
 
Hi5 Opensocial Code Lab Presentation
Hi5 Opensocial Code Lab PresentationHi5 Opensocial Code Lab Presentation
Hi5 Opensocial Code Lab Presentation
 
JavaScript and DOM Pattern Implementation
JavaScript and DOM Pattern ImplementationJavaScript and DOM Pattern Implementation
JavaScript and DOM Pattern Implementation
 
WP - Unit I.ppt
WP - Unit I.pptWP - Unit I.ppt
WP - Unit I.ppt
 
Ditching JQuery
Ditching JQueryDitching JQuery
Ditching JQuery
 
Tony Vitabile .Net Portfolio
Tony Vitabile .Net PortfolioTony Vitabile .Net Portfolio
Tony Vitabile .Net Portfolio
 
User Profiles: I Didn't Know I Could Do That?-Stacy Deere-Strole-SharePoint C...
User Profiles: I Didn't Know I Could Do That?-Stacy Deere-Strole-SharePoint C...User Profiles: I Didn't Know I Could Do That?-Stacy Deere-Strole-SharePoint C...
User Profiles: I Didn't Know I Could Do That?-Stacy Deere-Strole-SharePoint C...
 
Effective Android Data Binding
Effective Android Data BindingEffective Android Data Binding
Effective Android Data Binding
 

Mais de Salesforce Developers

Sample Gallery: Reference Code and Best Practices for Salesforce Developers
Sample Gallery: Reference Code and Best Practices for Salesforce DevelopersSample Gallery: Reference Code and Best Practices for Salesforce Developers
Sample Gallery: Reference Code and Best Practices for Salesforce DevelopersSalesforce Developers
 
Maximizing Salesforce Lightning Experience and Lightning Component Performance
Maximizing Salesforce Lightning Experience and Lightning Component PerformanceMaximizing Salesforce Lightning Experience and Lightning Component Performance
Maximizing Salesforce Lightning Experience and Lightning Component PerformanceSalesforce Developers
 
Local development with Open Source Base Components
Local development with Open Source Base ComponentsLocal development with Open Source Base Components
Local development with Open Source Base ComponentsSalesforce Developers
 
TrailheaDX India : Developer Highlights
TrailheaDX India : Developer HighlightsTrailheaDX India : Developer Highlights
TrailheaDX India : Developer HighlightsSalesforce Developers
 
Why developers shouldn’t miss TrailheaDX India
Why developers shouldn’t miss TrailheaDX IndiaWhy developers shouldn’t miss TrailheaDX India
Why developers shouldn’t miss TrailheaDX IndiaSalesforce Developers
 
CodeLive: Build Lightning Web Components faster with Local Development
CodeLive: Build Lightning Web Components faster with Local DevelopmentCodeLive: Build Lightning Web Components faster with Local Development
CodeLive: Build Lightning Web Components faster with Local DevelopmentSalesforce Developers
 
CodeLive: Converting Aura Components to Lightning Web Components
CodeLive: Converting Aura Components to Lightning Web ComponentsCodeLive: Converting Aura Components to Lightning Web Components
CodeLive: Converting Aura Components to Lightning Web ComponentsSalesforce Developers
 
Enterprise-grade UI with open source Lightning Web Components
Enterprise-grade UI with open source Lightning Web ComponentsEnterprise-grade UI with open source Lightning Web Components
Enterprise-grade UI with open source Lightning Web ComponentsSalesforce Developers
 
TrailheaDX and Summer '19: Developer Highlights
TrailheaDX and Summer '19: Developer HighlightsTrailheaDX and Summer '19: Developer Highlights
TrailheaDX and Summer '19: Developer HighlightsSalesforce Developers
 
Lightning web components - Episode 4 : Security and Testing
Lightning web components  - Episode 4 : Security and TestingLightning web components  - Episode 4 : Security and Testing
Lightning web components - Episode 4 : Security and TestingSalesforce Developers
 
LWC Episode 3- Component Communication and Aura Interoperability
LWC Episode 3- Component Communication and Aura InteroperabilityLWC Episode 3- Component Communication and Aura Interoperability
LWC Episode 3- Component Communication and Aura InteroperabilitySalesforce Developers
 
Lightning web components episode 2- work with salesforce data
Lightning web components   episode 2- work with salesforce dataLightning web components   episode 2- work with salesforce data
Lightning web components episode 2- work with salesforce dataSalesforce Developers
 
Lightning web components - Episode 1 - An Introduction
Lightning web components - Episode 1 - An IntroductionLightning web components - Episode 1 - An Introduction
Lightning web components - Episode 1 - An IntroductionSalesforce Developers
 
Migrating CPQ to Advanced Calculator and JSQCP
Migrating CPQ to Advanced Calculator and JSQCPMigrating CPQ to Advanced Calculator and JSQCP
Migrating CPQ to Advanced Calculator and JSQCPSalesforce Developers
 
Scale with Large Data Volumes and Big Objects in Salesforce
Scale with Large Data Volumes and Big Objects in SalesforceScale with Large Data Volumes and Big Objects in Salesforce
Scale with Large Data Volumes and Big Objects in SalesforceSalesforce Developers
 
Replicate Salesforce Data in Real Time with Change Data Capture
Replicate Salesforce Data in Real Time with Change Data CaptureReplicate Salesforce Data in Real Time with Change Data Capture
Replicate Salesforce Data in Real Time with Change Data CaptureSalesforce Developers
 
Modern Development with Salesforce DX
Modern Development with Salesforce DXModern Development with Salesforce DX
Modern Development with Salesforce DXSalesforce Developers
 
Integrate CMS Content Into Lightning Communities with CMS Connect
Integrate CMS Content Into Lightning Communities with CMS ConnectIntegrate CMS Content Into Lightning Communities with CMS Connect
Integrate CMS Content Into Lightning Communities with CMS ConnectSalesforce Developers
 

Mais de Salesforce Developers (20)

Sample Gallery: Reference Code and Best Practices for Salesforce Developers
Sample Gallery: Reference Code and Best Practices for Salesforce DevelopersSample Gallery: Reference Code and Best Practices for Salesforce Developers
Sample Gallery: Reference Code and Best Practices for Salesforce Developers
 
Maximizing Salesforce Lightning Experience and Lightning Component Performance
Maximizing Salesforce Lightning Experience and Lightning Component PerformanceMaximizing Salesforce Lightning Experience and Lightning Component Performance
Maximizing Salesforce Lightning Experience and Lightning Component Performance
 
Local development with Open Source Base Components
Local development with Open Source Base ComponentsLocal development with Open Source Base Components
Local development with Open Source Base Components
 
TrailheaDX India : Developer Highlights
TrailheaDX India : Developer HighlightsTrailheaDX India : Developer Highlights
TrailheaDX India : Developer Highlights
 
Why developers shouldn’t miss TrailheaDX India
Why developers shouldn’t miss TrailheaDX IndiaWhy developers shouldn’t miss TrailheaDX India
Why developers shouldn’t miss TrailheaDX India
 
CodeLive: Build Lightning Web Components faster with Local Development
CodeLive: Build Lightning Web Components faster with Local DevelopmentCodeLive: Build Lightning Web Components faster with Local Development
CodeLive: Build Lightning Web Components faster with Local Development
 
CodeLive: Converting Aura Components to Lightning Web Components
CodeLive: Converting Aura Components to Lightning Web ComponentsCodeLive: Converting Aura Components to Lightning Web Components
CodeLive: Converting Aura Components to Lightning Web Components
 
Enterprise-grade UI with open source Lightning Web Components
Enterprise-grade UI with open source Lightning Web ComponentsEnterprise-grade UI with open source Lightning Web Components
Enterprise-grade UI with open source Lightning Web Components
 
TrailheaDX and Summer '19: Developer Highlights
TrailheaDX and Summer '19: Developer HighlightsTrailheaDX and Summer '19: Developer Highlights
TrailheaDX and Summer '19: Developer Highlights
 
Live coding with LWC
Live coding with LWCLive coding with LWC
Live coding with LWC
 
Lightning web components - Episode 4 : Security and Testing
Lightning web components  - Episode 4 : Security and TestingLightning web components  - Episode 4 : Security and Testing
Lightning web components - Episode 4 : Security and Testing
 
LWC Episode 3- Component Communication and Aura Interoperability
LWC Episode 3- Component Communication and Aura InteroperabilityLWC Episode 3- Component Communication and Aura Interoperability
LWC Episode 3- Component Communication and Aura Interoperability
 
Lightning web components episode 2- work with salesforce data
Lightning web components   episode 2- work with salesforce dataLightning web components   episode 2- work with salesforce data
Lightning web components episode 2- work with salesforce data
 
Lightning web components - Episode 1 - An Introduction
Lightning web components - Episode 1 - An IntroductionLightning web components - Episode 1 - An Introduction
Lightning web components - Episode 1 - An Introduction
 
Migrating CPQ to Advanced Calculator and JSQCP
Migrating CPQ to Advanced Calculator and JSQCPMigrating CPQ to Advanced Calculator and JSQCP
Migrating CPQ to Advanced Calculator and JSQCP
 
Scale with Large Data Volumes and Big Objects in Salesforce
Scale with Large Data Volumes and Big Objects in SalesforceScale with Large Data Volumes and Big Objects in Salesforce
Scale with Large Data Volumes and Big Objects in Salesforce
 
Replicate Salesforce Data in Real Time with Change Data Capture
Replicate Salesforce Data in Real Time with Change Data CaptureReplicate Salesforce Data in Real Time with Change Data Capture
Replicate Salesforce Data in Real Time with Change Data Capture
 
Modern Development with Salesforce DX
Modern Development with Salesforce DXModern Development with Salesforce DX
Modern Development with Salesforce DX
 
Get Into Lightning Flow Development
Get Into Lightning Flow DevelopmentGet Into Lightning Flow Development
Get Into Lightning Flow Development
 
Integrate CMS Content Into Lightning Communities with CMS Connect
Integrate CMS Content Into Lightning Communities with CMS ConnectIntegrate CMS Content Into Lightning Communities with CMS Connect
Integrate CMS Content Into Lightning Communities with CMS Connect
 

Último

The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
What is Artificial Intelligence?????????
What is Artificial Intelligence?????????What is Artificial Intelligence?????????
What is Artificial Intelligence?????????blackmambaettijean
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 

Último (20)

The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
What is Artificial Intelligence?????????
What is Artificial Intelligence?????????What is Artificial Intelligence?????????
What is Artificial Intelligence?????????
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 

Creating Multi-Page Data Entry Controllers

  • 1. Building multi-page data entry Controllers Beyond Oz What to do when a simple Wizard is not enough Stuart Greenberg, OppenheimerFunds, Inc., Technical Lead @Stu_GuiGumdrops
  • 2. All about OppenheimerFunds, Inc. Since the original Oppenheimer fund was first offered to the public in 1959, OppenheimerFunds, Inc. (OFI) has grown into one of the largest and most reputable investment management firms in Click to Today, a subsidiary of Massachusetts Mutual Life Insurance Company the country. add brief company overview here. Lorem ipsum (MassMutual), OFI and its subsidiaries adipiscing elit. Sed lectusservices to individuals, dolor sit amet, consectetur offer a broad array of products and tortor, institutional investors and corporations worldwide. OFI provides advisory services to the Oppenheimer mutual funds and OFI Global Asset Management provides services to institutional pulvinar sit amet blandit ac, bibendum vitae sapien. clients. OFI, including subsidiaries, managed more than $222 billion in assets for more than 12 million shareholder accounts, including sub-accounts, as of September 30, 2013. ▪ Click to add implementation highlights; no more than four For more than 50 years, OFI has embraced an investment culture that has produced results, is sustainable, and reflects its commitment to being effective stewards of capital. A high conviction ▪ Click to add implementation highlights; no more than four. Lorem asset manager, OFI has a history of providing innovative investment strategies to its investors. Fouripsum dolor sit amet, consecteturinvestment culture: active management can deliver core beliefs lie at the heart of the OFI adipiscing elit. better outcomes, independent investment boutiques lead to better ideas, a global perspective is critical, and knowing the difference between risk & no more than four ▪ Click to add implementation highlights; risky. OFI’s investment professionals are a collection of distinct, yet collaborative, teams built to enable ▪ Click to add implementation highlights; no more than four a free exchange of ideas and to uncover opportunity wherever it lies; even where others see a disparate set of facts, events or trends. OFI is redefining what the world can expect from an asset manager, and stands united on its mission to turn its unconventional wisdom into value for investors.
  • 3. Who’s who and what’s what Stuart Greenberg ▪ ▪ ▪ ▪ Professional programmer since 1975 Past Senior Programmer, PC Magazine Labs Currently Tech Lead, OppenheimerFunds, Inc. Pennsylvania Railroad engineer And you? ▪ Visualforce developer? ▪ Written wizards or multi-page data entry? ▪ It’s late, all the other sessions were full and I just wanted to sit down?
  • 4. Single vs. wizard vs. multi-page data entry Single page ▪ Enter data / click save
  • 5. Single vs. wizard vs. multi-page data entry Wizard ▪ Enter data for step 1 / click next ▪ Enter data for step 2 / click next ▪ Etc.
  • 6. Single vs. wizard vs. multi-page data entry Multi-page ▪ Enter data on main page / click option ▪ Select option / Enter data on new page / click return ▪ Select option / Enter data on another page / click return ▪ Click save
  • 7. The problem ▪ Break the limit of one Contact/Lead and/or one other object attached to Events and Tasks (Multi-Who / Multi-What) ▪ Allow users to select objects in any order and skip selection of objects they don’t want ▪ Do not require the saving of Events and Tasks prior to selecting objects
  • 8. The solution ▪ Custom object (ActivitySidecar) connected to Events and Tasks using the WhatId ▪ Selection pages for all associated objects ▪ Multi-page data entry to keep all data in memory and save at the end
  • 10. Overall structure Controllers must be the same across pages. Classes instantiated as needed. Interfaces allow polymorphic functionality
  • 11. DEMO
  • 12. Gottas Wachagottadew… ▪ Selections must be queued ▪ All queued data must be saved at the same time ▪ Page code must be setup correctly
  • 13. Selectable Object public class OFI_SelectableObject { public Boolean isSelected {set;get;} public Boolean isEnabled {set;get;} public Boolean isInactive {set;get;} public Boolean isPrimary {set;get;} public String tag {set;get;} public Object obj {set;get;}
  • 14. Queueing selections // Lists Selectable Objects of the related objects // The tag property is used to indicate: // an existing object (tag = '') // an object to be added (tag = 'A') // an object to be deleted (tag = 'D') public List<OFI_SelectableObject> selProducts {get;set;} public List<OFI_SelectableObject> selContacts {get;set;} public List<OFI_SelectableObject> selFirms {get;set;} public List<OFI_SelectableObject> selUsers {get;set;} public List<OFI_SelectableObject> selFinancialAccounts {get;set;} public List<OFI_SelectableObject> selOpportunities {get;set;} public List<OFI_SelectableObject> selCampaigns {get;set;} public List<OFI_SelectableObject> selCases {get;set;}
  • 15. Selecting items public PageReference selectItems() { Integer i; for (OFI_SelectableObject record: recordsToDisplay) { if (record.isSelected) { if (!existingContactIds.contains(record.getContact().Id)) { // Not an existing selection for (i = 0; i < currentSelections.size(); i++) { // Check for undelete if (currentSelections[i].getActivityContact().Contact__c == record.getContact().Id && currentSelections[i].tag == 'D') { currentSelections[i].tag = ''; break; } } if (i == currentSelections.size()) { // Add new selection Activity_Contact__c actContact = new Activity_Contact__c(); // Set the Contact Id and Object. The Sidecar will be set when the Activity is saved. actContact.Contact__c = record.getContact().Id; actContact.Contact__r = record.getContact(); OFI_SelectableObject selObj = new OFI_SelectableObject(actContact); selObj.Tag = 'A'; currentSelections.add(selObj); } existingContactIds.add(record.getContact().Id); } } } return null; } // Add to existing Ids to enable checkmark
  • 16. Saving try { upsert evt; } catch (DMLException e) { ApexPages.addMessage(new ApexPages.Message(ApexPages.SEVERITY.ERROR, e.getLineNumber() + e.getMessage())); return false; } If (sidecarId == null) { Activity_Sidecar__c sidecar = [SELECT Id FROM Activity_sidecar__c WHERE Activity_Id__c = :evt.Id LIMIT 1]; evt.WhatId = sidecar.Id; } // Add / Delete Products List<Activity_Product__c> delProds = new List<Activity_Product__c>(); List<Activity_Product__c> addProds = new List<Activity_Product__c>(); for (OFI_SelectableObject o : sidecarEditor.selProducts) { if (o.tag == 'D') { delProds.add(o.getActivityProduct } else { if (o.tag == 'A') { o.getActivityProduct().Activity_Sidecar__c = evt.WhatId; addProds.add(o.getActivityProduct()); } } } if (delProds.size() > 0) { delete(delProds); } if (addProds.size() > 0) { insert(addProds); }
  • 17. Page code Event Edit Page <apex:page controller="ActivityEditPage2Controller" extensions="ActivityObjectSelController,VFFileUpload2" title="Calendar Event Edit"> Task Edit Page <apex:page controller="ActivityEditPage2Controller" extensions="ActivityObjectSelController,VFFileUpload2" title="Calendar Task Edit"> Selection Page <apex:page controller="ActivityEditPage2Controller" extensions="ActivityObjectSelController,VFFileUpload2" action="{!initObjectSelector}" title="Activity Contact Selection"> ▪ All controllers must be the same to keep their constructors from being called when a new page is opened. ▪ An Action must be added if any initialization is necessary when the page opens.
  • 18. Force instantiation on new session You need to use the following when you wish to start a new multi-page session: PageReference page = new PageReference('/apex/TaskEditPage'); page.setRedirect(true);
  • 20. You can’t leave the page The view state is maintained as long as the user doesn’t navigate to a page that has a different set of controllers. The solution: Javascript
  • 21. Avoid the message on “Good” clicks For example, the following was added to the Page Block Buttons: <apex:pageBlockButtons location="top" > <apex:commandButton value="Select and Return" action="{!SelectAndReturn}" onclick="setShowExitMessage(false);"/> <apex:commandButton value="Select and Add More" action="{!SelectItems}" onclick="setShowExitMessage(false);" rerender="thePage"/> <apex:commandButton value="Return" action="{!cancelSelection}" onclick="setShowExitMessage(false);"/> </apex:pageBlockButtons>
  • 22. <script type="text/javascript"> var isExitMessageTurnedOn = true; var showExitMessage = true; var isChrome = false; var isSafari = false; var ua = navigator.userAgent.toLowerCase(); if (ua.indexOf('safari') != -1){ if(ua.indexOf('chrome') > -1){ isChrome = true; } else { isSafari = true; } } function setShowExitMessage(val) { showExitMessage = val; } function isJavascriptElement() { if (isChrome || isSafari) return false;
  • 23. Be careful using classes ▪ Classes called from the controllers can be instantiated multiple times. ▪ Be sure to set the variables using the classes to null when finished.
  • 24. Example Destroy Selectors after each access Of a selection page.
  • 25. Return URLs ▪ Do not use the Return URL to go back to the initial page. ▪ Use the URL of the page itself. ▪ For example: // Cancel selection and return to the previous page. public pageReference cancelSelection() { destroySelector(); if (mainController.isTask) { return page.TaskEditPage2; } else { return page.EventEditPage2; } }
  • 26. Fugetaboutits Patient: Doc, it hurts when I do this. Doctor: Don’t do that.
  • 27. The View State size ▪ The View State is the data that is held between pages. ▪ Up to 135K of data. ▪ An exception is thrown if the limit is exceeded. ▪ Cannot hold attachments, for example.
  • 28. Time outs ▪ Sessions sitting too long can be timed out and data lost. ▪ Use multi-page data entry only for quick tasks.
  • 29. Alternatives Use multi-page data entry when you really have to Here are some alternatives: ▪ One page with hidden or collapsible sections ▪ A wizard flow based on initial selections ▪ Visual Workflow ▪ Dynamically generated search and select components
  • 30. Conclusion ▪ Multi-page data entry is possible with the proper care ▪ Use multi-page data entry once you’ve exhausted more mainstream options ▪ Nothing is impossible… Impossible just takes a bit longer
  • 31. Contact info and links Contact me at: ▪ Twitter: @Stu_GuiGumdrops ▪ Blog: http://www.guigumdrops.com Useful links: ▪ View State: http://wiki.developerforce.com/page/An_Introduction_to_Visualforce_View_State ▪ Visualforce and Visual Workflow: http://wiki.developerforce.com/page/User_Interface