{"id":106051,"date":"2017-12-22T17:28:17","date_gmt":"2017-12-22T17:28:17","guid":{"rendered":"https:\/\/webkul.com\/blog\/?p=106051"},"modified":"2026-02-17T13:40:28","modified_gmt":"2026-02-17T13:40:28","slug":"magento2-create-multi-select-ui-field-frontend-admin","status":"publish","type":"post","link":"https:\/\/webkul.com\/blog\/magento2-create-multi-select-ui-field-frontend-admin\/","title":{"rendered":"Magento 2 Create Multi Select UI Field on Frontend as Admin"},"content":{"rendered":"\n<p>Here we learn how to add or create Multi select field using the Ui Component on frontend.<\/p>\n\n\n\n<p>I am going to take an example of categories multi select files which looks like the below<br>image in admin->catalog New or Edit Product section.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" width=\"1147\" height=\"438\" src=\"https:\/\/cdnblog.webkul.com\/blog\/wp-content\/uploads\/2017\/12\/Screenshot-18.png\" alt=\"Select UI\" class=\"wp-image-106062\" srcset=\"https:\/\/cdnblog.webkul.com\/blog\/wp-content\/uploads\/2017\/12\/Screenshot-18.png 1147w, https:\/\/cdnblog.webkul.com\/blog\/wp-content\/uploads\/2017\/12\/Screenshot-18-250x95.png 250w, https:\/\/cdnblog.webkul.com\/blog\/wp-content\/uploads\/2017\/12\/Screenshot-18-300x115.png 300w, https:\/\/cdnblog.webkul.com\/blog\/wp-content\/uploads\/2017\/12\/Screenshot-18-768x293.png 768w\" sizes=\"(max-width: 1147px) 100vw, 1147px\" loading=\"lazy\" \/><\/figure>\n\n\n\n<p>Let&#8217;s start step by step.<br>You must have installed your custom Module on which you are going to implement this.<\/p>\n\n\n\n<p><strong>1.)<\/strong> Create a xml file which loads your Block and Phtml file.<\/p>\n\n\n\n<p><strong>For Example: Webkul\/Custom\/view\/frontend\/layout\/custom_test_index.xml<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\">&lt;?xml version=&quot;1.0&quot;?&gt;\n&lt;!--\n\/**\n * Webkul Software.\n *\n * @category  Webkul\n * @package   Webkul_Custom\n * @author    Webkul\n * @copyright Webkul Software Private Limited (https:\/\/webkul.com)\n * @license   https:\/\/store.webkul.com\/license.html\n *\/\n--&gt;\n&lt;page xmlns:xsi=&quot;http:\/\/www.w3.org\/2001\/XMLSchema-instance&quot; xsi:noNamespaceSchemaLocation=&quot;urn:magento:framework:View\/Layout\/etc\/page_configuration.xsd&quot;&gt;\n    &lt;update handle=&quot;customer_account&quot;\/&gt;\n    &lt;body&gt;\n        &lt;referenceBlock name=&quot;page.main.title&quot;&gt;\n            &lt;action method=&quot;setPageTitle&quot;&gt;\n                &lt;argument translate=&quot;true&quot; name=&quot;title&quot; xsi:type=&quot;string&quot;&gt;Ui Multi Select&lt;\/argument&gt;\n            &lt;\/action&gt;\n        &lt;\/referenceBlock&gt;\n        &lt;referenceContainer name=&quot;content&quot;&gt;\n            &lt;block class=&quot;Webkul\\Custom\\Block\\Test&quot; name=&quot;ui_multiselect&quot; template=&quot;test.phtml&quot; cacheable=&quot;false&quot;\/&gt;\n        &lt;\/referenceContainer&gt;\n    &lt;\/body&gt;\n&lt;\/page&gt;<\/pre>\n\n\n\n<p><strong>Now,<\/strong> create a Controller file for this.<br><strong>File:<\/strong> <strong>Webkul\/Custom\/Controller\/Test\/Index.php<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\">&lt;?php\nnamespace Webkul\\Custom\\Controller\\Test;\n\nuse Magento\\Framework\\App\\Action\\Context;\nuse Magento\\Framework\\View\\Result\\PageFactory;\nuse Magento\\Framework\\App\\RequestInterface;\nuse Magento\\Customer\\Model\\Url as CustomerUrl;\n\nclass Index extends \\Magento\\Customer\\Controller\\AbstractAccount\n{\n    \/**\n     * @var \\Magento\\Customer\\Model\\Session\n     *\/\n    protected $customerSession;\n\n    \/**\n     * @var PageFactory\n     *\/\n    protected $resultPageFactory;\n\n    \/**\n     * @var CustomerUrl\n     *\/\n    protected $customerUrl;\n\n   \/**\n    * Construct\n    *\n    * @param Context $context\n    * @param PageFactory $resultPageFactory\n    * @param \\Magento\\Customer\\Model\\Session $customerSession\n    * @param CustomerUrl $customerUrl\n    *\/\n    public function __construct(\n        Context $context,\n        PageFactory $resultPageFactory,\n        \\Magento\\Customer\\Model\\Session $customerSession,\n        CustomerUrl $customerUrl\n    ) {\n        $this-&gt;customerSession = $customerSession;\n        $this-&gt;resultPageFactory = $resultPageFactory;\n        $this-&gt;customerUrl = $customerUrl;\n        parent::__construct($context);\n    }\n\n    \/**\n     * Check customer authentication.\n     *\n     * @param RequestInterface $request\n     *\n     * @return \\Magento\\Framework\\App\\ResponseInterface\n     *\/\n    public function dispatch(RequestInterface $request)\n    {\n        $loginUrl = $this-&gt;customerUrl-&gt;getLoginUrl();\n\n        if (!$this-&gt;customerSession-&gt;authenticate($loginUrl)) {\n            $this-&gt;_actionFlag-&gt;set(&#039;&#039;, self::FLAG_NO_DISPATCH, true);\n        }\n\n        return parent::dispatch($request);\n    }\n\n    \/**\n     * Execute Action\n     *\n     * @return void\n     *\/\n    public function execute()\n    {\n        $resultPage = $this-&gt;resultPageFactory-&gt;create();\n        $resultPage-&gt;getConfig()-&gt;getTitle()-&gt;set(__(&#039;Ui Multi Select&#039;));\n\n        return $resultPage;\n    }\n}<\/pre>\n\n\n\n<p><strong>2.) <\/strong> Now Create the respective Block.<br><strong>Webkul\/Custom\/Block\/Test.php<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\">&lt;?php\n\/**\n * Webkul Software.\n *\n * @category  Webkul\n * @package   Webkul_Custom\n * @author    Webkul\n * @copyright Webkul Software Private Limited (https:\/\/webkul.com)\n * @license   https:\/\/store.webkul.com\/license.html\n *\/\nnamespace Webkul\\Custom\\Block;\n\nuse Magento\\Store\\Model\\StoreManagerInterface;\nuse Magento\\Framework\\App\\Filesystem\\DirectoryList;\n\nclass Test extends \\Magento\\Framework\\View\\Element\\Template\n{\n    \/**\n     * @var \\Magento\\Framework\\Data\\Form\\FormKey\n     *\/\n    protected $formKey;\n\n    \/**\n     * @var \\Magento\\Framework\\App\\Config\\ScopeConfigInterface\n     *\/\n    protected $_scopeConfig;\n\n    \/**\n     * @var \\Magento\\Framework\\UrlInterface\n     *\/\n    protected $_urlBuilder;\n\n    \/**\n     * @param \\Magento\\Backend\\Block\\Template\\Context $context\n     * @param \\Magento\\Framework\\View\\Model\\PageLayout\\Config\\BuilderInterface $pageLayoutBuilder\n     * @param \\Magento\\Framework\\ObjectManagerInterface $objectManager\n     * @param array $data\n     *\/\n    public function __construct(\n        \\Magento\\Backend\\Block\\Template\\Context $context,\n        \\Magento\\Framework\\View\\Model\\PageLayout\\Config\\BuilderInterface $pageLayoutBuilder,\n        \\Magento\\Framework\\ObjectManagerInterface $objectManager,\n        array $data = &#091;]\n    ) {\n        $this-&gt;_objectManager = $objectManager;\n        $this-&gt;formKey = $context-&gt;getFormKey();\n        parent::__construct($context, $data);\n    }\n\n    \/**\n     * Prepare layout\n     *\n     * @return this\n     *\/\n    public function _prepareLayout()\n    {\n        return parent::_prepareLayout();\n    }\n    \n    public function getCategoriesTree()\n    {\n        $categories = $this-&gt;_objectManager-&gt;create(\n            &#039;Magento\\Catalog\\Ui\\Component\\Product\\Form\\Categories\\Options&#039;\n        )-&gt;toOptionArray();\n        return json_encode($categories);\n    }\n}<\/pre>\n\n\n\n<p>In above Block file getCategoriesTree() Method loads the all Categories in array form. Its just<br>an example, you can pass your custom array to display in the field.<\/p>\n\n\n\n<p><strong>3.)<\/strong> Create the phtml template file.<br><strong>Webkul\/Custom\/view\/frontend\/templates\/test.phtml<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\">&lt;form action=&quot;&lt;?php echo $block-&gt;getUrl(&#039;custom\/manage\/save&#039;, &#091;&#039;_secure&#039; =&gt; $this-&gt;getRequest()-&gt;isSecure()]) ?&gt;&quot; enctype=&quot;multipart\/form-data&quot; method=&quot;post&quot;  data-mage-init=&#039;{&quot;validation&quot;:{}}&#039;&gt;\n    &lt;fieldset class=&quot;fieldset&quot;&gt;\n        &lt;div class=&quot;field required&quot;&gt;\n            &lt;label class=&quot;label&quot;&gt;&lt;?php echo __(&#039;Select Category&#039;) ?&gt;:&lt;\/label&gt;\n            &lt;div data-bind=&quot;scope: &#039;customCategory&#039;&quot;&gt;\n                &lt;!-- ko template: getTemplate() --&gt;&lt;!-- \/ko --&gt;\n            &lt;\/div&gt;\n            &lt;script type=&quot;text\/x-magento-init&quot;&gt;\n                {\n                    &quot;*&quot;: {\n                        &quot;Magento_Ui\/js\/core\/app&quot;: {\n                            &quot;components&quot;: {\n                                &quot;customCategory&quot;: {\n                                    &quot;component&quot;: &quot;Magento_Ui\/js\/form\/element\/ui-select&quot;,\n                                    &quot;template&quot; : &quot;Webkul_Custom\/ui-select&quot;,\n                                    &quot;filterOptions&quot;: true,\n                                    &quot;levelsVisibility&quot;: &quot;1&quot;,\n                                    &quot;multiple&quot;: true,\n                                    &quot;showCheckbox&quot;: true,\n                                    &quot;options&quot;: &lt;?php echo $block-&gt;getCategoriesTree()?&gt;\n                                }\n                            }\n                        }\n                    }\n                }\n            &lt;\/script&gt;\n        &lt;\/div&gt;\n    &lt;\/fieldset&gt;\n&lt;\/form&gt;<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">How to Create Multi Select UI Field on Frontend as Admin<\/h3>\n\n\n\n<p>In above template file, we have instantiated ui-select.js component and its default values.<br>You can customize this ui-select fields according to your choice. Like you can disable multiple, showCheckbox etc.<\/p>\n\n\n\n<p>For more default options of ui-select you can view this file:<br>Magento_Ui\/js\/form\/element\/ui-select.js<\/p>\n\n\n\n<p>For Now let&#8217;s create the ui-select.html template which we have used in customCategory component.<br><strong>Webkul\/<strong>Custom<\/strong>\/view\/frontend\/web\/template\/ui-select.html<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\">&lt;!-- ko ifnot: disableLabel --&gt;\n&lt;label class=&quot;admin__form-field-label&quot; data-bind=&quot;attr: {for: uid}\n&quot;&gt;\n    &lt;span translate=&quot;label&quot;&gt;&lt;\/span&gt;\n&lt;\/label&gt;\n&lt;!-- \/ko --&gt;\n&lt;div class=&quot;admin__action-multiselect-wrap action-select-wrap&quot; tabindex=&quot;0&quot; data-bind=&quot;\nattr: {\n    id: uid\n},\ncss: {\n    _active: listVisible,\n    &#039;admin__action-multiselect-tree&#039;: isTree()\n},\nevent: {\n    focusin: onFocusIn,\n    focusout: onFocusOut,\n    keydown: keydownSwitcher\n},\nouterClick: outerClick.bind($data)\n&quot;&gt;\n    &lt;!-- ko ifnot: chipsEnabled --&gt;\n    &lt;div class=&quot;action-select admin__action-multiselect&quot; data-role=&quot;advanced-select&quot; data-bind=&quot;\n    css: {_active: multiselectFocus},\n    click: function(data, event) {\n        toggleListVisible(data, event)\n    }\n&quot;&gt;\n        &lt;div class=&quot;admin__action-multiselect-text&quot; data-role=&quot;selected-option&quot; data-bind=&quot;text: setCaption()&quot;&gt;\n        &lt;\/div&gt;\n        &lt;!-- ko foreach: { data: getSelected(), as: &#039;option&#039;}  --&gt;\n        &lt;input type=&quot;hidden&quot; name=&quot;category_id&quot; data-bind=&quot;\n            attr: {\n                id: &#039;wk-cat-hide&#039;+value,\n                value: value\n            }\n        &quot;&gt;\n        &lt;!-- \/ko --&gt;\n    &lt;\/div&gt;\n    &lt;!-- \/ko --&gt;\n    &lt;!-- ko if: chipsEnabled --&gt;\n    &lt;div class=&quot;action-select admin__action-multiselect&quot; data-role=&quot;advanced-select&quot; data-bind=&quot;\n    css: {_active: multiselectFocus},\n    click: function(data, event) {\n        toggleListVisible(data, event)\n    }\n&quot;&gt;\n        &lt;div class=&quot;admin__action-multiselect-text&quot; data-bind=&quot;\n        visible: !hasData(),\n        i18n: selectedPlaceholders.defaultPlaceholder\n&quot;&gt;\n        &lt;\/div&gt;\n        &lt;!-- ko foreach: { data: getSelected(), as: &#039;option&#039;}  --&gt;\n        &lt;span class=&quot;admin__action-multiselect-crumb&quot;&gt;\n            &lt;span data-bind=&quot;text: label&quot;&gt;\n            &lt;\/span&gt;\n            &lt;button class=&quot;action-close&quot; type=&quot;button&quot; data-action=&quot;remove-selected-item&quot; tabindex=&quot;-1&quot; data-bind=&quot;click: $parent.removeSelected.bind($parent, value)\n        &quot;&gt;\n                &lt;span class=&quot;action-close-text&quot; translate=&quot;&#039;Close&#039;&quot;&gt;&lt;\/span&gt;\n            &lt;\/button&gt;\n        &lt;\/span&gt;\n        &lt;!-- \/ko --&gt;\n    &lt;\/div&gt;\n    &lt;!-- \/ko --&gt;\n    &lt;div class=&quot;action-menu&quot; data-bind=&quot;css: { _active: listVisible }\n&quot;&gt;\n        &lt;!-- ko if: filterOptions --&gt;\n        &lt;div class=&quot;admin__action-multiselect-search-wrap&quot;&gt;\n            &lt;input class=&quot;admin__control-text admin__action-multiselect-search&quot; data-role=&quot;advanced-select-text&quot; type=&quot;text&quot; data-bind=&quot;\n        event: {\n            keydown: filterOptionsKeydown\n        },\n        attr: {id: uid+2},\n        valueUpdate: &#039;afterkeydown&#039;,\n        value: filterInputValue,\n        hasFocus: filterOptionsFocus\n        &quot;&gt;\n            &lt;label class=&quot;admin__action-multiselect-search-label&quot; data-action=&quot;advanced-select-search&quot; data-bind=&quot;attr: {for: uid+2}\n    &quot;&gt;\n            &lt;\/label&gt;\n            &lt;div if=&quot;itemsQuantity&quot; data-bind=&quot;text: itemsQuantity&quot; class=&quot;admin__action-multiselect-search-count&quot;&gt;\n            &lt;\/div&gt;\n        &lt;\/div&gt;\n        &lt;!-- \/ko --&gt;\n        &lt;ul class=&quot;admin__action-multiselect-menu-inner _root&quot; data-bind=&quot;\n        event: {\n            mousemove: function(data, event){onMousemove($data, event)}\n        }\n    &quot;&gt;\n            &lt;!-- ko foreach: { data: options, as: &#039;option&#039;}  --&gt;\n            &lt;li class=&quot;admin__action-multiselect-menu-inner-item _root&quot; data-bind=&quot;css: { _parent: $data.optgroup }&quot; data-role=&quot;option-group&quot;&gt;\n                &lt;div class=&quot;action-menu-item&quot; data-bind=&quot;\n                css: {\n                    _selected: $parent.isSelected(option.value),\n                    _hover: $parent.isHovered(option, $element),\n                    _expended: $parent.getLevelVisibility($data),\n                    _unclickable: $parent.isLabelDecoration($data),\n                    _last: $parent.addLastElement($data),\n                    &#039;_with-checkbox&#039;: $parent.showCheckbox\n                },\n                click: function(data, event){\n                    $parent.toggleOptionSelected($data, event);\n                },\n                clickBubble: false\n        &quot;&gt;\n                    &lt;!-- ko if: $data.optgroup &amp;&amp; $parent.showOpenLevelsActionIcon--&gt;\n                    &lt;div class=&quot;admin__action-multiselect-dropdown&quot; data-bind=&quot;\n                    click: function(event){\n                        $parent.openChildLevel($data, $element, event);\n                    },\n                    clickBubble: false\n                 &quot;&gt;\n                    &lt;\/div&gt;\n                    &lt;!-- \/ko--&gt;\n                    &lt;!--ko if: $parent.showCheckbox--&gt;\n                    &lt;input class=&quot;admin__control-checkbox&quot; type=&quot;checkbox&quot; tabindex=&quot;-1&quot; data-bind=&quot;attr: { &#039;checked&#039;: $parent.isSelected(option.value) }&quot;&gt;\n                    &lt;!-- \/ko--&gt;\n                    &lt;label class=&quot;admin__action-multiselect-label&quot;&gt;\n                        &lt;span data-bind=&quot;text: option.label&quot;&gt;&lt;\/span&gt;\n                        &lt;span if=&quot;$parent.getPath(option)&quot; class=&quot;admin__action-multiselect-item-path&quot; data-bind=&quot;text: $parent.getPath(option)&quot;&gt;&lt;\/span&gt;\n                    &lt;\/label&gt;\n                &lt;\/div&gt;\n                &lt;!-- ko if: $data.optgroup --&gt;\n                &lt;!-- ko template: {name: $parent.optgroupTmpl, data: {root: $parent, current: $data}} --&gt;\n                &lt;!-- \/ko --&gt;\n                &lt;!-- \/ko--&gt;\n            &lt;\/li&gt;\n            &lt;!-- \/ko --&gt;\n        &lt;\/ul&gt;\n        &lt;!-- ko if: $data.closeBtn --&gt;\n        &lt;div class=&quot;admin__action-multiselect-actions-wrap&quot;&gt;\n            &lt;button class=&quot;action-default&quot; data-action=&quot;close-advanced-select&quot; type=&quot;button&quot; data-bind=&quot;click: outerClick&quot;&gt;\n                &lt;span translate=&quot;closeBtnLabel&quot;&gt;&lt;\/span&gt;\n            &lt;\/button&gt;\n        &lt;\/div&gt;\n        &lt;!-- \/ko --&gt;\n    &lt;\/div&gt;\n&lt;\/di\n\n&lt;strong&gt;Also,&lt;\/strong&gt; you can use your own  ui-select.js in component as: &lt;strong&gt;Webkul_Custom\/js\/form\/element\/ui-select.js&lt;\/strong&gt;<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\">define(&#091;\n    &#039;underscore&#039;,\n    &#039;Magento_Ui\/js\/form\/element\/abstract&#039;,\n    &#039;Magento_Ui\/js\/lib\/key-codes&#039;,\n    &#039;mage\/translate&#039;,\n    &#039;ko&#039;,\n    &#039;jquery&#039;,\n    &#039;Magento_Ui\/js\/lib\/view\/utils\/async&#039;\n], function (_, Abstract, keyCodes, $t, ko, $) {\n    &#039;use strict&#039;;\n\n    var isTouchDevice = typeof document.ontouchstart !== &#039;undefined&#039;;\n\n    \/**\n     * Processing options list\n     *\n     * @param {Array} array - Property array\n     * @param {String} separator - Level separator\n     * @param {Array} created - list to add new options\n     *\n     * @return {Array} Plain options list\n     *\/\n    function flattenCollection(array, separator, created)\n    {\n        var i = 0,\n            length,\n            childCollection;\n\n        array = _.compact(array);\n        length = array.length;\n        created = created || &#091;];\n\n        for (i; i &lt; length; i++) {\n            created.push(array&#091;i]);\n\n            if (array&#091;i].hasOwnProperty(separator)) {\n                childCollection = array&#091;i]&#091;separator];\n                delete array&#091;i]&#091;separator];\n                flattenCollection.call(this, childCollection, separator, created);\n            }\n        }\n\n        return created;\n    }\n\n    \/**\n     * Set levels to options list\n     *\n     * @param {Array} array - Property array\n     * @param {String} separator - Level separator\n     * @param {Number} level - Starting level\n     * @param {String} path - path to root\n     *\n     * @returns {Array} Array with levels\n     *\/\n    function setProperty(array, separator, level, path)\n    {\n        var i = 0,\n            length,\n            nextLevel,\n            nextPath;\n\n        array = _.compact(array);\n        length = array.length;\n        level = level || 0;\n        path = path || &#039;&#039;;\n\n        for (i; i &lt; length; i++) {\n            if (array&#091;i]) {\n                _.extend(array&#091;i], {\n                    level: level,\n                    path: path\n                });\n            }\n\n            if (array&#091;i].hasOwnProperty(separator)) {\n                nextLevel = level + 1;\n                nextPath = path ? path + &#039;.&#039; + array&#091;i].label : array&#091;i].label;\n                setProperty.call(this, array&#091;i]&#091;separator], separator, nextLevel, nextPath);\n            }\n        }\n\n        return array;\n    }\n\n    \/**\n     * Preprocessing options list\n     *\n     * @param {Array} nodes - Options list\n     *\n     * @return {Object} Object with property - options(options list)\n     *      and cache options with plain and tree list\n     *\/\n    function parseOptions(nodes)\n    {\n        var caption,\n            value,\n            cacheNodes,\n            copyNodes;\n\n        nodes = setProperty(nodes, &#039;optgroup&#039;);\n        copyNodes = JSON.parse(JSON.stringify(nodes));\n        cacheNodes = flattenCollection(copyNodes, &#039;optgroup&#039;);\n\n        nodes = _.map(nodes, function (node) {\n            value = node.value;\n\n            if (value == null || value === &#039;&#039;) {\n                if (_.isUndefined(caption)) {\n                    caption = node.label;\n                }\n            } else {\n                return node;\n            }\n        });\n\n        return {\n            options: _.compact(nodes),\n            cacheOptions: {\n                plain: _.compact(cacheNodes),\n                tree: _.compact(nodes)\n            }\n        };\n    }\n\n    return Abstract.extend({\n        defaults: {\n            options: &#091;],\n            listVisible: false,\n            value: &#091;],\n            filterOptions: false,\n            chipsEnabled: true,\n            itemsQuantity: &#039;&#039;,\n            filterInputValue: &#039;&#039;,\n            filterOptionsFocus: false,\n            multiselectFocus: false,\n            multiple: true,\n            selectType: &#039;tree&#039;,\n            lastSelectable: false,\n            showFilteredQuantity: true,\n            showCheckbox: true,\n            levelsVisibility: true,\n            openLevelsAction: true,\n            showOpenLevelsActionIcon: true,\n            optgroupLabels: false,\n            closeBtn: true,\n            showPath: true,\n            labelsDecoration: false,\n            disableLabel: false,\n            filterRateLimit: 500,\n            closeBtnLabel: $t(&#039;Done&#039;),\n            optgroupTmpl: &#039;ui\/grid\/filters\/elements\/ui-select-optgroup&#039;,\n            quantityPlaceholder: $t(&#039;options&#039;),\n            hoverClass: &#039;_hover&#039;,\n            rootListSelector: &#039;ul.admin__action-multiselect-menu-inner._root&#039;,\n            visibleOptionSelector: &#039;li.admin__action-multiselect-menu-inner-item:visible&#039;,\n            actionTargetSelector: &#039;.action-menu-item&#039;,\n            selectedPlaceholders: {\n                defaultPlaceholder: $t(&#039;Select...&#039;),\n                lotPlaceholders: $t(&#039;Selected&#039;)\n            },\n            separator: &#039;optgroup&#039;,\n            listens: {\n                listVisible: &#039;cleanHoveredElement&#039;,\n                filterInputValue: &#039;filterOptionsList&#039;,\n                options: &#039;checkOptionsList&#039;\n            },\n            presets: {\n                single: {\n                    showCheckbox: false,\n                    chipsEnabled: false,\n                    closeBtn: false\n                },\n                optgroup: {\n                    showCheckbox: false,\n                    lastSelectable: true,\n                    optgroupLabels: true,\n                    openLevelsAction: false,\n                    labelsDecoration: true,\n                    showOpenLevelsActionIcon: false\n                }\n            }\n        },\n\n        \/**\n         * Initializes UISelect component.\n         *\n         * @returns {UISelect} Chainable.\n         *\/\n        initialize: function () {\n            this._super();\n\n            $.async(\n                this.rootListSelector,\n                this,\n                this.onRootListRender.bind(this)\n            );\n\n            return this;\n        },\n\n        \/**\n         * Parses options and merges the result with instance\n         * Set defaults according to mode and levels configuration\n         *\n         * @param  {Object} config\n         * @returns {Object} Chainable.\n         *\/\n        initConfig: function (config) {\n            var result = parseOptions(config.options),\n                defaults = this.constructor.defaults,\n                multiple = _.isBoolean(config.multiple) ? config.multiple : defaults.multiple,\n                type = config.selectType || defaults.selectType,\n                showOpenLevelsActionIcon = _.isBoolean(config.showOpenLevelsActionIcon) ?\n                    config.showOpenLevelsActionIcon :\n                    defaults.showOpenLevelsActionIcon,\n                openLevelsAction = _.isBoolean(config.openLevelsAction) ?\n                    config.openLevelsAction :\n                    defaults.openLevelsAction;\n\n            multiple = !multiple ? &#039;single&#039; : false;\n            config.showOpenLevelsActionIcon = showOpenLevelsActionIcon &amp;&amp; openLevelsAction;\n            _.extend(config, result, defaults.presets&#091;multiple], defaults.presets&#091;type]);\n            this._super();\n\n            return this;\n        },\n\n        \/**\n         * Check child optgroup\n         *\/\n        hasChildList: function () {\n            return _.find(this.options(), function (option) {\n                return !!option&#091;this.separator];\n            }, this);\n        },\n\n        \/**\n         * Check tree mode\n         *\/\n        isTree: function () {\n            return this.hasChildList() &amp;&amp; this.selectType !== &#039;optgroup&#039;;\n        },\n\n        \/**\n         * Add option to lastOptions array\n         *\n         * @param {Object} data\n         * @returns {Boolean}\n         *\/\n        addLastElement: function (data) {\n            if (!data.hasOwnProperty(this.separator)) {\n                !this.cacheOptions.lastOptions ? this.cacheOptions.lastOptions = &#091;] : false;\n\n                if (!_.findWhere(this.cacheOptions.lastOptions, { value: data.value })) {\n                    this.cacheOptions.lastOptions.push(data);\n                }\n\n                return true;\n            }\n\n            return false;\n        },\n\n        \/**\n         * Check options length and set to cache\n         * if some options is added\n         *\n         * @param {Array} options - ui select options\n         *\/\n        checkOptionsList: function (options) {\n            if (options.length &gt; this.cacheOptions.plain.length) {\n                this.cacheOptions.plain = options;\n                this.setCaption();\n            }\n        },\n\n        \/**\n         * Check label decoration\n         *\/\n        isLabelDecoration: function (data) {\n            return data.hasOwnProperty(this.separator) &amp;&amp; this.labelsDecoration;\n        },\n\n        \/**\n         * Calls &#039;initObservable&#039; of parent, initializes &#039;options&#039; and &#039;initialOptions&#039;\n         *     properties, calls &#039;setOptions&#039; passing options to it\n         *\n         * @returns {Object} Chainable.\n         *\/\n        initObservable: function () {\n            this._super();\n            this.observe(&#091;\n                &#039;listVisible&#039;,\n                &#039;placeholder&#039;,\n                &#039;multiselectFocus&#039;,\n                &#039;options&#039;,\n                &#039;itemsQuantity&#039;,\n                &#039;filterInputValue&#039;,\n                &#039;filterOptionsFocus&#039;\n            ]);\n\n            this.filterInputValue.extend({\n                rateLimit: this.filterRateLimit\n            });\n\n            return this;\n        },\n\n        \/**\n         * object with key - keyname and value - handler function for this key\n         *\n         * @returns {Object} Object with handlers function name.\n         *\/\n        keyDownHandlers: function () {\n            return {\n                enterKey: this.enterKeyHandler,\n                escapeKey: this.escapeKeyHandler,\n                spaceKey: this.enterKeyHandler,\n                pageUpKey: this.pageUpKeyHandler,\n                pageDownKey: this.pageDownKeyHandler\n            };\n        },\n\n        \/**\n         * Processing level visibility for levels\n         *\n         * @param {Object} data - element data\n         *\n         * @returns {Boolean} level visibility.\n         *\/\n        showLevels: function (data) {\n            var curLevel = ++data.level,\n                isVisible;\n\n            if (data.visible) {\n                isVisible = data.visible();\n            } else {\n                isVisible = !!data.hasOwnProperty(this.separator) &amp;&amp;\n                    _.isBoolean(this.levelsVisibility) &amp;&amp;\n                    this.levelsVisibility ||\n                    data.hasOwnProperty(this.separator) &amp;&amp; parseInt(this.levelsVisibility, 10) &gt;= curLevel;\n\n                data.visible = ko.observable(isVisible);\n                data.isVisited = isVisible;\n            }\n\n            return isVisible;\n        },\n\n        \/**\n         * Processing level visibility for levels\n         *\n         * @param {Object} data - element data\n         *\n         * @returns {Boolean} level visibility.\n         *\/\n        getLevelVisibility: function (data) {\n            if (data.visible) {\n                return data.visible();\n            }\n\n            return this.showLevels(data);\n        },\n\n        \/**\n         * Set option to options array.\n         *\n         * @param {Object} option\n         * @param {Array} options\n         *\/\n        setOption: function (option, options) {\n            var copyOptionsTree;\n\n            options = options || this.cacheOptions.tree;\n\n            _.each(options, function (opt) {\n                if (opt.value == option.parent) { \/\/eslint-disable-line eqeqeq\n                    delete  option.parent;\n                    opt&#091;this.separator] ? opt&#091;this.separator].push(option) : opt&#091;this.separator] = &#091;option];\n                    copyOptionsTree = JSON.parse(JSON.stringify(this.cacheOptions.tree));\n                    this.cacheOptions.plain = flattenCollection(copyOptionsTree, this.separator);\n                    this.options(this.cacheOptions.tree);\n                } else if (opt&#091;this.separator]) {\n                    this.setOption(option, opt&#091;this.separator]);\n                }\n            }, this);\n        },\n\n        \/**\n         * Handler outerClick event. Closed options list\n         *\/\n        outerClick: function () {\n            this.listVisible() ? this.listVisible(false) : false;\n\n            if (isTouchDevice) {\n                this.multiselectFocus(false);\n            }\n        },\n\n        \/**\n         * Handler keydown event to filter options input\n         *\n         * @returns {Boolean} Returned true for emersion events\n         *\/\n        filterOptionsKeydown: function (data, event) {\n            var key = keyCodes&#091;event.keyCode];\n\n            !this.isTabKey(event) ? event.stopPropagation() : false;\n\n            if (key === &#039;pageDownKey&#039; || key === &#039;pageUpKey&#039;) {\n                event.preventDefault();\n                this.filterOptionsFocus(false);\n                this.cacheUiSelect.focus();\n            }\n\n            this.keydownSwitcher(data, event);\n\n            return true;\n        },\n\n        \/**\n         * Filtered options list by value from filter options list\n         *\/\n        filterOptionsList: function () {\n            var value = this.filterInputValue().trim().toLowerCase(),\n                array = &#091;];\n\n            if (value &amp;&amp; value.length &lt; 2) {\n                return false;\n            }\n\n            this.cleanHoveredElement();\n\n            if (!value) {\n                this.renderPath = false;\n                this.options(this.cacheOptions.tree);\n                this._setItemsQuantity(false);\n\n                return false;\n            }\n\n            this.showPath ? this.renderPath = true : false;\n\n            if (this.filterInputValue()) {\n                array = this.selectType === &#039;optgroup&#039; ?\n                    this._getFilteredArray(this.cacheOptions.lastOptions, value) :\n                    this._getFilteredArray(this.cacheOptions.plain, value);\n\n                if (!value.length) {\n                    this.options(this.cacheOptions.plain);\n                    this._setItemsQuantity(this.cacheOptions.plain.length);\n                } else {\n                    this.options(array);\n                    this._setItemsQuantity(array.length);\n                }\n\n                return false;\n            }\n\n            this.options(this.cacheOptions.plain);\n        },\n\n        \/**\n         * Filtered options list by value from filter options list\n         *\n         * @param {Array} list - option list\n         * @param {String} value\n         *\n         * @returns {Array} filters result\n         *\/\n        _getFilteredArray: function (list, value) {\n            var i = 0,\n                array = &#091;],\n                curOption;\n\n            for (i; i &lt; list.length; i++) {\n                curOption = list&#091;i].label.toLowerCase();\n\n                if (curOption.indexOf(value) &gt; -1) {\n                    array.push(list&#091;i]); \/*eslint max-depth: &#091;2, 4]*\/\n                }\n            }\n\n            return array;\n        },\n\n        \/**\n         * Get path to current option\n         *\n         * @param {Object} data - option data\n         * @returns {String} path\n         *\/\n        getPath: function (data) {\n            var pathParts,\n                createdPath = &#039;&#039;;\n\n            if (this.renderPath) {\n                pathParts = data.path.split(&#039;.&#039;);\n                _.each(pathParts, function (curData) {\n                    createdPath = createdPath ? createdPath + &#039; \/ &#039; + curData : curData;\n                });\n\n                return createdPath;\n            }\n        },\n\n        \/**\n         * Set filtered items quantity\n         *\n         * @param {Object} data - option data\n         *\/\n        _setItemsQuantity: function (data) {\n            if (this.showFilteredQuantity) {\n                data || parseInt(data, 10) === 0 ?\n                    this.itemsQuantity(data + &#039; &#039; + this.quantityPlaceholder) :\n                    this.itemsQuantity(&#039;&#039;);\n            }\n        },\n\n        \/**\n         * Remove element from selected array\n         *\/\n        removeSelected: function (value, data, event) {\n            event ? event.stopPropagation() : false;\n            this.value.remove(value);\n        },\n\n        \/**\n         * Checked key name\n         *\n         * @returns {Boolean}\n         *\/\n        isTabKey: function (event) {\n            return keyCodes&#091;event.keyCode] === &#039;tabKey&#039;;\n        },\n\n        \/**\n         * Clean hoveredElement variable\n         *\n         * @returns {Object} Chainable\n         *\/\n        cleanHoveredElement: function () {\n            if (this.hoveredElement) {\n                $(this.hoveredElement)\n                    .children(this.actionTargetSelector)\n                    .removeClass(this.hoverClass);\n\n                this.hoveredElement = null;\n            }\n\n            return this;\n        },\n\n        \/**\n         * Check selected option\n         *\n         * @param {String} value - option value\n         * @return {Boolean}\n         *\/\n        isSelected: function (value) {\n            return this.multiple ? _.contains(this.value(), value) : this.value() === value;\n        },\n\n        \/**\n         * Check optgroup label\n         *\n         * @param {Object} data - element data\n         * @return {Boolean}\n         *\/\n        isOptgroupLabels: function (data) {\n            return data.hasOwnProperty(this.separator) &amp;&amp; this.optgroupLabels;\n        },\n\n        \/**\n         * Check hovered option\n         *\n         * @param {Object} data - element data\n         * @return {Boolean}\n         *\/\n        isHovered: function (data) {\n            var element = this.hoveredElement,\n                elementData;\n\n            if (!element) {\n                return false;\n            }\n\n            elementData = ko.dataFor(this.hoveredElement);\n\n            return data.value === elementData.value;\n        },\n\n        \/**\n         * Toggle list visibility\n         *\n         * @returns {Object} Chainable\n         *\/\n        toggleListVisible: function () {\n            this.listVisible(!this.listVisible());\n\n            return this;\n        },\n\n        \/**\n         * Get selected element labels\n         *\n         * @returns {Array} array labels\n         *\/\n        getSelected: function () {\n            var selected = this.value();\n\n            return this.cacheOptions.plain.filter(function (opt) {\n                return _.isArray(selected) ?\n                    _.contains(selected, opt.value) :\n                selected == opt.value;\/\/eslint-disable-line eqeqeq\n            });\n        },\n\n        \/**\n         * Toggle activity list element\n         *\n         * @param {Object} data - selected option data\n         * @returns {Object} Chainable\n         *\/\n        toggleOptionSelected: function (data) {\n            var isSelected = this.isSelected(data.value);\n\n            if (this.lastSelectable &amp;&amp; data.hasOwnProperty(this.separator)) {\n                return this;\n            }\n\n            if (!this.multiple) {\n                if (!isSelected) {\n                    this.value(data.value);\n                }\n                this.listVisible(false);\n            } else {\n                if (!isSelected) { \/*eslint no-lonely-if: 0*\/\n                    this.value.push(data.value);\n                } else {\n                    this.value(_.without(this.value(), data.value));\n                }\n            }\n\n            return this;\n        },\n\n        \/**\n         * Change visibility to child level\n         *\n         * @param {Object} data - element data\n         *\/\n        openChildLevel: function (data) {\n            var contextElement = data,\n                isVisible;\n\n            if (this.openLevelsAction &amp;&amp; data.hasOwnProperty(this.separator) &amp;&amp; _.isBoolean(this.levelsVisibility) || this.openLevelsAction &amp;&amp; data.hasOwnProperty(this.separator) &amp;&amp; parseInt(this.levelsVisibility, 10) &lt;= data.level) {\n                isVisible = !contextElement.visible();\n\n                if (isVisible &amp;&amp; !contextElement.isVisited) {\n                    contextElement.isVisited = true;\n                }\n\n                contextElement.visible(isVisible);\n            }\n        },\n\n        \/**\n         * Check selected elements\n         *\n         * @returns {Boolean}\n         *\/\n        hasData: function () {\n            if (!this.value()) {\n                this.value(&#091;]);\n            }\n\n            return this.value() ? !!this.value().length : false;\n        },\n\n        \/**\n         * @deprecated\n         *\/\n        onMousemove: function () {},\n\n        \/**\n         * Handles hover on list items.\n         *\n         * @param {Object} event - mousemove event\n         *\/\n        onDelegatedMouseMouve: function (event) {\n            var target = $(event.currentTarget).closest(this.visibleOptionSelector)&#091;0];\n\n            if (this.isCursorPositionChange(event) || this.hoveredElement === target) {\n                return;\n            }\n\n            this._hoverTo(target);\n            this.setCursorPosition(event);\n        },\n\n        \/**\n         * Get option index\n         *\n         * @param {Object} data - object with data about this element\n         *\n         * @returns {Number}\n         *\/\n        getOptionIndex: function (data) {\n            var index;\n\n            _.each(this.cacheOptions.plain, function (opt, id) {\n                if (data.value === opt.value) {\n                    index = id;\n                }\n            });\n\n            return index;\n        },\n\n        \/**\n         * Set X and Y cursor position\n         *\n         * @param {Object} event - mousemove event\n         *\/\n        setCursorPosition: function (event) {\n            this.cursorPosition = {\n                x: event.pageX,\n                y: event.pageY\n            };\n        },\n\n        \/**\n         * Check previous and current cursor position\n         *\n         * @param {Object} event - mousemove event\n         * @returns {Boolean}\n         *\/\n        isCursorPositionChange: function (event) {\n            return this.cursorPosition &amp;&amp;\n                this.cursorPosition.x === event.pageX &amp;&amp;\n                this.cursorPosition.y === event.pageY;\n        },\n\n        \/**\n         * Set true to observable variable multiselectFocus\n         * @param {Object} ctx\n         * @param {Object} event - focus event\n         *\/\n        onFocusIn: function (ctx, event) {\n            !this.cacheUiSelect ? this.cacheUiSelect = event.target : false;\n            this.multiselectFocus(true);\n        },\n\n        \/**\n         * Set false to observable variable multiselectFocus\n         * and close list\n         *\/\n        onFocusOut: function () {\n            this.multiselectFocus(false);\n        },\n\n        \/**\n         * Handler enter key, if select list is closed - open select,\n         * if select list is open toggle selected current option\n         *\/\n        enterKeyHandler: function () {\n\n            if (this.filterOptionsFocus()) {\n                return false;\n            }\n\n            if (this.listVisible()) {\n                if (this.hoveredElement) {\n                    this.toggleOptionSelected(ko.dataFor(this.hoveredElement));\n                }\n            } else {\n                this.setListVisible(true);\n            }\n        },\n\n        \/**\n         * Handler escape key, if select list is open - closes it,\n         *\/\n        escapeKeyHandler: function () {\n            this.listVisible() ? this.setListVisible(false) : false;\n        },\n\n        \/**\n         * Handler pageDown key, selected next option in list, if current option is last\n         * selected first option in list\n         *\/\n        pageDownKeyHandler: function () {\n            this._setHoverToElement(1);\n        },\n\n        \/**\n         * Get jQuery element by option data\n         *\n         * @param {Object} data - option data\n         *\n         * @returns {Object} jQuery element\n         *\/\n        _getElemByData: function (data) {\n            var i = 0,\n                list = $(this.cacheUiSelect).find(&#039;li&#039;),\n                length = this.options().length,\n                result;\n\n            for (i; i &lt; length; i++) {\n                if (this.options()&#091;i].value === data.value) {\n                    result = $(list&#091;i]);\n                }\n            }\n\n            return result;\n        },\n\n        \/**\n         * Set hover to visible element\n         *\n         * @param {Number} direction - iterator\n         *\/\n        _setHoverToElement: function (direction) {\n            var element;\n\n            if (direction ===  1) {\n                element = this._getNextElement();\n            } else if (direction === -1) {\n                element = this._getPreviousElement();\n            }\n\n            if (element) {\n                this._hoverTo(element);\n                this._scrollTo(element);\n            }\n        },\n\n        \/**\n         * Find current hovered element\n         * and change scroll position\n         *\n         * @param {Number} element - element index\n         *\/\n        _scrollTo: function (element) {\n            var curEl = $(element).children(this.actionTargetSelector),\n                wrapper = $(this.rootList),\n                curElPos = {},\n                wrapperPos = {};\n\n            curElPos.start = curEl.offset().top;\n            curElPos.end = curElPos.start + curEl.outerHeight();\n\n            wrapperPos.start = wrapper.offset().top;\n            wrapperPos.end = wrapperPos.start + wrapper.height();\n\n            if (curElPos.start &lt; wrapperPos.start) {\n                wrapper.scrollTop(wrapper.scrollTop() - (wrapperPos.start - curElPos.start));\n            } else if (curElPos.end &gt; wrapperPos.end) {\n                wrapper.scrollTop(wrapper.scrollTop() + curElPos.end - wrapperPos.end);\n            }\n        },\n\n        \/**\n         * Handler pageUp key, selected previous option in list, if current option is first -\n         * selected last option in list\n         *\/\n        pageUpKeyHandler: function () {\n            this._setHoverToElement(-1);\n        },\n\n        \/**\n         * Switcher to parse keydown event and delegate event to needful method\n         *\n         * @param {Object} data - element data\n         * @param {Object} event - keydown event\n         * @returns {Boolean} if handler for this event doesn&#039;t found return true\n         *\/\n        keydownSwitcher: function (data, event) {\n            var keyName = keyCodes&#091;event.keyCode];\n\n            if (this.isTabKey(event)) {\n                if (!this.filterOptionsFocus() &amp;&amp; this.listVisible() &amp;&amp; this.filterOptions) {\n                    this.cacheUiSelect.blur();\n                    this.filterOptionsFocus(true);\n                    this.cleanHoveredElement();\n\n                    return false;\n                }\n                this.listVisible(false);\n\n                return true;\n            }\n\n            if (this.keyDownHandlers().hasOwnProperty(keyName)) {\n                this.keyDownHandlers()&#091;keyName].apply(this, arguments);\n            } else {\n                return true;\n            }\n        },\n\n        \/**\n         * Set caption\n         *\/\n        setCaption: function () {\n            var length;\n\n            if (!_.isArray(this.value()) &amp;&amp; this.value()) {\n                length = 1;\n            } else if (this.value()) {\n                length = this.value().length;\n            } else {\n                this.value(&#091;]);\n                length = 0;\n            }\n\n            if (length &gt; 1) {\n                this.placeholder(length + &#039; &#039; + this.selectedPlaceholders.lotPlaceholders);\n            } else if (length &amp;&amp; this.getSelected().length) {\n                this.placeholder(this.getSelected()&#091;0].label);\n            } else {\n                this.placeholder(this.selectedPlaceholders.defaultPlaceholder);\n            }\n\n            return this.placeholder();\n        },\n\n        \/**\n         * Set list status, open or close\n         *\n         * @param {Boolean} value - variable for set list visible status\n         *\/\n        setListVisible: function (value) {\n            this.listVisible(value);\n        },\n\n        \/**\n         * Processes preview for option by it&#039;s value, and sets the result\n         * to &#039;preview&#039; observable\n         *\n         * @returns {String}\n         *\/\n        getPreview: function () {\n            var selected = this.getSelected();\n\n            return selected.map(function (option) {\n                return option.label;\n            }).join(&#039;, &#039;);\n        },\n\n        \/**\n         * Defines previous option element to\n         * the one that is currently hovered.\n         *\n         * @returns {Element}\n         *\/\n        _getPreviousElement: function () {\n            var currentElement = this.hoveredElement,\n                lastElement    = this._getLastIn(this.rootList),\n                previousElement;\n\n            if (!currentElement) {\n                return lastElement;\n            }\n\n            previousElement = $(currentElement).prev()&#091;0];\n\n            return this._getLastIn(previousElement) ||\n                previousElement ||\n                this._getFirstParentOf(currentElement) ||\n                lastElement;\n        },\n\n        \/**\n         * Defines next option element to\n         * the one that is currently hovered.\n         *\n         * @returns {Element}\n         *\/\n        _getNextElement: function () {\n            var currentElement = this.hoveredElement,\n                firstElement   = this._getFirstIn(this.rootList);\n\n            if (!currentElement) {\n                return firstElement;\n            }\n\n            return this._getFirstIn(currentElement) ||\n                $(currentElement).next()&#091;0] ||\n                this._getParentsOf(currentElement).next()&#091;0] ||\n                firstElement;\n        },\n\n        \/**\n         * Returns first option element in provided scope.\n         *\n         * @param {Element} scope\n         * @returns {Element}\n         *\/\n        _getFirstIn: function (scope) {\n            return $(scope).find(this.visibleOptionSelector)&#091;0];\n        },\n\n        \/**\n         * Returns last descendant option element in provided scope.\n         *\n         * @param {Element} scope\n         * @returns {Element}\n         *\/\n        _getLastIn: function (scope) {\n            return $(scope).find(this.visibleOptionSelector).last()&#091;0];\n        },\n\n        \/**\n         * Returns a collection of parent option elements.\n         *\n         * @param {Element} scope\n         * @returns {jQueryCollection}\n         *\/\n        _getParentsOf: function (scope) {\n            return $(scope).parents(this.visibleOptionSelector);\n        },\n\n        \/**\n         * Returns first parent option element.\n         *\n         * @param {Element} scope\n         * @returns {Element}\n         *\/\n        _getFirstParentOf: function (scope) {\n            return this._getParentsOf(scope)&#091;0];\n        },\n\n        \/**\n         * Sets hover class to provided option element.\n         *\n         * @param {Element} element\n         *\/\n        _hoverTo: function (element) {\n            if (this.hoveredElement) {\n                $(this.hoveredElement)\n                    .children(this.actionTargetSelector)\n                    .removeClass(this.hoverClass);\n            }\n\n            $(element)\n                .children(this.actionTargetSelector)\n                .addClass(this.hoverClass);\n\n            this.hoveredElement = element;\n        },\n\n        \/**\n         * Callback which fires when root list element is rendered.\n         *\n         * @param {Element} element\n         *\/\n        onRootListRender: function (element) {\n            var targetSelector = &#039;li &gt; &#039; + this.actionTargetSelector;\n\n            this.rootList = element;\n\n            $(this.rootList).on(\n                &#039;mousemove&#039;,\n                targetSelector,\n                this.onDelegatedMouseMouve.bind(this)\n            );\n        }\n    });\n});<\/pre>\n\n\n\n<p><br>Now, Flush the Cache, and see the result like below image.<\/p>\n\n\n\n<p><strong>Note:<\/strong> <strong>You will have to get the CSS from Admin for this field, otherwise it will not look as Admin.<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" width=\"1275\" height=\"593\" src=\"https:\/\/cdnblog.webkul.com\/blog\/wp-content\/uploads\/2017\/12\/Screenshot-1-1.png\" alt=\"Select UI\" class=\"wp-image-106064\" srcset=\"https:\/\/cdnblog.webkul.com\/blog\/wp-content\/uploads\/2017\/12\/Screenshot-1-1.png 1275w, https:\/\/cdnblog.webkul.com\/blog\/wp-content\/uploads\/2017\/12\/Screenshot-1-1-250x116.png 250w, https:\/\/cdnblog.webkul.com\/blog\/wp-content\/uploads\/2017\/12\/Screenshot-1-1-300x140.png 300w, https:\/\/cdnblog.webkul.com\/blog\/wp-content\/uploads\/2017\/12\/Screenshot-1-1-768x357.png 768w, https:\/\/cdnblog.webkul.com\/blog\/wp-content\/uploads\/2017\/12\/Screenshot-1-1-1200x558.png 1200w\" sizes=\"(max-width: 1275px) 100vw, 1275px\" loading=\"lazy\" \/><\/figure>\n\n\n\n<p>Thanks.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Here we learn how to add or create Multi select field using the Ui Component on frontend. I am going to take an example of categories multi select files which looks like the belowimage in admin->catalog New or Edit Product section. Let&#8217;s start step by step.You must have installed your custom Module on which you <a href=\"https:\/\/webkul.com\/blog\/magento2-create-multi-select-ui-field-frontend-admin\/\">[&#8230;]<\/a><\/p>\n","protected":false},"author":69,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[302],"tags":[5961,5962,5963],"class_list":["post-106051","post","type-post","status-publish","format-standard","hentry","category-magento2","tag-multiselect-ui-field","tag-ui-field","tag-ui-select-component"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Magento2 Create Multi Select UI Field on Frontend as Admin<\/title>\n<meta name=\"description\" content=\"How to Create Multi Select UI Field on Frontend as Admin Here we learn how to add or create Multi select field using the Ui Component on frontend. I am going to take an example of categories multi select files which looks like the below image in admin-&gt;catalog New or Edit Product section\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/webkul.com\/blog\/magento2-create-multi-select-ui-field-frontend-admin\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Magento2 Create Multi Select UI Field on Frontend as Admin\" \/>\n<meta property=\"og:description\" content=\"How to Create Multi Select UI Field on Frontend as Admin Here we learn how to add or create Multi select field using the Ui Component on frontend. I am going to take an example of categories multi select files which looks like the below image in admin-&gt;catalog New or Edit Product section\" \/>\n<meta property=\"og:url\" content=\"https:\/\/webkul.com\/blog\/magento2-create-multi-select-ui-field-frontend-admin\/\" \/>\n<meta property=\"og:site_name\" content=\"Webkul Blog\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/webkul\/\" \/>\n<meta property=\"article:published_time\" content=\"2017-12-22T17:28:17+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-02-17T13:40:28+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/webkul.com\/blog\/wp-content\/uploads\/2017\/12\/Screenshot-18.png\" \/>\n<meta name=\"author\" content=\"Mahesh Singh\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@webkul\" \/>\n<meta name=\"twitter:site\" content=\"@webkul\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Mahesh Singh\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"2 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/webkul.com\/blog\/magento2-create-multi-select-ui-field-frontend-admin\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/webkul.com\/blog\/magento2-create-multi-select-ui-field-frontend-admin\/\"},\"author\":{\"name\":\"Mahesh Singh\",\"@id\":\"https:\/\/webkul.com\/blog\/#\/schema\/person\/53d3b977a0ab5adcf32aef9f97e595bd\"},\"headline\":\"Magento 2 Create Multi Select UI Field on Frontend as Admin\",\"datePublished\":\"2017-12-22T17:28:17+00:00\",\"dateModified\":\"2026-02-17T13:40:28+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/webkul.com\/blog\/magento2-create-multi-select-ui-field-frontend-admin\/\"},\"wordCount\":272,\"commentCount\":6,\"publisher\":{\"@id\":\"https:\/\/webkul.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/webkul.com\/blog\/magento2-create-multi-select-ui-field-frontend-admin\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/webkul.com\/blog\/wp-content\/uploads\/2017\/12\/Screenshot-18.png\",\"keywords\":[\"Multiselect ui field\",\"UI Field\",\"ui-select component\"],\"articleSection\":[\"Magento2\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/webkul.com\/blog\/magento2-create-multi-select-ui-field-frontend-admin\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/webkul.com\/blog\/magento2-create-multi-select-ui-field-frontend-admin\/\",\"url\":\"https:\/\/webkul.com\/blog\/magento2-create-multi-select-ui-field-frontend-admin\/\",\"name\":\"Magento2 Create Multi Select UI Field on Frontend as Admin\",\"isPartOf\":{\"@id\":\"https:\/\/webkul.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/webkul.com\/blog\/magento2-create-multi-select-ui-field-frontend-admin\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/webkul.com\/blog\/magento2-create-multi-select-ui-field-frontend-admin\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/webkul.com\/blog\/wp-content\/uploads\/2017\/12\/Screenshot-18.png\",\"datePublished\":\"2017-12-22T17:28:17+00:00\",\"dateModified\":\"2026-02-17T13:40:28+00:00\",\"description\":\"How to Create Multi Select UI Field on Frontend as Admin Here we learn how to add or create Multi select field using the Ui Component on frontend. I am going to take an example of categories multi select files which looks like the below image in admin->catalog New or Edit Product section\",\"breadcrumb\":{\"@id\":\"https:\/\/webkul.com\/blog\/magento2-create-multi-select-ui-field-frontend-admin\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/webkul.com\/blog\/magento2-create-multi-select-ui-field-frontend-admin\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/webkul.com\/blog\/magento2-create-multi-select-ui-field-frontend-admin\/#primaryimage\",\"url\":\"https:\/\/cdnblog.webkul.com\/blog\/wp-content\/uploads\/2017\/12\/Screenshot-18.png\",\"contentUrl\":\"https:\/\/cdnblog.webkul.com\/blog\/wp-content\/uploads\/2017\/12\/Screenshot-18.png\",\"width\":1147,\"height\":438},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/webkul.com\/blog\/magento2-create-multi-select-ui-field-frontend-admin\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/webkul.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Magento 2 Create Multi Select UI Field on Frontend as Admin\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/webkul.com\/blog\/#website\",\"url\":\"https:\/\/webkul.com\/blog\/\",\"name\":\"Webkul Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/webkul.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/webkul.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/webkul.com\/blog\/#organization\",\"name\":\"WebKul Software Private Limited\",\"url\":\"https:\/\/webkul.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/webkul.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/cdnblog.webkul.com\/blog\/wp-content\/uploads\/2021\/08\/webkul-logo-accent-sq.png\",\"contentUrl\":\"https:\/\/cdnblog.webkul.com\/blog\/wp-content\/uploads\/2021\/08\/webkul-logo-accent-sq.png\",\"width\":380,\"height\":380,\"caption\":\"WebKul Software Private Limited\"},\"image\":{\"@id\":\"https:\/\/webkul.com\/blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/webkul\/\",\"https:\/\/x.com\/webkul\",\"https:\/\/www.instagram.com\/webkul\/\",\"https:\/\/www.linkedin.com\/company\/webkul\",\"https:\/\/www.youtube.com\/user\/webkul\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/webkul.com\/blog\/#\/schema\/person\/53d3b977a0ab5adcf32aef9f97e595bd\",\"name\":\"Mahesh Singh\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/webkul.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/f4c013ebf7008223382b8a49203e6d354677e8baff0eca373e6e4266efa762da?s=96&d=https%3A%2F%2Fcdnblog.webkul.com%2Fblog%2Fwp-content%2Fuploads%2F2019%2F10%2Fmike.png&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/f4c013ebf7008223382b8a49203e6d354677e8baff0eca373e6e4266efa762da?s=96&d=https%3A%2F%2Fcdnblog.webkul.com%2Fblog%2Fwp-content%2Fuploads%2F2019%2F10%2Fmike.png&r=g\",\"caption\":\"Mahesh Singh\"},\"url\":\"https:\/\/webkul.com\/blog\/author\/mahesh721\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Magento2 Create Multi Select UI Field on Frontend as Admin","description":"How to Create Multi Select UI Field on Frontend as Admin Here we learn how to add or create Multi select field using the Ui Component on frontend. I am going to take an example of categories multi select files which looks like the below image in admin->catalog New or Edit Product section","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/webkul.com\/blog\/magento2-create-multi-select-ui-field-frontend-admin\/","og_locale":"en_US","og_type":"article","og_title":"Magento2 Create Multi Select UI Field on Frontend as Admin","og_description":"How to Create Multi Select UI Field on Frontend as Admin Here we learn how to add or create Multi select field using the Ui Component on frontend. I am going to take an example of categories multi select files which looks like the below image in admin->catalog New or Edit Product section","og_url":"https:\/\/webkul.com\/blog\/magento2-create-multi-select-ui-field-frontend-admin\/","og_site_name":"Webkul Blog","article_publisher":"https:\/\/www.facebook.com\/webkul\/","article_published_time":"2017-12-22T17:28:17+00:00","article_modified_time":"2026-02-17T13:40:28+00:00","og_image":[{"url":"https:\/\/webkul.com\/blog\/wp-content\/uploads\/2017\/12\/Screenshot-18.png","type":"","width":"","height":""}],"author":"Mahesh Singh","twitter_card":"summary_large_image","twitter_creator":"@webkul","twitter_site":"@webkul","twitter_misc":{"Written by":"Mahesh Singh","Est. reading time":"2 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/webkul.com\/blog\/magento2-create-multi-select-ui-field-frontend-admin\/#article","isPartOf":{"@id":"https:\/\/webkul.com\/blog\/magento2-create-multi-select-ui-field-frontend-admin\/"},"author":{"name":"Mahesh Singh","@id":"https:\/\/webkul.com\/blog\/#\/schema\/person\/53d3b977a0ab5adcf32aef9f97e595bd"},"headline":"Magento 2 Create Multi Select UI Field on Frontend as Admin","datePublished":"2017-12-22T17:28:17+00:00","dateModified":"2026-02-17T13:40:28+00:00","mainEntityOfPage":{"@id":"https:\/\/webkul.com\/blog\/magento2-create-multi-select-ui-field-frontend-admin\/"},"wordCount":272,"commentCount":6,"publisher":{"@id":"https:\/\/webkul.com\/blog\/#organization"},"image":{"@id":"https:\/\/webkul.com\/blog\/magento2-create-multi-select-ui-field-frontend-admin\/#primaryimage"},"thumbnailUrl":"https:\/\/webkul.com\/blog\/wp-content\/uploads\/2017\/12\/Screenshot-18.png","keywords":["Multiselect ui field","UI Field","ui-select component"],"articleSection":["Magento2"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/webkul.com\/blog\/magento2-create-multi-select-ui-field-frontend-admin\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/webkul.com\/blog\/magento2-create-multi-select-ui-field-frontend-admin\/","url":"https:\/\/webkul.com\/blog\/magento2-create-multi-select-ui-field-frontend-admin\/","name":"Magento2 Create Multi Select UI Field on Frontend as Admin","isPartOf":{"@id":"https:\/\/webkul.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/webkul.com\/blog\/magento2-create-multi-select-ui-field-frontend-admin\/#primaryimage"},"image":{"@id":"https:\/\/webkul.com\/blog\/magento2-create-multi-select-ui-field-frontend-admin\/#primaryimage"},"thumbnailUrl":"https:\/\/webkul.com\/blog\/wp-content\/uploads\/2017\/12\/Screenshot-18.png","datePublished":"2017-12-22T17:28:17+00:00","dateModified":"2026-02-17T13:40:28+00:00","description":"How to Create Multi Select UI Field on Frontend as Admin Here we learn how to add or create Multi select field using the Ui Component on frontend. I am going to take an example of categories multi select files which looks like the below image in admin->catalog New or Edit Product section","breadcrumb":{"@id":"https:\/\/webkul.com\/blog\/magento2-create-multi-select-ui-field-frontend-admin\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/webkul.com\/blog\/magento2-create-multi-select-ui-field-frontend-admin\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/webkul.com\/blog\/magento2-create-multi-select-ui-field-frontend-admin\/#primaryimage","url":"https:\/\/cdnblog.webkul.com\/blog\/wp-content\/uploads\/2017\/12\/Screenshot-18.png","contentUrl":"https:\/\/cdnblog.webkul.com\/blog\/wp-content\/uploads\/2017\/12\/Screenshot-18.png","width":1147,"height":438},{"@type":"BreadcrumbList","@id":"https:\/\/webkul.com\/blog\/magento2-create-multi-select-ui-field-frontend-admin\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/webkul.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Magento 2 Create Multi Select UI Field on Frontend as Admin"}]},{"@type":"WebSite","@id":"https:\/\/webkul.com\/blog\/#website","url":"https:\/\/webkul.com\/blog\/","name":"Webkul Blog","description":"","publisher":{"@id":"https:\/\/webkul.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/webkul.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/webkul.com\/blog\/#organization","name":"WebKul Software Private Limited","url":"https:\/\/webkul.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/webkul.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/cdnblog.webkul.com\/blog\/wp-content\/uploads\/2021\/08\/webkul-logo-accent-sq.png","contentUrl":"https:\/\/cdnblog.webkul.com\/blog\/wp-content\/uploads\/2021\/08\/webkul-logo-accent-sq.png","width":380,"height":380,"caption":"WebKul Software Private Limited"},"image":{"@id":"https:\/\/webkul.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/webkul\/","https:\/\/x.com\/webkul","https:\/\/www.instagram.com\/webkul\/","https:\/\/www.linkedin.com\/company\/webkul","https:\/\/www.youtube.com\/user\/webkul\/"]},{"@type":"Person","@id":"https:\/\/webkul.com\/blog\/#\/schema\/person\/53d3b977a0ab5adcf32aef9f97e595bd","name":"Mahesh Singh","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/webkul.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/f4c013ebf7008223382b8a49203e6d354677e8baff0eca373e6e4266efa762da?s=96&d=https%3A%2F%2Fcdnblog.webkul.com%2Fblog%2Fwp-content%2Fuploads%2F2019%2F10%2Fmike.png&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/f4c013ebf7008223382b8a49203e6d354677e8baff0eca373e6e4266efa762da?s=96&d=https%3A%2F%2Fcdnblog.webkul.com%2Fblog%2Fwp-content%2Fuploads%2F2019%2F10%2Fmike.png&r=g","caption":"Mahesh Singh"},"url":"https:\/\/webkul.com\/blog\/author\/mahesh721\/"}]}},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/webkul.com\/blog\/wp-json\/wp\/v2\/posts\/106051","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/webkul.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/webkul.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/webkul.com\/blog\/wp-json\/wp\/v2\/users\/69"}],"replies":[{"embeddable":true,"href":"https:\/\/webkul.com\/blog\/wp-json\/wp\/v2\/comments?post=106051"}],"version-history":[{"count":8,"href":"https:\/\/webkul.com\/blog\/wp-json\/wp\/v2\/posts\/106051\/revisions"}],"predecessor-version":[{"id":526776,"href":"https:\/\/webkul.com\/blog\/wp-json\/wp\/v2\/posts\/106051\/revisions\/526776"}],"wp:attachment":[{"href":"https:\/\/webkul.com\/blog\/wp-json\/wp\/v2\/media?parent=106051"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/webkul.com\/blog\/wp-json\/wp\/v2\/categories?post=106051"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/webkul.com\/blog\/wp-json\/wp\/v2\/tags?post=106051"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}