Best way to redirect based on "type" field value?

  • 1
  • Question
  • Updated 5 years ago
We use the Account object in our app for three purposes: prospects, clients and service providers. These are picklist entries in the custom field picklist Account.Organisation_Type__c. Each of these has a specific detail page in Skuid: ProspectView, ClientView and ProviderView, and each Skuid page is housed in a Visualforce page of the same name.

Whenever we render Account.Name in our Skuid pages, we want the underlying hyperlink to point to the Visualforce/Skuid page relevant for the type. e.g. if the account is a client, the URL should be "/apex/ClientView?id=01r90000000SJBc". The question: how best to do this?

I don't think Skuid page assignments are applicable, as we're directing traffic to Visualforce pages. We tried creating a single Visualforce page to redirect the traffic, and it works, but it's slow, taking several seconds each time (which isn't good enough for such a high use scenario). We could render the field via a template, but then we lose inline editing and sorting, which is a high price.

It seems to me that a magical custom field renderer could do it. My theory is that it simply needs to replace the "/" that renders in front of the Id with the correct page name. But the magic eludes me. Am I at least on the right track?
Photo of Glenn Elliott

Glenn Elliott, Champion

  • 7,738 Points 5k badge 2x thumb
  • getting close to the solution, although it may be a mirage

Posted 5 years ago

  • 1
Photo of Rob Hatch

Rob Hatch, Official Rep

  • 44,006 Points 20k badge 2x thumb
Glenn.  I'll ask Zach to comment on the magical custom field renderer solution.  But can I ask why you are not using record type to make this distinction and then the standard page assignment routines to correctly route users to different VF pages?  I imagine that it might be some rework for you, or that you are using record type for other functionality.  But as far as I know - you are describing the exact use case for which we built the record type - page assignment interaction. 
Photo of Zach McElrath

Zach McElrath, Employee

  • 49,056 Points 20k badge 2x thumb
I think that the VF Page serving as the redirector is the simplest in principle, as it requires no changes to field renderers in your Skuid Pages.

As far as the custom field renderer option, though, yes it would work and would be slighty faster.

Here's the base Snippet, called CustomReferenceRedirect




var CONDITIONAL_FIELD_ID = 'Organisation_Type__c';

var VALUE_TO_URL_MAPPINGS = {
'Prospect' : '/apex/c__ProspectView',
'Client' : '/apex/c__ClientView',
'Provider' : '/apex/c__ProviderView'
};

// The page to send the user to if there's no value
// (OPTIONAL - if left blank, then the user will be sent to '/'+Id)
var DEFAULT_URL = '/apex/c__ProspectView';

var field = arguments[0],
value = skuid.utils.decodeHTML(arguments[1]),
$ = skuid.$,
displayType = field.metadata.displaytype,
conditionalFieldValue = field.model.getFieldValue(
field.row,CONDITIONAL_FIELD_ID,true
),
targetFieldId;

if (displayType === 'STRING' || displayType === 'TEXT') {
// We assume that this is the Name field value,
// otherwise there wouldn't be a link
targetFieldId = field.row.Id;
} else if (displayType === 'REFERENCE') {
targetFieldId = value;
}

skuid.ui.fieldRenderers[field.metadata.displaytype][field.mode](field,value);

if (field.mode !== 'edit') {
var link = field.element.find('a');
if (link.length && targetFieldId) {

var newUrl;
if (conditionalFieldValue in VALUE_TO_URL_MAPPINGS) {
newUrl = VALUE_TO_URL_MAPPINGS[conditionalFieldValue];
} else if (DEFAULT_URL) {
newUrl = DEFAULT_URL;
} else {
return;
}
if (newUrl.indexOf('?')===-1) newUrl += '?';
else newUrl += '&';

newUrl = newUrl + 'id=' + targetFieldId;

link.attr('href',newUrl);
}
}



How to use this Snippet

(a) From a Field Editor / Table on an Account(s) Model (e.g. an Accounts Tab page)

1. Make sure you have the Organisation_Type__c field present in your Account Model.
2. Go to the "Name" field in your Account Table, and set to use a Custom Field Renderer, using "CustomReferenceRedirect" as the Render Snippet Name.

(b) From a Field Editor / Table on some other Object Type that has a Lookup to Account (e.g. to override the Contact "AccountId" field behavior)

1. Make sure you have the Account.Organisation_Type__c field present in your Account Model.
2. ***Modify the above Snippet: CONDITIONAL_FIELD_ID to 'Account.Organisation_Type__c', e.g. the new first line in the Snippet should be:

var CONDITIONAL_FIELD_ID = 'Account.Organisation_Type__c';

3. Go to the "AccountId" field in your Contact Table/Field Editor, and set to use a Custom Field Renderer, using "CustomReferenceRedirect" as the Render Snippet Name.
Photo of Glenn Elliott

Glenn Elliott, Champion

  • 7,738 Points 5k badge 2x thumb
Zach: that looks perfect. Will give it a try.

Rob: Are you talking about using record types with Skuid's Page Assignments functionality? But am I right in thinking that that can only redirect to a Skuid page (not a VF page) or a standard page, like here?



Our "type" specific Skuid pages each have a container VF page, mostly for the purpose of user-friendly URLs. To redirect to those VF container pages, I couldn't find a way to make Skuid Page Assignments work, hence we created our OrgRedir VF page:

<apex:page standardController="Account" extensions="OrganisationDispatcher"
action="{!nullValue(redir.url, urlFor($Action.Account.View, account.id, null, true))}">
</apex:page>


and its controller:

public class OrganisationDispatcher {

public OrganisationDispatcher(ApexPages.StandardController controller) {
this.controller = controller;
}

public String myType {
get
{
String x = ApexPages.currentPage().getParameters().get('id');
String t = [SELECT Organisation_Type__c from Account where id = :x LIMIT 1].Client_Type__c;
return t;
}
set;
}

public String myId {
get
{
String i = ApexPages.currentPage().getParameters().get('id');
return i;
}
set;
}

public PageReference getRedir() {

PageReference myPage;
if (myType == 'Client Household' || myType == 'Client Business') {
myPage = Page.ClientView;
myPage.getParameters().put('id', myId);
return myPage.setRedirect(true);
} else {
return null;
}
}

private final ApexPages.StandardController controller;
}


That approach works, but it's inconsistently slow (turns a typical page load from 2 sec to 4-5 sec, which just isn't acceptable). Hence the need for Zach's custom field renderer magic.

Hope that makes sense and that I'm not missing anything simple. :)