Can I limit which objects are possible targets of polymorphic fields such as the WhatId and WhoId fi

When working with the “WhatId” (aka “Opportunity/Account Id” or “Related To”) field on the Task and Event objects, Salesforce lets you pick from lots of different possible target objects. On certain Skuid Pages, I would like to limit the set of possible target objects to, say, just Opportunities, or just Accounts and Cases, so that the user doesn’t have to scroll through a list of all the possible target objects. Is this possible with Skuid?

Yes, this is possible using a custom field renderer. For our example, we’ll limit this to just let the User pick Accounts or Opportunities. 1. Create a custom field renderer -Snippet Name: something like “relatedToRenderer” -Type: Inline (Snippet) -Body: Copy the following, but edit the top part to select your desired target objects:

//
// CONFIGURATION 
// 
// Define the possible target objects 
var targetObjects = ['Account', 'Opportunity']; 
// Render as a Picklist instead of an Autocomplete? 
var renderAsPicklist = false; 
var field = arguments[0], 
    value = skuid.utils.decodeHTML(arguments[1]), 
    metadata = field.metadata, 
    $ = skuid.$; 
if (field.mode == 'edit') { 
    // Limit the set of target objects 
    var targets = [], 
       uniqueTargets = {}; 
    $.each(metadata.referenceTo,function(i,r){ 
       if (($.inArray(r.objectName,targetObjects) != -1) && (!uniqueTargets[r.objectName])) { 
          targets.push(r); 
          uniqueTargets[r.objectName] = 1; 
          if (targets.length == targetObjects.length) return false; 
        } 
    }); 
    if (targets.length) { 
       // Make this field render as a picklist? 
       if (renderAsPicklist) field.options.type = 'REFPICK'; 
       // Override the current referenceTo 
       metadata.referenceTo.length = 0; 
       metadata.ref = $.map(targets,function(targ){return targ.objectName;}).join();
       metadata.referenceTo = targets; 
    } 
} 
// Run the standard renderer 
skuid.ui.fieldRenderers[metadata.displaytype][field.mode](field,value); 

2. Assign this custom field renderer to your “WhatId” field

You’re done!

BONUS If you only want ONE possible target item, this is fine – Skuid will remove the object-selection picklist entirely! For instance, to limit to just Cases:

We came across this challenge yesterday and were scratching our heads as to what a solution might look like. I implemented this just now in about 2 minutes and it works beautifully. Fantastic.

UPDATE: there were some bugs with the original Snippet I posted here, but I have updated the Snippet and it should work properly now.

I have a followup question to this item. I am developing some custom pages with my Force.com administration license. With this license I can see all objects of Salesforce; however when I go to deploy this to my staff they are using Force.com - App Subscription licenses. These license types limit the Standard objects to Accounts, Contacts and Acitivities.

Ideally this is great as when I create a new event in the Related to drop down I only see Accounts and Contacts and any custom objects I’ve created; HOWEVER

I created an Activities List view page in Skuid that I can create records inline (with my developer license). When I view this page with a Force.com - App Subscription license (staff license) and I add a new record; the Related To picklist shows all Salesforce Standard objects. If I create a record under this license through the standard Salesforce New Task Detail page and I select the Related To field it only shows the allowed objects (not all).

Any insight into this would be greatly appreciated?

Hi David,

Thanks for reporting this — we’re classifying this as a bug/enhancement and it should be fixed as of our next minor release.

Regards,

Zach

This has been fixed as of Skuid 4.15 which should be available on www.skuidify.com/SkuidReleases by close of business today (5/2/14)

Zach, this works great. What if I want to display different text on the object lookup than objectName? I tried setting up some if statements, but I’m not sure which part of the code sets the values for the picklist here.

Craig, there is a way to make it so that when you are picking a value you could see different fields on the target object other than the object’s Name field, but we would not easily be able to show this value again when the field is in read mode. That is, when the user picks/changes a value for this field, and saves the record, we could make this all go well and good. But when the user comes back to this page again, it will not show your custom “other” field — because you can’t query for any field other than “What.Name” or “Who.Name”. So to get this to work in read mode, we’d have to check when the page first loads whether the field we want to show is the same as “What.Name” or “Who.Name”, and if it’s not, we’d have to do a quick dynamic query to go get that value. At this point we’re doing quite a bit of JavaScript — if you really need this, we can perhaps go this direction — or if you’re just concerned about edit mode showing different fields, let me know and I can give you that will work just in edit mode.

