0

I'm currently attempting to change the "sizes.js" file using a child theme in adminhtml. This is with the "Commerce" version of Magento 2.2.5.

As we have a large number of customers and orders. What I'm trying to do is modify the paging sizes so that instead of the default "20, 30, 50, 100, 200" it uses the values "50, 100, 500, 1000, 2000". The "Custom" option is insufficient for this as this needs to be available for all users and the custom option will only allow values up to 999.

Looking into the background it would seem that the file I need to overwrite is the following one:

vendor > magento > module-ui > view > base > web > js > grid > paging > sizes.js

I've created a new theme using the vendor "TCT" and the theme "Joy". I've added a new "sizes.js" file at the location below:

app > design > adminhtml > TCT > joy > web > js > sizes.js

...containing the following code:

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

/**
 * @api
 */
define([
    'ko',
    'underscore',
    'mageUtils',
    'uiElement'
], function (ko, _, utils, Element) {
    'use strict';

    return Element.extend({
        defaults: {
            template: 'ui/grid/paging/sizes',
            value: 20,
            minSize: 1,
            maxSize: 9999,
            options: {
                '50': {
                    value: 50,
                    label: 50
                },
                '100': {
                    value: 100,
                    label: 100
                },
                '500': {
                    value: 500,
                    label: 500
                },
                '1000': {
                    value: 1000,
                    label: 1000
                },
                '2000': {
                    value: 2000,
                    label: 2000
                }
            },
            statefull: {
                options: true,
                value: true
            },
            listens: {
                value: 'onValueChange',
                options: 'onSizesChange'
            }
        },

        /**
         * Initializes sizes component.
         *
         * @returns {Sizes} Chainable.
         */
        initialize: function () {
            this._super()
                .updateArray();

            return this;
        },

        /**
         * Initializes observable properties.
         *
         * @returns {Sizes} Chainable.
         */
        initObservable: function () {
            this._super()
                .track([
                    'value',
                    'editing',
                    'customVisible',
                    'customValue'
                ])
                .track({
                    optionsArray: []
                });

            this._value = ko.pureComputed({
                read: ko.getObservable(this, 'value'),

                /**
                 * Validates input field prior to updating 'value' property.
                 */
                write: function (value) {
                    value = this.normalize(value);

                    this.value = value;
                    this._value.notifySubscribers(value);
                },

                owner: this
            });

            return this;
        },

        /**
         * Starts editing of the specified size.
         *
         * @param {Number} value - Value of the size.
         * @returns {Sizes} Chainable.
         */
        edit: function (value) {
            this.editing = value;

            return this;
        },

        /**
         * Discards changes made to the currently editable size.
         *
         * @returns {Sizes} Chainable.
         */
        discardEditing: function () {
            var value = this.editing;

            if (value) {
                this.updateSize(value, value);
            }

            return this;
        },

        /**
         * Invokes 'discardEditing' and 'discardCustom' actions.
         *
         * @returns {Sizes} Chainable.
         */
        discardAll: function () {
            this.discardEditing()
                .discardCustom();

            return this;
        },

        /**
         * Returns value of the first size.
         *
         * @returns {Number}
         */
        getFirst: function () {
            return this.optionsArray[0].value;
        },

        /**
         * Returns size which matches specified value.
         *
         * @param {Number} value - Value of the item.
         * @returns {Object|Undefined}
         */
        getSize: function (value) {
            return this.options[value];
        },

        /**
         * Sets current size to the specified value.
         *
         * @param {Number} value - Value of the size.
         * @returns {Sizes} Chainable.
         */
        setSize: function (value) {
            this.value = value;

            return this;
        },

        /**
         * Adds a new value to sizes list.
         *
         * @param {Number} value - Value to be added.
         * @returns {Sizes} Chainable.
         */
        addSize: function (value) {
            var size;

            if (!this.hasSize(value)) {
                size = this.createSize(value);

                this.set('options.' + value, size);
            }

            return this;
        },

        /**
         * Removes provided value from the sizes list.
         *
         * @param {Number} value - Value to be removed.
         * @returns {Sizes} Chainable.
         */
        removeSize: function (value) {
            if (!this.hasSize(value)) {
                return this;
            }

            this.remove('options.' + value);

            if (this.isSelected(value)) {
                this.setSize(this.getFirst());
            }

            return this;
        },

        /**
         * Updates existing value to the provided one. If new value
         * is not specified, then sizes' '_value' property will be taken.
         *
         * @param {Number} value - Existing value that should be updated.
         * @param {(Number|String)} [newValue=size._value] - New size value.
         * @returns {Sizes} Chainable.
         */
        updateSize: function (value, newValue) {
            var size = this.getSize(value);

            if (!size) {
                return this;
            }

            newValue = newValue || size._value;

            if (isNaN(+newValue)) {
                this.discardEditing();

                return this;
            }

            newValue = this.normalize(newValue);

            this.remove('options.' + value)
                .addSize(newValue);

            if (this.isSelected(value)) {
                this.setSize(newValue);
            }

            return this;
        },

        /**
         * Creates new editable size instance with the provided value.
         *
         * @param {Number} value - Value of the size.
         * @returns {Object}
         */
        createSize: function (value) {
            return {
                value: value,
                label: value,
                _value: value,
                editable: true
            };
        },

        /**
         * Checks if provided value exists in the sizes list.
         *
         * @param {Number} value - Value to be checked.
         * @returns {Boolean}
         */
        hasSize: function (value) {
            return !!this.getSize(value);
        },

        /**
         * Hides and clears custom field.
         *
         * @returns {Sizes} Chainable.
         */
        discardCustom: function () {
            this.hideCustom()
                .clearCustom();

            return this;
        },

        /**
         * Shows custom field.
         *
         * @returns {Sizes} Chainable.
         */
        showCustom: function () {
            this.customVisible = true;

            return this;
        },

        /**
         * Hides custom field.
         *
         * @returns {Sizes} Chainable.
         */
        hideCustom: function () {
            this.customVisible = false;

            return this;
        },

        /**
         * Empties value of the custom field.
         *
         * @returns {Sizes} Chainable.
         */
        clearCustom: function () {
            this.customValue = '';

            return this;
        },

        /**
         * Adds a new size specified in the custom field.
         *
         * @returns {Sizes} Chainable.
         */
        applyCustom: function () {
            var value = this.customValue;

            value = this.normalize(value);

            this.addSize(value)
                .setSize(value)
                .discardCustom();

            return this;
        },

        /**
         * Checks if custom field is visible.
         *
         * @returns {Boolean}
         */
        isCustomVisible: function () {
            return this.customVisible;
        },

        /**
         * Converts provided value to a number and puts
         * it in range between 'minSize' and 'maxSize' properties.
         *
         * @param {(Number|String)} value - Value to be normalized.
         * @returns {Number}
         */
        normalize: function (value) {
            value = +value;

            if (isNaN(value)) {
                return this.getFirst();
            }

            return utils.inRange(Math.round(value), this.minSize, this.maxSize);
        },

        /**
         * Updates the array of options.
         *
         * @returns {Sizes} Chainable.
         */
        updateArray: function () {
            var array = _.values(this.options);

            this.optionsArray = _.sortBy(array, 'value');

            return this;
        },

        /**
         * Checks if provided value is in editing state.
         *
         * @param {Number} value - Value to be checked.
         * @returns {Boolean}
         */
        isEditing: function (value) {
            return this.editing === value;
        },

        /**
         * Checks if provided value is selected.
         *
         * @param {Number} value - Value to be checked.
         * @returns {Boolean}
         */
        isSelected: function (value) {
            return this.value === value;
        },

        /**
         * Listener of the 'value' property changes.
         */
        onValueChange: function () {
            this.discardAll()
                .trigger('close');
        },

        /**
         * Listener of the 'options' object changes.
         */
        onSizesChange: function () {
            this.editing = false;

            this.updateArray();
        }
    });
});

