Filter by ID

I have a custom filter that I would expect to be able to use with an array of ids to open a selection-list drawer with only the accounts in the array.

<?php
  $viewdefs['Accounts']['base']['filter']['basic']['filters'][] = array(
  'id' => 'FilterAccountsIdTemplate',
  'name' => 'LBL_FILTER_ACCOUNTS_BY_ID_TEMPLATE',
  'filter_definition' => array(
    array(
      'id' => array(
        '$in'=>'',
      ),
    ),
  ),
  'editable' => true,
  'is_template' => true,
);
?>

The ids are returned by an API call which gets the Account IDs related to a Contact (we have am M-N relationship between Accounts and Contacts).
The intent is, if there is only one account related to the contact, populate the Account relate field on this module, else, present the user with a selection-list drawer with only Accounts related to the selected Contact

({  extendsFrom: 'CreateActionsView',
  initialize: function(options){
    this._super('initialize', [options]);
    this.model.on('change:case_primary_contact_c', this.updateAccount, this);
  },
  updateAccount: function() {   
    console.log('updateAccount');
    if(!_.isEmpty(this.model.get('contact_id_c'))){
      var contact_id = this.model.get('contact_id_c'),
          url = app.api.buildURL('Contacts/'+contact_id+'/link/accounts_contacts/');
      app.api.call('GET', url, null, {
        success: _.bind( function (data){
          console.log(data);
          if(data.records.length == 1){
            this.model.set('account_id', data.records[0].id);
            this.model.set('account_name', data.records[0].name);
          }else if(data.records.length >1){
           console.log('more than 1');
            var account_ids = [];
            _.each(data.records, function (record){
              account_ids.push(record.id); //generate array of Account ids
            });
            console.log(account_ids);
            var filterOptions = new app.utils.FilterOptions()
              .config({
                'initial_filter': 'FilterAccountsByIdTemplate',
                'initial_filter_label': 'LBL_FILTER_ACCOUNTS_BY_ID_TEMPLATE',
                'filter_populate': {
                 'id':account_ids,
                }
              }).format();
            console.log(filterOptions);
            app.drawer.open({
              layout: 'selection-list',
              context: {
                module: 'Accounts',
                filterOptions: filterOptions,
              }
            });
          }
        }, this),
        error:_.bind(function(o){
          console.log("Error retrieving Account related to Contact" + o);
        }, this),
      });
    }
  },

But, although the filter shows in the selection-list, the criteria is not applied (it shows all accounts as if unfiltered)

I suspect the problem is filtering by ID, which is not normally a filter field.

Any suggestions on how to get around this?
FrancescaS
Parents
  • Hi FrancescaS,

    Yes I too have faced this problem.Then I used  'name' instead of id and it started working for me.Also I believe the filter definition should be like this.
    'filter_definition' => array(
        array(
          'name' => array(
            '$in'=> array(),
          ),
        ),
      ),

    You can use $in => array() instead of an empty string as we are going to pass an array of account names.

    Hope it helps.
    Thanks!
  • If we are passing id which field is being selected as the filter in the UI?
  • Hey one question, accounts_contacts standard relationship is one to many from accounts to contacts no?
    I got confused when you said one contact can have many accounts! Did you change the standard relationship?
  • Hi FrancescaS,

    It is currently not possible to filter by ID. 
    ID is not a field type that is supported by the client: see the list of field types and their supported operators: clients/base/filters/operators/operators.php 

    You can add support yourself by doing some work: 
    - You add the “id” field type, and the operators you’d like -> easy
    - You add the "id" field to the list of filterable fields for the Accounts module (modules/Accounts/clients/base/filters/basic/basic.php)  -> easy
    - You extend clients/base/views/filter-rows/filter-rows.js #handleOperatorSelected to add logic specific to your field type. I believe you should pay attention to the “relate” field type that works somewhat similar (“relate" filters by id but also fetches the names and instantiates a relate field to display nice in the UI), even though as of the current release it only supports filtering by a single record… :( Note that this part will break on upgrades) -> painful

    Another strategy would be to open a selection-list drawer that fetches only the contact's related accounts without applying a filter. 
    You can get that with: 
    app.drawer.open({ layout: 'selection-list', context: { module: 'Contacts', parentModelId: ‘<the_contact_id>', link: 'accounts' } });
    Notes: 
    - I think he selection-list does not support a related context very well. You will have to extend it a little in order to get the Accounts metadata instead of the Contacts metadata (for the columns to be displayed in the list view). 
    - You will be restricted to selecting an account from that list.  

    I think I would go with option 2. 

    Hope this helps,
    Julien.
  • Merci Julien,
    I think the bigger difficulty is that the relationship Contacts<->Accounts was changed to N-M and right now I'm getting an error in the log:

    Warning: Multiple links found for relationship accounts_contacts within module Contacts

    I will try option 2.
Reply Children
No Data