Shortly after posting this, I realized that we don’t want the user to be able to change which record the task is related to for this specific object type. I added some custom field renders to say our custom text just for that object time in read and edit mode and it works great. I am curious how we would change what displays in just edit mode, since I couldn’t figure that part out yesterday.

Craig, unfortunately I’m going to have to back-pedal on this one. I couldn’t reliably use a Snippet to get this to work – there’s too much hackery necessary for me to feel comfortable posting a snippet for it on the Community, and even with a lot of hackery, it still doesn’t work as it should when you switch which object you want to search for. I think that this would need to be implemented by Skuid declaratively for it to be supported. Sorry to disappoint.

Hi Zach, 

We have tried this to render Task Assigned To (Who ID) with User, Partner User.  But the above given script unluckily doesn render anything such for us.  

we have followed the steps that you have provided from creating in line snippet, custom field renderer uses this snippet.  But it doesn wrks.

Any help would be great!

Thanks

Hi,

Does anyone know how to modify the js for V2, please?

Thanks

Hey @Monica! I found a newer post that may answer your question:

Thanks so much. I copied and pasted the js and used it as a custom field renderer. But the page will not load.

Hey @Monica,

When you take out the JS and reload the page, does it load then? If so, then there could be an issue with how the JS itself is on your page. Have you debugged the page to see the error message it’s giving off?

If possible, can you share any screenshots of the console to see if there are any error messages?

Thanks,

@Germany,

Yes, once I delete the JS the page loads. Here is the xml with the JS.

<skuid__page unsavedchangeswarning="yes" personalizationmode="server" showsidebar="true" showheader="true">
	<models>
		<model id="Tasks" limit="0" query="false" createrowifnonefound="true" datasource="salesforce" sobject="Task">
			<fields>
				<field id="RecordTypeId"/>
				<field id="RecordType.Name"/>
				<field id="WhoId"/>
				<field id="Who.Name"/>
				<field id="WhatId" overridemetadata="true" ogdisplaytype="REFERENCE" displaytype="REFERENCE" datasource="salesforce">
					<batchfields/>
				</field>
				<field id="What.Name" overridemetadata="false" ogdisplaytype="STRING" displaytype="STRING" defaultvaluetype="fieldvalue" defaultValue="Account"/>
				<field id="Description"/>
			</fields>
			<conditions/>
			<actions/>
		</model>
	</models>
	<components>
		<skuid__wrapper uniqueid="sk-35vw-2068">
			<components>
				<skuid__buttonSet uniqueid="sk-3G9r-3544" position="center">
					<groups>
						<skuid__buttonGroup uniqueId="sk-3G9r-3542" displayType="detached">
							<buttons>
								<skuid__button label="Open Modal" uniqueId="sk-3G9r-3543">
									<actions>
										<action type="showModal">
											<skuid__modal title="New Task" width="640px">
												<components>
													<skuid__form showErrorsInline="true" model="Tasks" uniqueid="sk-3GA4-9917" mode="edit">
														<sections>
															<section title="New Section">
																<rows>
																	<row>
																		<fields>
																			<skuid__field id="Description" uniqueId="sk-3GA7-10542"/>
																		</fields>
																	</row>
																	<row>
																		<fields>
																			<skuid__field id="WhoId" uniqueId="sk-3GA7-10547"/>
																		</fields>
																	</row>
																	<row>
																		<fields>
																			<skuid__field id="WhatId" uniqueId="sk-3GA7-10552"/>
																		</fields>
																	</row>
																	
																</rows>
															</section>
														</sections>
													</skuid__form>
												</components>
											</skuid__modal>
										</action>
									</actions>
								</skuid__button>
							</buttons>
						</skuid__buttonGroup>
					</groups>
				</skuid__buttonSet>
				<skuid__form showErrorsInline="true" model="Tasks" uniqueid="sk-35wN-6298" mode="edit" styleSettingsVariant="ad151853-c086-41d9-aae3-c8041796dcec">
					<sections>
						<section title="New Section">
							<rows>
								
								<row>
									<fields>
										<skuid__field id="WhatId" uniqueId="sk-35wN-6303" displayAs="PICKLIST" fieldRenderer="newFieldRenderer"/>
									</fields>
								</row>
								<row>
									<fields>
										<skuid__field id="Description" uniqueId="sk-35wY-9662">
											<renderConditions logictype="and" onhidedatabehavior="keep"/>
											<enableConditions/>
											<styleVariantConditions/>
										</skuid__field>
									</fields>
								</row>
							</rows>
							<renderConditions logictype="and"/>
						</section>
					</sections>
					<styles>
						<spacing top="6" bottom="6" left="6" right="6" styleSettingsVariant="ad151853-c086-41d9-aae3-c8041796dcec"/>
					</styles>
				</skuid__form>
			</components>
			<styles>
				<spacing top="6" bottom="6" left="6" right="6"/>
			</styles>
			<background/>
		</skuid__wrapper>
	</components>
	<resources>
		<labels/>
		<javascript>
			
		<jsitem location="inlinesnippet" name="newSnippet" cachelocation="false">var $ = skuid.$,  
