I have build a custom form using uicomponent I want to add a button and on click want to open a modal with product grid.

How can I achieve this using uicomponent form ?


1 Answer 1


I have created a similar feature to assign categories via popup.

My Custom Product Grid (below) where I have inserted a modal with UI-grid with opens on click on the column category.

You can use insertForm instead of insertListing (mymodule_mycategory_listing) for your form.

Product Grid:

<?xml version="1.0" encoding="UTF-8"?>
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    <!-- listingToolbar, dataSource, etc components same as product grid    -->
    <columns name="product_columns" class="Magento\Catalog\Ui\Component\Listing\Columns">
        <actionsColumn name="product_category" class="MyVendor\MyModule\Ui\Component\Listing\Columns\Product\Category">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="component" xsi:type="string">MyVendor_MyModule/js/grid/columns/product/category/assign</item>
                    <item name="label" xsi:type="string" translate="true">Category</item>
                    <item name="indexField" xsi:type="string">id</item>
                    <item name="urlEntityParamName" xsi:type="string">id</item>
                    <item name="sortOrder" xsi:type="number">1000</item>
    <modal name="assign_category_modal">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="options" xsi:type="array">
                    <item name="buttons" xsi:type="array">
                        <item name="0" xsi:type="array">
                            <item name="text" xsi:type="string">Cancel</item>
                            <item name="class" xsi:type="string">action-secondary</item>
                            <item name="actions" xsi:type="array">
                                <item name="0" xsi:type="string">actionCancel</item>
                        <item name="1" xsi:type="array">
                            <item name="text" xsi:type="string">Assign Category</item>
                            <item name="class" xsi:type="string">action-primary save</item>
                            <item name="actions" xsi:type="array">
                                <item name="0" xsi:type="array">
                                    <item name="targetName" xsi:type="string">myvendor_mymodule_myproductgrid.myvendor_mymodule_myproductgrid.assign_category_modal.general.insertListing</item>
                                    <item name="actionName" xsi:type="string">save</item>
                                <item name="1" xsi:type="string">closeModal</item>
        <fieldset name="general">
                <argument name="data" xsi:type="array">
                    <item name="config" xsi:type="array">
                        <item name="component" xsi:type="string">Magento_Ui/js/form/components/insert-listing</item>
                        <item name="autoRender" xsi:type="string">true</item>
                        <item name="ns" xsi:type="string">mymodule_mycategory_listing</item>
                        <item name="externalProvider" xsi:type="string">myvendor_mymodule_myproductgrid.product_listing_data_source</item>
                        <item name="selectionsProvider" xsi:type="string">${ $.ns }.${ $.ns }.mymodule_mycategory_listing_columns.ids</item>
                        <item name="gridProvider" xsi:type="string">myvendor_mymodule_myproductgrid.myvendor_mymodule_myproductgrid</item>
                        <item name="addCategoryUrl" xsi:type="url" path="mymodule/product/assigncategory"/>

Column JS assign.js:

    function (Actions, $, registry) {
        'use strict';

        return Actions.extend({
            defaults: {
                bodyTmpl: 'My_Module/grid/cells/category/actions',

             * Applies specified action.
             * @param   {String} actionIndex - Actions' identifier.
             * @param   {Number} rowIndex - Index of a row.
             * @returns {ActionsColumn} Chainable.
            applyAction: function (actionIndex, rowIndex) {
                var action = this.getAction(rowIndex, actionIndex),
                    callback = this._getCallback(action);
                if (action.modal) {
                    // Opening popup with category grid
                    var modal = registry.get('myvendor_mymodule_myproductgrid.myvendor_mymodule_myproductgrid.assign_category_modal');
                return this;

Template for Category Action Column:

<div if="$col.isSingle($row()._rowIndex)" style="min-width: 120px">
    <div style="float: left">
                repeat="foreach: $col.getVisibleActions($row()._rowIndex), item: '$action'"
                attr="href: $action().url"
    <div style="float: right">
                repeat="foreach: $col.getVisibleActions($row()._rowIndex), item: '$action'"
                attr="href: $action().href, 'class': $action().class, 'title':$action().label"/>

<div if="$col.isMultiple($row()._rowIndex)" collapsible>
    <ul attr="'style': 'width:'+ ($col.getVisibleActions($row()._rowIndex).length * 30) + 'px'">
        <li class="mymodule actions-li" repeat="foreach: $col.getVisibleActions($row()._rowIndex), item: '$action'">
            <a click="$col.getActionHandler($action())"
               attr="href: $action().href, 'data-action': 'item-' + $action().index, 'class': $action().class, 'title':$action().label, 'download':$action().download, 'disabled':$action().disabled"

    .mymodule.actions-li {
        list-style: none;
        display: inline;

    .mymodule.actions {
        font-size: 0;
        cursor: pointer;

    .mymodule.actions.edit:before {
        display: inline-block;
        content: "\270E";

Category Column PHP Component (Category.php):

namespace MyVendor\MyModule\Ui\Component\Listing\Columns\Product;

use Magento\Ui\Component\Listing\Columns\Column;

class Category extends Column
     * Prepare Data Source
     * @param array $dataSource
     * @return array
    public function prepareDataSource(array $dataSource)
        if (isset($dataSource['data']['items'])) {
            foreach ($dataSource['data']['items'] as & $item) {
                if (isset($item['entity_id'])) {
                    $item[$this->getData('name')] = [
                        'category' => [
                            // 'category_id' have the category id already assign
                            'modal' => ['category_id' => ""],
                            'label' => __('Assign Category'),
                            // 'category_value' have the category name already assign
                            'value' => $item['category_value'],
                            'class' => 'mymodule actions edit',
                            'url' => "",
                            'href' => ''
        return $dataSource;
  • Sir can you elaborate about the phtml file
    – Asad Khan
    Oct 14, 2020 at 12:21
  • can I make insertForm component required field?
    – huykon225
    Dec 30, 2020 at 6:50
  • you should update your answer with File paths.it will help others. Aug 16, 2021 at 10:11

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.