9

I try to turn on inline edit in catalog grid as it described in DevDocs: http://devdocs.magento.com/guides/v2.0/ui-components/ui-secondary-inline.html

Main problem is how to override this block of configuration in

\vendor\magento\module-catalog\view\adminhtml\ui_component\product_listing.xml

            <item name="childDefaults" xsi:type="array">
                <item name="fieldAction" xsi:type="array">
                    <item name="provider" xsi:type="string">product_listing.product_listing.product_columns.actions</item>
                    <item name="target" xsi:type="string">applyAction</item>
                    <item name="params" xsi:type="array">
                        <item name="0" xsi:type="string">edit</item>
                        <item name="1" xsi:type="string">${ $.$data.rowIndex }</item>                            
                    </item>
                </item>
            </item>

with custom "params" required for inline edit in

\app\code\MyVendor\MyModule\view\adminhtml\ui_component\product_listing.xml

                    <item name="params" xsi:type="array">
                        <item name="0" xsi:type="string">${ $.$data.rowIndex }</item>
                        <item name="1" xsi:type="boolean">true</item>
                    </item>   

It throws error while loading configuration by the core framework function

**Magento\Ui\Model\Manager->evaluateComponentArguments()**

I don't know how to cure it except overriding framework components such as

Magento\Ui\Model\Manager or Magento\Framework\View\Layout\Generator\UiComponent,

but it's bad idea

Other decision is to comment "fieldAction" item in original Magento product_listing.xml

With this modification inline edit works.

Here is the full sample code:

\app\code\MyVendor\MyModule\etc\adminhtml\di.xml

<preference for="Magento\Catalog\Ui\Component\Listing\Columns" type="MyVendor\MyModule\Magento\Catalog\Ui\Component\Listing\Columns" />

\app\code\MyVendor\MyModule\etc\adminhtml\routes.xml

<router id="admin">
    <route id="my_product" frontName="my_product">
        <module name="MyVendor_MyModule"/>
    </route>
</router>

Modified original magento config:

\vendor\magento\module-catalog\view\adminhtml\ui_component\product_listing.xml

             ------
             <item name="childDefaults" xsi:type="array">
                <!--<item name="fieldAction" xsi:type="array">
                    <item name="provider" xsi:type="string">product_listing.product_listing.product_columns.actions</item>
                    <item name="target" xsi:type="string">applyAction</item>
                    <item name="params" xsi:type="array">
                        <item name="0" xsi:type="string">edit</item>
                        <item name="1" xsi:type="string">${ $.$data.rowIndex }</item>                           
                    </item>
                </item>--> 
            </item>
            --------

Custom config:

\app\code\MyVendor\MyModule\view\adminhtml\ui_component\product_listing.xml

<dataSource name="product_listing_data_source"></dataSource>
<listingToolbar name="listing_top"></listingToolbar>
<columns name="product_columns" class="Magento\Customer\Ui\Component\Listing\Columns">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="editorConfig" xsi:type="array">
                <item name="selectProvider" xsi:type="string">product_listing.product_listing.product_columns.ids</item>
                <item name="enabled" xsi:type="boolean">true</item>
                <item name="indexField" xsi:type="string">entity_id</item>
                <item name="clientConfig" xsi:type="array">
                    <item name="saveUrl" xsi:type="url" path="my_product/product/inlineEdit"/>
                    <item name="validateBeforeSave" xsi:type="boolean">false</item>
                </item>
            </item>
            <item name="childDefaults" xsi:type="array">
                <item name="fieldAction" xsi:type="array">
                    <item name="provider" xsi:type="string">product_listing.product_listing.product_columns_editor</item>
                    <item name="target" xsi:type="string">startEdit</item>
                    <item name="params" xsi:type="array">
                        <item name="0" xsi:type="string">${ $.$data.rowIndex }</item>
                        <item name="1" xsi:type="boolean">true</item>
                    </item>                        
                </item>
            </item>
        </item>
    </argument>
    <column name="name">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="editor" xsi:type="string">text</item>
            </item>
        </argument>
    </column>
    <column name="my_pku">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="editor" xsi:type="string">text</item>                    
            </item>
        </argument>
    </column>
    ----- other columns ----
 </columns>

\app\code\MyVendor\MyModule\Controller\Adminhtml\Product.php

namespace MyVendor\MyModule\Controller\Adminhtml;
use Magento\Backend\App\Action;
abstract class Product extends \Magento\Backend\App\Action {
    const ADMIN_RESOURCE = 'Magento_Catalog::products';

    public function __construct(
        \Magento\Backend\App\Action\Context $context
    ) {
        parent::__construct($context);
    }
}

\app\code\MyVendor\MyModule\Controller\Adminhtml\Product\InlineEdit.php

namespace MyVendor\MyModule\Controller\Adminhtml\Product;

use Magento\Backend\App\Action;
use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Catalog\Api\ProductRepositoryInterface;

class InlineEdit extends \Magento\Backend\App\Action {

    const ADMIN_RESOURCE = 'Magento_Catalog::products';

    private $product;
    protected $productRepository;
    protected $resultJsonFactory;
    protected $dataObjectHelper;
    protected $logger;

    public function __construct(
    Action\Context $context, ProductRepositoryInterface $productRepository,
            \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory,
            \Magento\Framework\Api\DataObjectHelper $dataObjectHelper,
            \Psr\Log\LoggerInterface $logger
    ) {
        $this->productRepository = $productRepository;
        $this->resultJsonFactory = $resultJsonFactory;
        $this->dataObjectHelper = $dataObjectHelper;
        $this->logger = $logger;
        parent::__construct($context);
    }

