How to use 'Or' expression in custom filter for two different field in custom filter ?

Hi There,

I am looking to implement custom filters with 'OR' expression for two different field , As in sugar we can not use 'OR' expression for two different fields , it's working for same field. 

How can i implement it for two different fields ? 

As per below screenshot , I want to use these 2 filter  auto select on one of the dropdown selection , As per sugar default flow ,  For these 2 fields , 'AND' expression is being used , but i have to use 'OR' expression . 

Below is the code , i used for this : 

File : relate.js 

selectLocation: function () {
    var m03_work_product_name = this.model.get('m03_work_product_ii_inventory_item_1_name');
    console.log('m03_work_product_name', m03_work_product_name);
    var filterOptions = new app.utils.FilterOptions()
            .config({
                'initial_filter': 'FilterTestSystem',
                'initial_filter_label': 'Current Work Product Assignment',
                
                'filter_populate': {
                    'assigned_to_wp_c': m03_work_product_name,
                    'm03_work_product_id_c': ['4a529aae-5165-3149-6db7-5702c7b98a5e']
                },
                'filter_relate': {
                    'assigned_to_wp_c': m03_work_product_name,'m03_work_product_id_c': ['4a529aae-5165-3149-6db7-5702c7b98a5e'],
                },
            })
            .populateRelate(this.model)
            .format();
    //this custom code will effect for all relate fields in Enrollment module.But we need initial filter only for Test system relate field.
    filterOptions = (this.getSearchModule() == "ANML_Animals") ? filterOptions : this.getFilterOptions();
    app.drawer.open({
        layout: 'selection-list',
        context: {
            module: this.getSearchModule(),
            fields: this.getSearchFields(),
            filterOptions: filterOptions,
        }
    }, _.bind(this.setValue, this));
},

file : Filtertest.php : 

$viewdefs['ANML_Animals']['base']['filter']['basic']['filters'][] = array (
  'id' => 'FilterTestSystem',
  'name' => 'Current Work Product Assignment',
 
'filter_definition' => array(
  array(
    '$or' => array(
      'assigned_to_wp_c' => array(
        '$equals' => ''
      ),
      'm03_work_product_id_c' => array(
        '$in' => ''
      ),
    ),
  ),
),

  'editable' => true,
  'is_template' => true,
);

By using this ,  no filter is working , Below screen is showing : 

...

Parents
  • Hi Gurpreet,

    It can be late, but i encounter the same issues, and i manage to get it work by overriding javascript model Filter populateFilterDefinition function, in odrer to take account of nested array.

    I come up with this solution: 

    1. File include by JS grouping : customUrl.js

    (function (app) {
    
        app.events.on("router:init", function () {
    
            //Register the route #helloWorld
    
            var routes = [
    
                {
    
                    name: 'searchContactByPhone',
    
                    route: ':module/kiamo/:tel',
    
                    callback: function (module, tel) {
    
                        if (!tel) {
    
                            // Call standard "list" route if no value has been passed for "phone" attribute
    
                            app.router.list(module);
    
                            return;
    
                        }
    
    
                        var filterOptionsFormated = new app.utils.FilterOptions()
    
                            .config({
    
                                'initial_filter': 'filterContactByPhone',
    
                                'initial_filter_label': 'LBL_FILTER_CONTACT_BY_PHONE',
    
                                'filter_populate': {
    
                                    'phone_mobile': tel,
    
                                    'phone_work': tel,
    
                                    'phone_other': tel,
    
                                    'phone_fax': tel,
    
                                    'assistant_phone': tel
    
                                }
    
                            }).format();
    
    
                        app.controller.loadView({
    
                            module: module,
    
                            layout: 'records',
    
                            filterOptions: filterOptionsFormated
    
                        });
    
                    }
    
                }
    
            ];
    
            app.router.addRoutes(routes);
    
        });
    
    
        /**
    
         * Wrapper function for "populateFilterDefinition" of Data.Base.FiltersBean model
    
         * This function manage a recursive filter definition population for complex filters (e.g. "phone" search field is
    
         * a concatenation of 2 dbFields combined by "$or" operator.
    
         * A potential case will be open on Sugar portal to deal with this problematic, in that case this function might be deleted
    
         * @param origFunction
    
         * @param filterDef
    
         * @param populateObj
    
         * @returns {*}
    
         */
    
        var nestedPopulateFilterDefinition = function(origFunction, filterDef, populateObj) {
    
            if (!populateObj) {
    
                return filterDef;
    
            }
    
    
            _.each(filterDef, function (row) {
    
                _.each(row, function (filter, field) {
    
                    if(_.contains(['$or', '$and'], field) && _.isArray(filter)){
    
                        row[field] = nestedPopulateFilterDefinition(origFunction, filter, populateObj);
    
                    }
    
                });
    
            });
    
    
            return origFunction(filterDef, populateObj);
    
        };
    
    
        // Bind on first trigger of "app:view:change" to be sure sidecar have loaded all its metadata (particularly the "data" type
    
        // with Data.Base.FiltersBean model definition)
    
        app.events.once('app:view:change', function () {
    
            var protoFilters = app.data.getBeanClass('Filters').prototype;
    
            if(_.isFunction(protoFilters.populateFilterDefinition)) {
    
                // Override standard method "populateFilterDefinition" for nested set of filters that need to be populated with
    
                // related data
    
                app.data.getBeanClass('Filters').prototype.populateFilterDefinition = _.wrap(protoFilters.populateFilterDefinition, nestedPopulateFilterDefinition);
    
            }
    
        });
    
    })(SUGAR.App);

    Filter metadata : by_phone_filter.php

    <?php
    
    
    $viewdefs['Contacts']['base']['filter']['by_phone_number']['filters'][] = [
    
        'id' => 'filterContactByPhone',
    
        'name' => 'LBL_FILTER_CONTACT_BY_PHONE',
    
        'filter_definition' => [
    
            [
    
                '$or' => [
    
                    [
    
                        'phone_mobile' => [
    
                            '$starts' => ''
    
                        ],
    
                    ],
    
                    [
    
                        'phone_work' => [
    
                            '$starts' => ''
    
                        ],
    
                    ],
    
                    [
    
                        'phone_other' => [
    
                            '$starts' => ''
    
                        ],
    
                    ],
    
                    [
    
                        'phone_fax' => [
    
                            '$starts' => ''
    
                        ],
    
                    ],
    
                    [
    
                        'assistant_phone' => [
    
                            '$starts' => ''
    
                        ]
    
                    ],
    
                ]
    
            ]
    
        ],
    
        'editable' => true,
    
        'is_template' => true
    
    ];

    Hope it can help Slight smile

    Best regards

