Benj, since you're using the JavaScript Ajax Toolkit to get at the Dependent Picklist API, another option is to cache the information using JavaScript as well, by storing it in HTML5 Local / Session Storage, with a fallback either to Cookies or Custom Settings (as per Andrew Fawcett's 'striping' approach, which is a good solution as well) for older browsers that do not support HTML5. We've used this for caching calls to describeTabs, and it's worked great. HTML5 Session/Local storage is definitely the way to go looking forward, as it's lightning fast, gives you plenty of storage space, and is all client-side, so after the first call there's no work at all done in Apex.
Here's a great intro to HTML5 Local/Session Storage.
Here's the basic approach you'd need to do in Visualforce/JavaScript to get this going:
- Create some storage getter/setter methods that will do the hard work of checking for support of local/session storage and falling back to cookies if necessary.
- On page load, check your storage for a cached picklist dependencies key in your storage.
- If the cache exists, grab it! Otherwise, do a call to AJAX API to retrieve the info you need. Then, strip the info down to the bare minimum you need to store (the AJAX API calls often return a lot of needless bloat, I recommend parsing your responses down to just what you need), and then use
JSON.stringify() to convert your data to JSON before storing it in your cache.
Part 1: Create your Local Storage Repo
// The canUseLocalStorage() function will let you know
// if HTML5 local storage is supported
var _canUseLocalStorage = 'nodata',
canUseLocalStorage = function(){
if (_canUseLocalStorage === 'nodata') {
try {
return (_canUseLocalStorage = 'localStorage' in window && window['localStorage'] !== null);
} catch (e) {
return (_canUseLocalStorage = false);
}
} else return _canUseLocalStorage;
},
// Store stuff in local storage, if possible,
// otherwise fall back to cookies
localStorage = function(key,value) {
// Can we use storage?
var canUseStorage = canUseLocalStorage();
return (
// If we're RETRIEVING content...
(typeof value === 'undefined') ? (
// Use Local Storage
(canUseStorage) ? window.localStorage[key]
// Use cookies
: $.cookie(key,value)
)
// If we're STORING content
: (
// Use Session Storage
(canUseStorage) ? (window.localStorage[key] = value)
// Use cookies
: $.cookie(key,value)
)
);
};
Part 2: Check to see if your storage repo has a cached result
// Our key(s) will be called 'picklistCache_<objectName>_<fieldName>`
// So here's an example for the Account Type field
var cacheName = 'picklistCache_Account_AccountType',
cacheResult = localStorage(cacheName);
// If we did NOT have such a result,
// we'll need to query the AJAX API
if (!cacheResult) {
if (sforce.connection.sessionId) {
// Query the AJAX API for the Picklist Dependency info,
// using the strategy in the following article:
// http://iwritecrappycode.wordpress.com/2012/02/23/dependent-picklists-in-salesforce-without-metadata-api-or-visualforce/
// ....
// ANd stringify your result once you're done!
cacheResult = JSON.stringify(cacheResult);
// Once we've got our data, cache it!
localStorage(cacheName,cacheResult);
}
}
// Now use the result to do your client-side picklist dependency work!
if (cacheResult) {
// Unpack our JSON result
cacheResult = JSON.parse(cacheResult);
// Render dependent picklists
}