[miniShop2] Группируем поля на вкладке "Свойства товара"

Всем привет, небольшая инструкция про кастомизацию вкладки «Свойства товара» у miniShop2.

Стандартный вид этой вкладки:


Как мы все знаем, на ней поля выводятся в 2х колонках, какой-либо группировки не предусмотрено.

Недостатки:
— если полей много, в них путаешься;
— тяжело расположить поля логично;
— если вы поместите checkbox куда-либо в середину — вся сетка сбивается.

Что ж, попробуем сделать так:



Основные шаги:

1. Плагин на событие msOnManagerCustomCssJs, назовем его miniShop2_extend:
В плагине мы просто подключаем js файл на странице редактирования товара.
<?php
switch ($modx->event->name) {
    case 'msOnManagerCustomCssJs':
        if ($page == 'product_update' || $page == 'product_create') {
            $modx->controller->addLastJavascript(MODX_ASSETS_URL.'components/minishop2/plugins/ms2productextend.js');
        }
     break;
}

2. Создадим файл ms2productextend.js
в каталоге
/assets/components/minishop2/plugins/ms2productextend.js

Что мы сделаем:

За вывод вкладки «Свойства товара» отвечает функция miniShop2.panel.Product.getProductFields, описанная в файле /assets/components/minishop2/js/mgr/product/product.common.js

Мы ее перепишем на свой лад:
— сначала в переменную override_fields запишем все те поля, которые отображаем вручную;
— далее стандартный вывод, но пропускаем наши override_fields;
— потом выведем наши поля так, как нам нужно.

В моем примере у товара добавлены вот такие поля, помимо стандартных, не удивляйтесь: supplier, price_supplier, site_source, price_retail.

Код простой, но свою задачу выполняет.

Ext.override(miniShop2.panel.Product, {
    getProductFields: function (config) {

        // Поля, которыми мы будем управлять вручную
        var override_fields = ['new', 'favorite', 'popular', 'supplier', 'price_supplier', 'site_source', 'price_retail'];

        var enabled = miniShop2.config.data_fields;
        var available = miniShop2.config.extra_fields;

        var product_fields = this.getAllProductFields(config);
        var col1 = [];
        var col2 = [];
        var tmp;
        for (var i = 0; i < available.length; i++) {
            var field = available[i];
            this.active_fields = [];
            if ((enabled.length > 0 && enabled.indexOf(field) === -1)
                || this.active_fields.indexOf(field) !== -1) {
                continue;
            }

            // Если это поле, поведение которого мы переопределили, то просто добавляем его в active_fields
            // но не выводим
            if (override_fields.indexOf(field) !== -1) {
                this.active_fields.push(field);
                continue;
            }

            if (tmp = product_fields[field]) {
                this.active_fields.push(field);
                tmp = this.getExtField(config, field, tmp);
                if (i % 2) {
                    col2.push(tmp);
                } else {
                    col1.push(tmp);
                }
            }
        }

        return {
            title: _('ms2_tab_product_data'),
            id: 'minishop2-product-data',
            bodyCssClass: 'main-wrapper',
            items: [{
                layout: 'column',
                items: [{
                    columnWidth: .5,
                    layout: 'form',
                    id: 'minishop2-product-data-left',
                    labelAlign: 'top',
                    items: col1,
                }, {
                    columnWidth: .5,
                    layout: 'form',
                    id: 'minishop2-product-data-right',
                    labelAlign: 'top',
                    items: col2,
                }],
            }, {
                html: '<h3>Метки к товару</h3>',
                style: 'margin-top: 30px;border-bottom: solid 1px #e4e4e4;',
                border: false
            }, {
                layout: 'column',
                items: [{
                    columnWidth: .5,
                    layout: 'form',
                    id: 'minishop2-product-data-checkboxes',
                    labelAlign: 'top',
                    items: [
                        this.getExtField(config, 'new', product_fields['new']),
                        this.getExtField(config, 'favorite', product_fields['favorite']),
                        this.getExtField(config, 'popular', product_fields['popular'])
                    ],
                }],
            }, {
                html: '<h3>Информация о поставщике</h3>',
                style: 'margin-top: 30px;border-bottom: solid 1px #e4e4e4;',
                border: false
            }, {
                layout: 'column',
                items: [{
                    columnWidth: .35,
                    layout: 'form',
                    id: 'minishop2-product-data-supplier-left',
                    labelAlign: 'top',
                    items: [
                        this.getExtField(config, 'supplier', product_fields['supplier']),
                        this.getExtField(config, 'price_supplier', product_fields['price_supplier'])
                    ],
                },{
                    columnWidth: .65,
                    layout: 'form',
                    id: 'minishop2-product-data-supplier-right',
                    labelAlign: 'top',
                    items: [
                        this.getExtField(config, 'site_source', product_fields['site_source']),
                        this.getExtField(config, 'price_retail', product_fields['price_retail'])
                    ],
                }],
            }
            ],
            listeners: {},
        };
    }
});
Результат — приведен на скриншоте в первой половине статьи.
Наумов Алексей
20 июля 2021, 17:09
modx.pro
12
1 067
+13
Поблагодарить автора Отправить деньги

Комментарии: 3

Роман
21 июля 2021, 11:54
+1
Намного удобнее, и сразу все понятно, где и что должно заполнятся.
    Дима Сайт
    23 июля 2021, 20:57
    +1
    @Наумов Алексей, спасибо, отличный пример!
    Не занудства ради, ибо сам не привыкну никак, но хочется уточнить что в «новом модном JS» принято неизменяемые переменные объявлять через const, то есть:
    const override_field ... const enabled ... const available ... const override_fields
    А изменяемые, если им не нужна глобальная область видимости, через
    let tmp;
      Наумов Алексей
      26 июля 2021, 10:42
      0
      Может быть, да)
      но код в посте на 90% взят с минишопа, а написан он уже несколько лет назад
      Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
      3