Checkbox filter inverses logic to "notequal" when almost all values are selected

I'd discovered that Checkbox filter inverses logic to "notequal" when almost all values are selected, so instead of listing the selected values, it lists the non-selected ones and changes "equal" to "notequal".

I need the filtering to work in one consistent way.

How can I disable this?

Here you can see the difference.


Image_4165_1696249510941 Image_9013_1696249536334


1 Reply

VS Vikram Sundararajan Syncfusion Team November 4, 2023 04:02 AM UTC

Hi Pol Maresma,


Greetings from Syncfusion support,


In the EJ2 Excel/CheckBox filter, when the number of selected items is greater than the number of unselected items, the filtering is based on the unselected items. This is the default behavior and is implemented for efficiency. However, if you want to overcome this behavior and always filter with only the selected items, regardless of the count of selected and unselected items, you can achieve this by overriding the internal method "fltrBtnHandler" of the CheckBoxFilterBase module and removing the code that changes the filter values and operator based on the count of selected and unselected items. By doing this, the CheckBox filter will always perform filtering based on the selected values or only with "equal" operator. The code snippet has been added for your reference.


  [index.js]

 

 

CheckBoxFilterBase.prototype.fltrBtnHandler = function () {

  var _this = this;

 

  console.log(this);

 

  var checked = [].slice.call(

    this.cBox.querySelectorAll('.e-check:not(.e-selectall):not(.e-add-current)')

  );

 

  var check = checked;

 

  var optr = 'equal';

 

  var ddlValue = this.dialogObj.element.querySelector('.e-dropdownlist');

 

  if (ddlValue) {

    this.options.operator = optr = ddlValue.ej2_instances[0].value;

  }

 

  this.isMenuNotEqual = this.options.operator === 'notequal';

 

  var searchInput;

 

  if (!this.options.hideSearchbox) {

    searchInput = this.searchBox.querySelector('.e-searchinput');

  }

 

  var caseSen = this.options.allowCaseSensitive;

 

  var defaults = {

    field: this.options.field,

    predicate: this.isMenuNotEqual ? 'and' : 'or',

    uid: this.options.uid,

 

    operator: optr,

    type: this.options.type,

    matchCase: caseSen,

    ignoreAccent: this.options.ignoreAccent,

  };

 

  var isNotEqual =

    this.itemsCnt !== checked.length &&

    this.itemsCnt - checked.length < checked.length;

 

  //remove the below code as this code is responsible for filtering based on unselected values

 

  // if (isNotEqual && searchInput && searchInput.value === '') {

 

  //     optr = this.isMenuNotEqual ? 'equal' : 'notequal';

 

  //     console.log(optr)

 

  //     checked = [].slice.call(this.cBox.querySelectorAll('.e-uncheck:not(.e-selectall)'));

 

  //     defaults.predicate = this.isMenuNotEqual ? 'or' : 'and';

 

  //     defaults.operator = optr;

 

  // }

 

  var value;

 

  var val;

 

  var length;

 

  var fObj;

 

  var coll = [];

 

  if (

    checked.length !== this.itemsCnt ||

    (searchInput && searchInput.value && searchInput.value !== '')

  ) {

    for (var i = 0; i < checked.length; i++) {

      value =

        this.values[

          parentsUntil(

            checked[parseInt(i.toString(), 10)],

            'e-ftrchk'

          ).getAttribute('uid')

        ];

 

      fObj = extend({}, { value: value }, defaults);

 

      if (value && !value.toString().length) {

        fObj.operator = isNotEqual ? 'notequal' : 'equal';

      }

 

      if (value === '' || isNullOrUndefined(value)) {

        coll = coll.concat(

          CheckBoxFilterBase.generateNullValuePredicates(defaults)

        );

      } else {

        coll.push(fObj);

      }

 

      var args = {

        instance: this,

        handler: this.fltrBtnHandler,

        arg1: fObj.field,

        arg2: fObj.predicate,

        arg3: fObj.operator,

 

        arg4: fObj.matchCase,

        arg5: fObj.ignoreAccent,

        arg6: fObj.value,

        cancel: false,

      };

 

      this.parent.notify('filter-Prevent', args);

 

      if (args.cancel) {

        return;

      }

    }

 

    if (

      (this.options.type === 'date' || this.options.type === 'datetime') &&

      check.length

    ) {

      length = check.length - 1;

 

      val =

        this.values[

          parentsUntil(

            check[parseInt(length.toString(), 10)],

            'e-ftrchk'

          ).getAttribute('uid')

        ];

 

      if (isNullOrUndefined(val) && isNotEqual) {

        coll.push({

          field: defaults.field,

          matchCase: defaults.matchCase,

          operator: 'equal',

 

          predicate: 'and',

          value: null,

        });

      }

    }

 

    if (

      this.cBox.querySelector('.e-add-current') &&

      this.cBox.querySelector('.e-add-current').classList.contains('e-check')

    ) {

      var existingPredicate_1 = this.existingPredicate[this.options.field];

 

      if (existingPredicate_1) {

        var _loop_1 = function (j) {

          if (

            !coll.some(function (data) {

              return (

                data.value ===

                existingPredicate_1[parseInt(j.toString(), 10)].value

              );

            })

          ) {

            coll.push(existingPredicate_1[parseInt(j.toString(), 10)]);

          }

        };

 

        for (var j = 0; j < existingPredicate_1.length; j++) {

          _loop_1(j);

        }

      } else {

        return;

      }

    }

 

    this.initiateFilter(coll);

  } else {

    var isClearFilter = this.options.filteredColumns.some(function (value) {

      return _this.options.field === value.field;

    });

 

    if (isClearFilter) {

      this.clearFilter();

    }

  }

};


Sample: https://stackblitz.com/edit/react-qv8pta-u7kc87?file=index.js


Regards,

Vikram S



Loader.
Up arrow icon