    public function execute() {
        $resultJson = $this->resultJsonFactory->create();

        $postItems = $this->getRequest()->getParam('items', []);
        if (!($this->getRequest()->getParam('isAjax') && count($postItems))) {
            return $resultJson->setData([
                        'messages' => [__('Please correct the data sent.')],
                        'error' => true,
            ]);
        }

        foreach ($postItems as $productId => $productRow) {
            $this->setProduct($this->productRepository->getById($productId));

            $data = $this->product->getData();
            // ---- formatting and validating
            // $this->my_server_side_validator($data);
            // $this->my_server_side_formatter($data);

            // saving
            $dataUpdated = array_replace($data, $productRow);
            $this->product->setData($dataUpdated);
            $this->product->save();
        }

        return $resultJson->setData([
                    'messages' => $this->getErrorMessages(),
                    'error' => $this->isErrorExists()
        ]);
    }

    protected function getErrorMessages() {
        $messages = [];
        foreach ($this->getMessageManager()->getMessages()->getItems() as $error) {
            $messages[] = $error->getText();
        }
        return $messages;
    }

    protected function isErrorExists() {
        return (bool) $this->getMessageManager()->getMessages(true)->getCount();
    }

    protected function setProduct(ProductInterface $product) {
        $this->product = $product;
        return $this;
    }

    protected function getProduct() {
        return $this->product;
    }
}

\app\code\MyVendor\MyModule\Magento\Catalog\Ui\Component\Listing\Columns.php

namespace MyVendor\MyModule\Magento\Catalog\Ui\Component\Listing;
class Columns extends \Magento\Catalog\Ui\Component\Listing\Columns {
    // Array of attributes not included in
    //  \vendor\magento\module-catalog\view\adminhtml\ui_component\product_listing.xml
    protected $additional_fields = [
        'my_pku'
    ];
    public function __construct(
    \Magento\Framework\View\Element\UiComponent\ContextInterface $context,
            \Magento\Catalog\Ui\Component\ColumnFactory $columnFactory,
            \Magento\Catalog\Ui\Component\Listing\Attribute\RepositoryInterface $attributeRepository,
            array $components = [], array $data = []
    ) {
        parent::__construct($context, $columnFactory, $attributeRepository,
                $components, $data);
    }
    /**
     * {@inheritdoc}
     */
    public function prepare() {
        $columnSortOrder = self::DEFAULT_COLUMNS_MAX_ORDER;
        foreach ($this->attributeRepository->getList() as $attribute) {
            $attr_code = $attribute->getAttributeCode();
            $config = [];
            if (!isset($this->components[$attr_code]) || in_array($attr_code,
                            $this->additional_fields)) {
                $config['sortOrder'] = ++$columnSortOrder;
                if ($attribute->getIsFilterableInGrid()) {
                    $config['filter'] = $this->getFilterType($attribute->getFrontendInput());
                }
                // Copy editor configuration for additional attributes
                if (isset($this->components[$attr_code]->_data['config']['editor'])) {
                    $config['editor'] = $this->components[$attr_code]->_data['config']['editor'];
                }
                $column = $this->columnFactory->create($attribute,
                        $this->getContext(), $config);
                $column->prepare();
                $this->addComponent($attribute->getAttributeCode(), $column);
            }
        }
        parent::prepare();
    }
}

I need to extend Column.php because custom product_listing.xml also can't add editor config for additional product attributes like "my_pku" code, that not included in original magento product_listing.xml

Without this I can inline edit only predefined fields in original magento product_listing.xml

So, QUESTIONS are:

  1. How to enable catalog inline edit without modifying \vendor\magento\module-catalog\view\adminhtml\ui_component\product_listing.xml ?

  2. What is acceptable method to replace original ui_component config xml files safely, when item types are different?

UPDATE:

to Pramod Kumar Sharma

In 2.1.6 I had to comment out this block of code in

\vendor\magento\module-catalog\view\adminhtml\ui_component\product_listing.xml

             ------
         <item name="childDefaults" xsi:type="array">
            <!--<item name="fieldAction" xsi:type="array">
                <item name="provider" xsi:type="string">product_listing.product_listing.product_columns.actions</item>
                <item name="target" xsi:type="string">applyAction</item>
                <item name="params" xsi:type="array">
                    <item name="0" xsi:type="string">edit</item>
                    <item name="1" xsi:type="string">${ $.$data.rowIndex }</item>                           
                </item>
            </item>--> 
        </item>
        --------

In 2.2.1 it works whithout commenting out. I have no separate extension for this, it's part of my module with many other improvements

Just do as described above

Here it is

  • Have you completed the inline edit in product grid ? – Pramod Kumar Sharma Jan 9 '18 at 5:54
  • yes, it works. And after upgrade from 2.1.6 to 2.2.1 it works without modifying \vendor\magento\module-catalog\view\adminhtml\ui_component\product_listing.xml – my display name Jan 15 '18 at 1:22
  • Can you please send me the extension so i can refer that extension. – Pramod Kumar Sharma Jan 15 '18 at 5:02
  • How you override the product_listing.xml in your module can you please explain me. It will be helpful for me. Thanks – Pramod Kumar Sharma Jan 19 '18 at 5:59
  • Pramod Kumar Sharma, I've updated post – my display name Jan 23 '18 at 5:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.