1

Once we add something for filtering ended with white space, search results are not displayed even the data is present.Can we have trim function and if yes then how?

  • The issue in Magento default or custom module? because default Magento already trimming after and before. – Nikunj Vadariya May 11 '18 at 12:22
  • @NikunjVadariya no its the issue of default magento 2.1x versions, trimming is done in 2.2x versions. – Ruhani May 11 '18 at 12:42
  • You should upgrade your magento 2.X to 2.2.x is good option. :) – Nikunj Vadariya May 11 '18 at 12:47
  • its not feasible for now..thanks for the suggestion :) – Ruhani May 11 '18 at 12:51
  • Is that issue only for product grid filter or the same issue in other grid? – kunj May 11 '18 at 13:09
1

I have created the module and override the filter.js as below.

1. Create requirejs-config.js under

Namespace\Module\view\base\requirejs-config.js

with below code. (Don't use adminhtml/base as it's a base file)

var config = {
      "map": {
        "*": {
          "Magento_Ui/js/grid/filters/filters": 
              "<Namespace>_<Module>/js/grid/filters/filters"
        }
      }
    };

2. override filter.js to below path.

Namespace\Module\view\base\web\js\grid\filters\filters.js

added latest versions js as below.

/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
**/

/**
* @api
*/
define([
   'underscore',
   'mageUtils',
   'uiLayout',
   'uiCollection',
   'mage/translate',
   'jquery'
], function (_, utils, layout, Collection, $t, $) {
   'use strict';

/**
 * Extracts and formats preview of an element.
 *
 * @param {Object} elem - Element whose preview should be extracted.
 * @returns {Object} Formatted data.
 */
function extractPreview(elem) {
    return {
        label: elem.label,
        preview: elem.getPreview(),
        elem: elem
    };
}

/**
 * Removes empty properties from the provided object.
 *
 * @param {Object} data - Object to be processed.
 * @returns {Object}
 */
function removeEmpty(data) {
    var result = utils.mapRecursive(data, utils.removeEmptyValues.bind(utils));

    return utils.mapRecursive(result, function (value) {
        return _.isString(value) ? value.trim() : value;
    });
}

return Collection.extend({
    defaults: {
        template: 'ui/grid/filters/filters',
        stickyTmpl: 'ui/grid/sticky/filters',
        _processed: [],
        columnsProvider: 'ns = ${ $.ns }, componentType = columns',
        bookmarksProvider: 'ns = ${ $.ns }, componentType = bookmark',
        applied: {
            placeholder: true
        },
        filters: {
            placeholder: true
        },
        templates: {
            filters: {
                base: {
                    parent: '${ $.$data.filters.name }',
                    name: '${ $.$data.column.index }',
                    provider: '${ $.$data.filters.name }',
                    dataScope: '${ $.$data.column.index }',
                    label: '${ $.$data.column.label }',
                    imports: {
                        visible: '${ $.$data.column.name }:visible'
                    }
                },
                text: {
                    component: 'Magento_Ui/js/form/element/abstract',
                    template: 'ui/grid/filters/field'
                },
                select: {
                    component: 'Magento_Ui/js/form/element/select',
                    template: 'ui/grid/filters/field',
                    options: '${ JSON.stringify($.$data.column.options) }',
                    caption: ' '
                },
                dateRange: {
                    component: 'Magento_Ui/js/grid/filters/range',
                    rangeType: 'date'
                },
                textRange: {
                    component: 'Magento_Ui/js/grid/filters/range',
                    rangeType: 'text'
                }
            }
        },
        chipsConfig: {
            name: '${ $.name }_chips',
            provider: '${ $.chipsConfig.name }',
            component: 'Magento_Ui/js/grid/filters/chips'
        },
        listens: {
            active: 'updatePreviews',
            applied: 'cancel updateActive'
        },
        statefull: {
            applied: true
        },
        exports: {
            applied: '${ $.provider }:params.filters'
        },
        imports: {
            onColumnsUpdate: '${ $.columnsProvider }:elems',
            onBackendError: '${ $.provider }:lastError',
            bookmarksActiveIndex: '${ $.bookmarksProvider }:activeIndex'
        },
        modules: {
            columns: '${ $.columnsProvider }',
            chips: '${ $.chipsConfig.provider }'
        }
    },

    /**
     * Initializes filters component.
     *
     * @returns {Filters} Chainable.
     */
    initialize: function () {
        _.bindAll(this, 'updateActive');

        this._super()
            .initChips()
            .cancel();

        return this;
    },

    /**
     * Initializes observable properties.
     *
     * @returns {Filters} Chainable.
     */
    initObservable: function () {
        this._super()
            .track({
                active: [],
                previews: []
            });

        return this;
    },

    /**
     * Initializes chips component.
     *
     * @returns {Filters} Chainable.
     */
    initChips: function () {
        layout([this.chipsConfig]);

        this.chips('insertChild', this.name);

        return this;
    },

    /**
     * Called when another element was added to filters collection.
     *
     * @returns {Filters} Chainable.
     */
    initElement: function (elem) {
        this._super();

        elem.on('elems', this.updateActive);

        this.updateActive();

        return this;
    },

    /**
     * Clears filters data.
     *
     * @param {Object} [filter] - If provided, then only specified
     *      filter will be cleared. Otherwise, clears all data.
     * @returns {Filters} Chainable.
     */
    clear: function (filter) {
        filter ?
            filter.clear() :
            _.invoke(this.active, 'clear');

        this.apply();

        return this;
    },

    /**
     * Sets filters data to the applied state.
     *
     * @returns {Filters} Chainable.
     */
    apply: function () {
        this.set('applied', removeEmpty(this.filters));

        return this;
    },

    /**
     * Resets filters to the last applied state.
     *
     * @returns {Filters} Chainable.
     */
    cancel: function () {
        this.set('filters', utils.copy(this.applied));

        return this;
    },

    /**
     * Sets provided data to filter components (without applying it).
     *
     * @param {Object} data - Filters data.
     * @param {Boolean} [partial=false] - Flag that defines whether
     *      to completely replace current filters data or to extend it.
     * @returns {Filters} Chainable.
     */
    setData: function (data, partial) {
        var filters = partial ? this.filters : {};

        data = utils.extend({}, filters, data);

        this.set('filters', data);

        return this;
    },

    /**
     * Creates instance of a filter associated with the provided column.
     *
     * @param {Column} column - Column component for which to create a filter.
     * @returns {Filters} Chainable.
     */
    addFilter: function (column) {
        var index       = column.index,
            processed   = this._processed,
            filter;

        if (!column.filter || _.contains(processed, index)) {
            return this;
        }

        filter = this.buildFilter(column);

        processed.push(index);

        layout([filter]);

        return this;
    },

    /**
     * Creates filter component configuration associated with the provided column.
     *
     * @param {Column} column - Column component whith a basic filter declaration.
     * @returns {Object} Filters' configuration.
     */
    buildFilter: function (column) {
        var filters = this.templates.filters,
            filter  = column.filter,
            type    = filters[filter.filterType];

        if (_.isObject(filter) && type) {
            filter = utils.extend({}, type, filter);
        } else if (_.isString(filter)) {
            filter = filters[filter];
        }

        filter = utils.extend({}, filters.base, filter);

        return utils.template(filter, {
            filters: this,
            column: column
        }, true, true);
    },

    /**
     * Returns an array of range filters.
     *
     * @returns {Array}
     */
    getRanges: function () {
        return this.elems.filter(function (filter) {
            return filter.isRange;
        });
    },

    /**
     * Returns an array of non-range filters.
     *
     * @returns {Array}
     */
    getPlain: function () {
        return this.elems.filter(function (filter) {
            return !filter.isRange;
        });
    },

    /**
     * Tells wether specified filter should be visible.
     *
     * @param {Object} filter
     * @returns {Boolean}
     */
    isFilterVisible: function (filter) {
        return filter.visible() || this.isFilterActive(filter);
    },

    /**
     * Checks if specified filter is active.
     *
     * @param {Object} filter
     * @returns {Boolean}
     */
    isFilterActive: function (filter) {
        return _.contains(this.active, filter);
    },

    /**
     * Checks if collection has visible filters.
     *
     * @returns {Boolean}
     */
    hasVisible: function () {
        return this.elems.some(this.isFilterVisible, this);
    },

    /**
     * Finds filters whith a not empty data
     * and sets them to the 'active' filters array.
     *
     * @returns {Filters} Chainable.
     */
    updateActive: function () {
        var applied = _.keys(this.applied);

        this.active = this.elems.filter(function (elem) {
            return _.contains(applied, elem.index);
        });

        return this;
    },

    /**
     * Returns number of applied filters.
     *
     * @returns {Number}
     */
    countActive: function () {
        return this.active.length;
    },

    /**
     * Extract previews of a specified filters.
     *
     * @param {Array} filters - Filters to be processed.
     * @returns {Filters} Chainable.
     */
    updatePreviews: function (filters) {
        var previews = filters.map(extractPreview);

        this.previews = _.compact(previews);

        return this;
    },

    /**
     * Listener of the columns provider children array changes.
     *
     * @param {Array} columns - Current columns list.
     */
    onColumnsUpdate: function (columns) {
        columns.forEach(this.addFilter, this);
    },

    /**
     * Provider ajax error listener.
     *
     * @param {bool} isError - Selected index of the filter.
     */
    onBackendError: function (isError) {
        var defaultMessage = 'Something went wrong with processing the default view and we have restored the ' +
                'filter to its original state.',
            customMessage  = 'Something went wrong with processing current custom view and filters have been ' +
                'reset to its original state. Please edit filters then click apply.';

        if (isError) {
            this.clear();

            $('body').notification('clear')
                .notification('add', {
                    error: true,
                    message: $.mage.__(this.bookmarksActiveIndex !== 'default' ? customMessage : defaultMessage),

                    /**
                     * @param {String} message
                     */
                    insertMethod: function (message) {
                        var $wrapper = $('<div/>').html(message);

                        $('.page-main-actions').after($wrapper);
                    }
                });
        }
    }
});
});

3. Run below commands

php bin/magento setup:upgrade

php bin/magento setup:static-content:deploy

  • You shouldn't copy latest versions filters.js file, because, it may affect to other functions or functionality. Kindly replace that removeEmpty function in new override file. – kunj May 11 '18 at 18:51
  • You can try magento 2 js mixin, that is best way to override only one function of core JS. – kunj May 11 '18 at 19:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.