Magento 2 | Модификация multiselect

Magento 2 | Модификация multiselect

Очень часто в разработке модулей для Magento 2 мы добавляем возможность настройки этого решения для конечного пользователя, обычно это администратор сайта. Возможность настроить модуль дает гибкость в использовании и выбор требуемых параметров. Но не всегда настройка модуля удобна и понятна и некоторые элементы выбора особенно мульти-список требуют определенных навыков и знаний, чтобы к примеру деактивировать ранее сделанный выбор, ведь многие не знают, что нужно нажимать определенные клавиши на клавиатуре, такие как: CTRL или SHIFT 🙂

 

 

Чтобы облегчить жизнь пользователя, было бы очень кстати иметь рядом с таким списком кнопку, которая деактивирует ранее сделанный выбор.

Добавить кнопку очень просто, нужен компонент который будет расширять уже существующий UIComponent Multiselect и для этого добавим 2 файла в ваш модуль.

/view/adminhtml/web/template/ui/form/element/reset-select.html

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

<select multiple class="admin__control-multiselect" data-bind="
    attr: {
        name: inputName,
        id: uid,
        size: size ? size : '6',
        disabled: disabled,
        'aria-describedby': noticeId,
        placeholder: placeholder
    },
    hasFocus: focused,
    optgroup: options,
    selectedOptions: value,
    optionsValue: 'value',
    optionsText: 'label'"
/>
<div class="admin__field-note">
    <button type="button"
            click="action"
            attr="'data-index': index">
        <span text="title"/>
    </button>
</div>

 

/view/adminhtml/web/js/ui/form/element/reset-select.js

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

/**
 * @api
 */
define([
    'underscore',
    'mageUtils',
    'Magento_Ui/js/form/element/select'
], function (_, utils, Select) {
    'use strict';

    return Select.extend({
        defaults: {
            size: 5,
            listens: {
                value: 'setDifferedFromDefault setPrepareToSendData'
            },
            title: 'Reset'
        },

        /**
         * @inheritdoc
         */
        setInitialValue: function () {
            this._super();

            this.initialValue = utils.copy(this.initialValue);

            return this;
        },

        /**
         * @inheritdoc
         */
        normalizeData: function (value) {
            if (utils.isEmpty(value)) {
                value = [];
            }

            return _.isString(value) ? value.split(',') : value;
        },

        /**
         * Sets the prepared data to dataSource
         * by path, where key is component link to dataSource with
         * suffix "-prepared-for-send"
         *
         * @param {Array} data - current component value
         */
        setPrepareToSendData: function (data) {
            if (_.isUndefined(data) || !data.length) {
                data = '';
            }

            this.source.set(this.dataScope + '-prepared-for-send', data);
        },

        /**
         * @inheritdoc
         */
        getInitialValue: function () {
            var values = [
                    this.normalizeData(this.source.get(this.dataScope)),
                    this.normalizeData(this.default)
                ],
                value;

            values.some(function (v) {
                return _.isArray(v) && (value = utils.copy(v)) && !_.isEmpty(v);
            });

            return value;
        },

        /**
         * @inheritdoc
         */
        hasChanged: function () {
            var value = this.value(),
                initial = this.initialValue;

            return !utils.equalArrays(value, initial);
        },

        /**
         * @inheritdoc
         */
        reset: function () {
            this.value(utils.copy(this.initialValue));
            this.error(false);

            return this;
        },

        /**
         * @inheritdoc
         */
        clear: function () {
            this.value([]);
            this.error(false);

            return this;
        },

        action: function () {
            this.clear();
        },
    });
});

 

и добавим компонент на форму /view/adminhtml/ui_component/form.xml

<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* Copyright 2016 aheadWorks. All rights reserved.
* See LICENSE.txt for license details.
*/
-->

<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <fieldset name="general_fieldset">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="label" xsi:type="string" translate="true">General Information</item>
                <item name="collapsible" xsi:type="boolean">true</item>
                <item name="sortOrder" xsi:type="number">10</item>
                <item name="opened" xsi:type="boolean">true</item>
            </item>
        </argument>
        <field name="subdivision">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <!--component constructor-->
                    <item name="component" xsi:type="string">Magento2_Extension/js/ui/form/element/reset-select</item>
                    <item name="template" xsi:type="string">ui/form/field</item>
                    <item name="elementTmpl" xsi:type="string">Magento2_Extension/ui/form/element/reset-select</item>
                    <item name="label" xsi:type="string">Available for States</item>
                    <item name="notice" xsi:type="string" translate="true">CTRL + Mouse Click</item>
                    <item name="visible" xsi:type="boolean">true</item>
                    <item name="dataType" xsi:type="string">string</item>
                    <item name="formElement" xsi:type="string">multiselect</item>
                    <item name="source" xsi:type="string">slide</item>
                    <item name="sortOrder" xsi:type="number">55</item>
                    <item name="dataScope" xsi:type="string">subdivision</item>
                </item>
                <item name="options" xsi:type="object">Magento2\Extension\Model\Source\Geo\Subdivision</item>
            </argument>
        </field>
        
    </fieldset>
</form>

 

И администратор доволен 🙂