targetObjects = ['Opportunity', 'Account'], 
// Define the objects made available in the selector.  field = arguments[0],  value = skuid.utils.decodeHTML(arguments[1]),  metadata = field.metadata,  model = field.model,  row = field.row,  whatId = row.WhatId,  whatString = String(whatId),  whatPrefix = whatString.substring(0,3),  renderAsPicklist = false; // if set to true, WhatId lookup field becomes a picklist. Not useful for objects with large number of search results. 
var updateFieldData = function(field, whatPrefix) {   // this function controls which fields are searched and made visible in the selector popup.  // &lt;a target="" rel="" href="https://community.skuid.com/skuid/topics/use-javascript-to-control-the-display-and-search-templates-of-a-polymorphic-whatid-field?rfm=1" alt="" title="Link httpscommunityskuidcomskuidtopicsuse-javascript-to-control-the-display-and-search-templates-of-a-polymorphic-whatid-fieldrfm1" name="" value="" type=""&gt;https://community.skuid.com/skuid/topics/use-javascript-to-control-the-display-and-search-templates-...&lt;/a&gt;
  switch ( whatPrefix ) {           
      case "006":  
      // Opportunity      
      field.options.returnFields = [{id: 'Id', showInSearchDialog: false}, {id: 'Name', showInSearchDialog: true}, {id: 'StageName', showInSearchDialog: true}];      
      field.options.searchTemplate = "{{Name}}, Stage: {{StageName}}";      
      break;         
      case "001":  
      // Account aka Organization      
      field.options.returnFields = [ {id: 'Id', showInSearchDialog: false},   {id: 'Name', showInSearchDialog: true},  {id: 'Organization_Alias_Name__c', showInSearchDialog: true}];      
      field.options.searchTemplate = "{{Name}}, Alias: {{Organization_Alias_Name__c}}";      
      break;       
    } 
};
        if (field.mode == 'edit') {
        // Limit the set of target objects  
        var targets = [],    
        uniqueTargets = {};     
        $.each(metadata.referenceTo,function(i,r){    
            if (($.inArray(r.objectName,targetObjects) != -1) 
                (!uniqueTargets[r.objectName])) {      
                    targets.push(r);      
                    uniqueTargets[r.objectName] = 1;      
                    if (targets.length == targetObjects.length) 
                        return false;    
                }  
            });
            if (targets.length) {       
                // Make this field render as a picklist? (no - var is set to false for this implementation)  if (renderAsPicklist) field.options.type = 'REFPICK';
                // Override the current referenceTo    
                metadata.referenceTo.length = 0;    
                metadata.ref = $.map(targets,function(targ){return targ.objectName;
                }).join();    
                metadata.referenceTo = targets;  
            }
        }
// Get field renderer - &lt;a target="" rel="" href="https://docs.skuid.com/latest/en/skuid/api/skuid_ui.html#skuid.ui.getFieldRenderer" alt="" title="Link httpsdocsskuidcomlatestenskuidapiskuid_uihtmlskuiduigetFieldRenderer" name="" value="" type=""&gt;https://docs.skuid.com/latest/en/skuid/api/skuid_ui.html#skuid.ui.getFieldRenderer&lt;/a&gt;
skuid.ui.getFieldRenderer(field)[field.mode](field, value);
// control the search layout
if ( whatPrefix === 'und') whatPrefix = "701";  // default to Campaign
updateFieldData(field, whatPrefix);
$(field.element).find("select").bind("change", function(e) {
  var val = $( "select option:selected" ).text();   if( val.includes("Opportunity") ) {       updateFieldData(field,"006");     } else if ( val.includes("Account")) {     updateFieldData(field,"001");   }  else {       updateFieldData(field, whatPrefix);     }
});</jsitem>
</javascript>
		<css/>
		<actionsequences/>
	</resources>
	<styles>
		<styleitem type="background" bgtype="none"/>
	</styles>
</skuid__page>

@Germany

There is no error, but this is what I see on in inspect.

Thanks