and a I've also added a "requirejs-config.js" file at the following location:

app > design > adminhtml > TCT > joy > requirejs-config.js

...containing the following code:

var config = {
  "map": {
    "*": {
      "Magento_Ui/js/grid/paging/sizes": "js/sizes"
    }
  }
};

I've cleared the caches and reloaded the admin pages but the paging grid still looks like this:

paging

Despite the developer console appearing as follows:

enter image description here

It appears that the site is loading my amended "sizes.js" and not the base file but the adminhtml doesnot seem to have been amended.

I've looked at questions 161644 and 212303 but these have only gotten me this far.

1 Answer 1

0

As a stop-gap solution I have overwritten the sizes.html file at the following location:

app > design > adminhtml > TCT > Joy > web > templates > template > sizes.html

added the following code into a template file called sizes.html

    <li>
        <div class="selectmenu-item">
            <button class="selectmenu-item-action" type="button" text="1000" click="setSize.bind($data, 1000)"/>
        </div>
    </li>
    <li>
        <div class="selectmenu-item">
            <button class="selectmenu-item-action" type="button" text="2000" click="setSize.bind($data, 2000)"/>
        </div>
    </li>

So the code appears as follows:

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

<div class="selectmenu" collapsible="">
    <div class="selectmenu-value" openCollapsible="">
        <input type="text" ko-value="_value" attr="id: index" autoselect/>
    </div>
    <button class="selectmenu-toggle" type="button" css="_active: $collapsible.opened" toggleCollapsible>
        <span translate="'Select'"/>
    </button>
    <div class="selectmenu-items" css="_active: $collapsible.opened" outerClick="discardAll.bind($data)">
        <ul>
            <li repeat="foreach: optionsArray, item: '$size'" css="_edit: isEditing($size().value)">
                <div class="selectmenu-item-edit" if="$size().editable" keyboard="13: updateSize.bind($data, $size().value, false)">
                    <input class="admin__control-text" type="text"
                        ko-value="$size()._value" hasFocus="isEditing($size().value)"/>
                    <button class="action-save" type="button" click="updateSize.bind($data, $size().value, false)">
                        <span translate="'Save'"/>
                    </button>
                    <button class="action-delete" type="button" click="removeSize.bind($data, $size().value, false)">
                        <span translate="'Delete'"/>
                    </button>
                </div>
                <div class="selectmenu-item">
                    <button class="selectmenu-item-action" type="button" text="$size().label" click="setSize.bind($data, $size().value)"/>
                    <button class="action-edit" type="button" if="$size().editable"
                        data-bind="
                            click: function () {
                                discardCustom().edit($size().value);
                            }">
                        <span translate="'Edit'"/>
                    </button>
                </div>
            </li>
            <li>
                <div class="selectmenu-item">
                    <button class="selectmenu-item-action" type="button" text="1000" click="setSize.bind($data, 1000)"/>
                </div>
            </li>
            <li>
                <div class="selectmenu-item">
                    <button class="selectmenu-item-action" type="button" text="2000" click="setSize.bind($data, 2000)"/>
                </div>
            </li>
            <li css="_edit: isCustomVisible()">
                <div class="selectmenu-item">
                    <button class="selectmenu-item-action" type="button"
                       translate="'Custom'"
                       ko-visible="!isCustomVisible()"
                       data-bind="
                            click: function () {
                                $data.showCustom()
                                    .discardEditing();
                            }"/>
                </div>
                <div class="selectmenu-item-edit" keyboard="13: applyCustom">
                    <input class="admin__control-text" type="text" ko-value="customValue" hasFocus="isCustomVisible()"/>
                    <button class="action-save" type="button" click="applyCustom">
                        <span translate="'Save'"/>
                    </button>
                </div>
            </li>
        </ul>
    </div>
</div>
<label class="admin__control-support-text" translate="'per page'" attr="for: index"/>

I the referenced it in sizes.js with

'templates/sizes',

The admin now appears as follows and appears to work as intended

enter image description here

This may not be the best solution but it will suffice until I can find a better one

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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