ElasticUI icon indicating copy to clipboard operation
ElasticUI copied to clipboard

eui-or-filter not watching

Open petercsmith opened this issue 10 years ago • 3 comments
trafficstars

My analytics app uses a lot of "Or" aggregations configured with "filter-self=false", which makes the list of filters quite long. Customers find it difficult to sift through the list of aggregations to disable previously selected filters. To address this I've created a simple widget that lists all selected filters and allows them to be disabled individually. When the customer disables a filter via this widget it's expected that the state of checkboxes be reflected in the corresponding aggregation list. This works perfectly for "And" aggregations, but doesn't correctly update filter.enabled state for "Or" aggregations. Why is the "filter.enabled" state synchronized between two identically named "And" aggregations, but not for two identically name "Or" aggregations?

Thanks!

petercsmith avatar Jul 15 '15 20:07 petercsmith

I see what the problem is, the or-filter creates a "filters" property in the local scope of the aggregation, whereas the and-filter uses the "filters" property in the $parent scope. All "and" aggregations $watch the filters property in the $parent scope, so if you have two identical aggregations they will have their enabled filters synchronized; however, an "or" aggregation uses a filter property in the local scope, so the enabled filters will not synchronize between two identical aggregations. How to fix this is another problem entirely... suggestions welcome.

petercsmith avatar Jul 16 '15 18:07 petercsmith

Here's a hack to OrFilterController so identically named or-aggregations have synchronized filter selections, just like their and-aggregation counterpart. The general idea is to register the FilterCollection of an or-aggregation in $rootScope so an identically named or-aggregation can share the FilterCollection. There were a number of alternate approaches, but this was the lowest cost to implement.

module elasticui.controllers {
    export class OrFilterController {
        public filters = new util.FilterCollection();
        private name: any;
        private scope: any;

        static $inject = ['$scope', '$rootScope'];
        constructor($scope: any, $rootScope: any){
            $scope.$watch('aggregation.agg', () => {
                this.name = Object.keys($scope.aggregation.agg.toJSON())[0];

                if ($rootScope[this.name]) {
                    $scope.filters = $rootScope[this.name];
                } else {
                    $scope.filters = this.filters;
                    $rootScope[this.name] = this.filters;
                }
            });

            $scope.$watchCollection('filters.ejsObjects', () => this.updateCombinedFilter());

            this.scope = $scope;
        }

        private updateCombinedFilter() {
            if (this.scope.combinedFilter) {
                this.scope.$parent.filters.remove(this.scope.combinedFilter);
            }

            this.scope.combinedFilter = this.filters.getAsORFilter();
            if (this.scope.combinedFilter) {
                this.scope.$parent.filters.add(this.scope.combinedFilter);
            }
        }
    }
}

petercsmith avatar Jul 17 '15 02:07 petercsmith

Hi Peter,

Would it be possible to provide a small JS Fiddle illustrating the issue?

I'm pretty sure I know what you mean, but before I look into a fix I want to make sure how you build the aggregations / filters.

YousefED avatar Jul 22 '15 18:07 YousefED