Filtering Multiple Models Using a Single Set of Filters (Global Filters)

  • 1
  • Question
  • Updated 4 months ago
  • Answered
Hi,

We're displaying 10 account models on a single page.  All the models have been pre-filtered based on a customer segmention value.  This works fine, but we're having trouble determining how to apply additional filters to all 10 models (global filters).  The user may continue to filter the accounts by a number of additional fields (Sales Rep, Region, Gross Margin, etc.) so the solution here which suggests hardcoding values in the condition(s) isn't feasible.

We've also tried the example in the cross-object conditions post, but again the example is based on hardcoded values.  How do we pass a value selected in one filter into the value field on conditions on other models?  That seems to be the part we're missing.  Thanks!
Photo of Chad Barker

Chad Barker

  • 82 Points 75 badge 2x thumb

Posted 2 years ago

  • 1
Photo of Skuidward Tentacles (Raymond)

Skuidward Tentacles (Raymond), Champion

  • 17,224 Points 10k badge 2x thumb
I think you can create a condition based on records being in another model. So, you could have one model on which you apply your various filters and conditions and all other models would have one condition that would limit the records to only the records in the first model. You would likely also have to have a model action on your first model to requery all the other models when the first model is requeried. Then each time a filter or condition is applied to the first model, the other models will requery to display the correct records. I am not sure if this will work. Just an idea....
Photo of Chad Barker

Chad Barker

  • 82 Points 75 badge 2x thumb
Thanks Raymond - we're on a similar track.  The part we're missing is when a user sets a filter value on the model that has the filters, how do we pass the value to the conditions on the other models?

Model 1
Condition (Always On): Customer_Segment = null
(Auto) Filter: Sales_Rep

Model 2
Condition (Default Inactive): Customer_Segment = 2
Condition: __autofilter__Sales_Rep__c

The models load properly with the applicable conditions applied.  When the user selects a Sales Rep from Model 1, two actions are fired.  A JS snippet to make the condition on Model 2 active and set the condition value, and one to reload the models.

Based on one of the links in my original post, it appears JS is the only way to do this.  If that's true, can someone provide the mechanism to pass the value of Sales_Rep from Model 1 to the corresponding condition in Model 2.

Thanks again.
Photo of Henry Goddard

Henry Goddard

  • 776 Points 500 badge 2x thumb
Hey Chad,

The only way I could determine how to achieve this was indeed with a .js snippet. Using a read-only table with no fields selected, hook one of the models up to the desired filters. For the script to work properly you've then got to ensure that each model you want to be hooked up to the global filter is:

a) The same Salesforce object type
b) Has conditions identically named (_autofilter_ conditions work just fine. The fastest and most accurate way to do this is at the XML level.)

Next you want add a model action to the master model that will sit in the table and be filtered. It will call the following script as a js snippet:

https://gist.github.com/anonymous/a557119c0fc9547a9f126d25843e4713


For a short demo, try this skuid page: https://gist.github.com/anonymous/95d4c076b36d2ee7d5e55452501a07ec
(Edited)
Photo of Chandra V

Chandra V, Champion

  • 6,966 Points 5k badge 2x thumb
We are doing "super filtering" in a ton of places on our pages.  Not only for applying a single value across multiple objects, but also same objects in different models - especially aggregate models when we are displaying charts.

We use UI fields on a "dummy" model and then run a snippet when the user clicks a "search" button.

So, create a model to hold your Search UI fields.  We have a Look Ups object that we use everywhere for this, and the user has permission to create records in this object (although they never actually save anything to the object.)

- Add UI fields to your model that are what the user needs to search by (text, picklists, etc.)

 - For your models that you want to affect, create conditions on each model (filter default off).

For us, we may use a field called "Market" to filter our Contact object, Account object, and Opportunity object.  User wants to select market at the top, and the filter would get applied to all three models on the page.

Search Model...
UI field called "Market".  Picklist values = Energy, Oil & Gas, Education.

Contact Model...
Condition Market__c = {blank value}, off by default, named MarketContact

Account Model...
Condition Market__c = {blank value}, off by default, named MarketAccount

Opportunity Model...
Condition Market__c = {blank value}, off by default, named MarketOpportunity


The snippet looks something like this:

var params = arguments[0],           
 $ = skuid.$;

// Declare your search model                       
var FilterModel = skuid.model.getModel('SearchModel');
var FilterRow = FilterModel.getFirstRow();
           
//**************Include all your Search Fields
var marketVar = FilterModel.getFieldValue(FilterRow,'Market',true);
if (marketVar === "") {marketVar = null;}


// Declare your models you want to affect the conditions on
var contactModel = skuid.model.getModel('Contacts');
contactModel.emptyData();

var AccountModel = skuid.model.getModel('Accounts');
AccountModel.emptyData();

var OppModel = skuid.model.getModel('Opportunities');
OppModel.emptyData();

//***********Declare all Model Conditions 
var contactMarketCondition = contactModel.getConditionByName('MarketContact');
var accountMarketCondition = AccountModel.getConditionByName('MarketAccount');
var oppMarketCondition = OppModel.getConditionByName('MarketOpportunity');


//***********Deactivate all Model Conditions 
contactModel.deactivateCondition(contactMarketCondition, false);
AccountModel.deactivateCondition(accountMarketCondition, false);
OppModel.deactivateCondition(oppMarketCondition, false);


 
//***********Set Model Conditions if search fields are populated
if(marketVar !== null) {contactModel.setCondition(contactMarketCondition, marketVar, false);}
if(marketVar !== null) {AccountModel.setCondition(accountMarketCondition, marketVar, false);}
if(marketVar !== null) {OppModel.setCondition(oppMarketCondition, marketVar, false);}



// query models with conditions set
skuid.model.updateData([contactModel],function(){
    console.log('Contact model updated!');
});

skuid.model.updateData([AccountModel],function(){
    console.log('Account model updated!');
});

skuid.model.updateData([OppModel],function(){
    console.log('Opp model updated!');
});
Photo of John Dahlberg

John Dahlberg, Champion

  • 2,442 Points 2k badge 2x thumb
Here's an updated version of this snippet.  We're in the process of setting up a skuidified reporting package and have created a set of centralized filters that we can plug in via page includes.  This snippet is generalized to accept a source model name and an array of target models as input parameters, which we invoke with a url:

javascript:skuid.snippet.getSnippet('FilterSync')('Report_AccountFilter_Accounts',['Report_Accounts','Report_AccountTermination']);


var src = arguments[0],
    tgt = arguments[1],
$ = skuid.$;
    s = skuid.$M(src);
    $.each(s.conditions, function(i,condition){
        var sc = condition.name;
        if(sc.substring(0,14) == '__autofilter__'){
            co = sc.substring(14);
        }
        else{
            co = sc;
        }        
        $.each(tgt,function(s,cond){
            m = skuid.$M(cond);
           c = m.getConditionByName(co);
            if(condition.inactive){
                m.deactivateCondition(c);
            }
            else{
                m.activateCondition(c,condition.value);
                m.setCondition(c,condition.value);
            }
        });
    });
Photo of John Dahlberg

John Dahlberg, Champion

  • 2,442 Points 2k badge 2x thumb
I should mention that this version also handles autofilters as well.