Calendar "WhatId" filter lookup for all related available objects, Accounts, Opportunitiy, Custom Object etc.

  • 1
  • Question
  • Updated 4 years ago
  • Answered
When working with calendar events sources custom popoup and "configure on-click popup" the field WhatId displays all available records.  I would like to filter the field WhatId to only display items related to the account record I am working on for example Acme.  i.e. If I select Account then Acme should be the only available option and if I select Opportunity it should only display Opportunties related to Acme.  I have attempted to use the lookup filter and selected the Account Id field from Accounts referenced by the Url id.  That works fine and only displays Acme for the Account option but then also clears all the values for Opportunity, Cases, Etc.  Is there a way to set a filter for all lookup actions from the WhatId field to Accounts+Opportunities+Cases+Etc = AccounId {{id}}

Photo of Gregg Baxter

Gregg Baxter, Official Rep

  • 3,080 Points 3k badge 2x thumb
  • stupidly confused

Posted 4 years ago

  • 1
Photo of Zach McElrath

Zach McElrath, Employee

  • 49,056 Points 20k badge 2x thumb
This is not possible declaratively right now in Skuid, because there's no way to say "For only these Target Object types, filter on these fields, but for other Target Object types, filter on these other fields".

So the only option right now is JavaScript.

Here is a Custom Field Renderer for the WhatId field that will do it. There are 3 Configuration settings you may need to change, the first one is the AccountModelId variable, which should be set to the Id of your parent Account Model. The next variable basically says, "If target object is X, then only return records of X where field Y is equal to our Account Id". In the JavaScript code, we are dynamically adding / removing a Lookup Filter that produces this effect.

//
// CONFIGURATION
//
// THe name of your Account Model
var AccountModelId = 'Account';
// Define the Account reference fields on each target object
var accountLookupFilterFieldByTargetObject = {
    'Account': 'Id',
    'Asset': 'AccountId',
    'Case': 'AccountId',
    'Contract': 'AccountId',
    'Opportunity': 'AccountId',
    'Quote': 'AccountId'
    // 'MyCustomObject__c': 'Account__c'
};
// Render as a Picklist instead of an Autocomplete?
var renderAsPicklist = true;
var field = arguments[0],
    value = skuid.utils.decodeHTML(arguments[1]),
    options = field.options,
    metadata = field.metadata,
    referenceTo = metadata.referenceTo,
    $ = skuid.$;
if (renderAsPicklist) {
    options.type='REFPICK';
}
var addLookupFilterForSelectedObject = function(selectedObject){
    var filters = field.options.filters;
    if (!filters) {
        filters = [];
        field.options.filters = filters;
    } else {
        filters.length = 0;   
    }
    var accountReferenceFieldForObject = 
        selectedObject 
        ? accountLookupFilterFieldByTargetObject[selectedObject]
        : null; 
    if (accountReferenceFieldForObject) {
        filters.push({
           type: 'modelmerge',
           field: accountReferenceFieldForObject,
           mergeModel: AccountModelId,
           operator: '=',
           encloseValueInQuotes: true,
           mergeField: 'Id'
        });
    }
};
if ((field.mode === 'edit')
&&value
&&(!skuid.model.isNewId(value))
&&(field.metadata.namePointing) 
&&(field.metadata.referenceTo.length>1)) {
    // find the selected object type from the key prefix of our value
    var keyPrefix = value.substring(0,3);
    var obj;
    $.each(referenceTo,function(i,targetObj){
        if (targetObj.keyPrefix===keyPrefix){
            obj = targetObj.objectName;
            return false;
        }
    });
    addLookupFilterForSelectedObject(obj);
}
    
// Run the standard renderer
skuid.ui.fieldRenderers[metadata.displaytype][field.mode](field,value);
var bindObjectChangeHandlerTo = function(field) {
    var firstSelect = field.element.find('select').first();
    firstSelect.on('change',function(){
        var $this = $(this);
        var newObj = $this.children('option[value="'+$this.val()+'"]')
            .attr('data-sobject');
        addLookupFilterForSelectedObject(newObj);
        $this.off('change');
        skuid.ui.fieldRenderers[metadata.displaytype][field.mode](
            field,
            field.model.getFieldValue(field.row,field.id,true)
        );
        bindObjectChangeHandlerTo(field);
    });
};
bindObjectChangeHandlerTo(field);

Photo of Gregg Baxter

Gregg Baxter, Official Rep

  • 3,080 Points 3k badge 2x thumb
Thanks again Zach.  Works a dream. I added an additinal lookup filter just to kick the snippet in place lol.