Reply
  • Hi Gurpreet,

    It can be late, but i encounter the same issues, and i manage to get it work by overriding javascript model Filter populateFilterDefinition function, in odrer to take account of nested array.

    I come up with this solution: 

    1. File include by JS grouping : customUrl.js

    (function (app) {
    
        app.events.on("router:init", function () {
    
            //Register the route #helloWorld
    
            var routes = [
    
                {
    
                    name: 'searchContactByPhone',
    
                    route: ':module/kiamo/:tel',
    
                    callback: function (module, tel) {
    
                        if (!tel) {
    
                            // Call standard "list" route if no value has been passed for "phone" attribute
    
                            app.router.list(module);
    
                            return;
    
                        }
    
    
                        var filterOptionsFormated = new app.utils.FilterOptions()
    
                            .config({
    
                                'initial_filter': 'filterContactByPhone',
    
                                'initial_filter_label': 'LBL_FILTER_CONTACT_BY_PHONE',
    
                                'filter_populate': {
    
                                    'phone_mobile': tel,
    
                                    'phone_work': tel,
    
                                    'phone_other': tel,
    
                                    'phone_fax': tel,
    
                                    'assistant_phone': tel
    
                                }
    
                            }).format();
    
    
                        app.controller.loadView({
    
                            module: module,
    
                            layout: 'records',
    
                            filterOptions: filterOptionsFormated
    
                        });
    
                    }
    
                }
    
            ];
    
            app.router.addRoutes(routes);
    
        });
    
    
        /**
    
         * Wrapper function for "populateFilterDefinition" of Data.Base.FiltersBean model
    
         * This function manage a recursive filter definition population for complex filters (e.g. "phone" search field is
    
         * a concatenation of 2 dbFields combined by "$or" operator.
    
         * A potential case will be open on Sugar portal to deal with this problematic, in that case this function might be deleted
    
         * @param origFunction
    
         * @param filterDef
    
         * @param populateObj
    
         * @returns {*}
    
         */
    
        var nestedPopulateFilterDefinition = function(origFunction, filterDef, populateObj) {
    
            if (!populateObj) {
    
                return filterDef;
    
            }
    
    
            _.each(filterDef, function (row) {
    
                _.each(row, function (filter, field) {
    
                    if(_.contains(['$or', '$and'], field) && _.isArray(filter)){
    
                        row[field] = nestedPopulateFilterDefinition(origFunction, filter, populateObj);
    
                    }
    
                });
    
            });
    
    
            return origFunction(filterDef, populateObj);
    
        };
    
    
        // Bind on first trigger of "app:view:change" to be sure sidecar have loaded all its metadata (particularly the "data" type
    
        // with Data.Base.FiltersBean model definition)
    
        app.events.once('app:view:change', function () {
    
            var protoFilters = app.data.getBeanClass('Filters').prototype;
    
            if(_.isFunction(protoFilters.populateFilterDefinition)) {
    
                // Override standard method "populateFilterDefinition" for nested set of filters that need to be populated with
    
                // related data
    
                app.data.getBeanClass('Filters').prototype.populateFilterDefinition = _.wrap(protoFilters.populateFilterDefinition, nestedPopulateFilterDefinition);
    
            }
    
        });
    
    })(SUGAR.App);

    Filter metadata : by_phone_filter.php

    <?php
    
    
    $viewdefs['Contacts']['base']['filter']['by_phone_number']['filters'][] = [
    
        'id' => 'filterContactByPhone',
    
        'name' => 'LBL_FILTER_CONTACT_BY_PHONE',
    
        'filter_definition' => [
    
            [
    
                '$or' => [
    
                    [
    
                        'phone_mobile' => [
    
                            '$starts' => ''
    
                        ],
    
                    ],
    
                    [
    
                        'phone_work' => [
    
                            '$starts' => ''
    
                        ],
    
                    ],
    
                    [
    
                        'phone_other' => [
    
                            '$starts' => ''
    
                        ],
    
                    ],
    
                    [
    
                        'phone_fax' => [
    
                            '$starts' => ''
    
                        ],
    
                    ],
    
                    [
    
                        'assistant_phone' => [
    
                            '$starts' => ''
    
                        ]
    
                    ],
    
                ]
    
            ]
    
        ],
    
        'editable' => true,
    
        'is_template' => true
    
    ];

    Hope it can help Slight smile

    Best regards

Children
No Data