0

My prepare collection code :

 protected function _prepareCollection()
    {
        $store = $this->_getStore();
        $collection = $this->productFactory->create()->getCollection()->addAttributeToSelect(
            'sku'
        )->addAttributeToSelect(
            'name'
        )->addAttributeToSelect(
            'attribute_set_id'
        )->addAttributeToSelect(
            'type_id'
        )->setStore(
            $store
        );

        if ($this->moduleManager->isEnabled('Magento_CatalogInventory')) {
            $collection->joinField(
                'qty',
                'cataloginventory_stock_item',
                'qty',
                'product_id=entity_id',
                '{{table}}.stock_id=1',
                'left'
            );
        }
        if ($store->getId()) {
            $collection->setStoreId($store->getId());
            $collection->addStoreFilter($store);
            $collection->joinAttribute(
                'name',
                'catalog_product/name',
                'entity_id',
                null,
                'inner',
                Store::DEFAULT_STORE_ID
            );

            $collection->joinAttribute(
                'status',
                'catalog_product/status',
                'entity_id',
                null,
                'inner',
                $store->getId()
            );
            $collection->joinAttribute(
                'visibility',
                'catalog_product/visibility',
                'entity_id',
                null,
                'inner',
                $store->getId()
            );

            $collection->joinAttribute('price', 'catalog_product/price', 'entity_id', null, 'left', $store->getId());


        } else {
            $collection->addAttributeToSelect('price');
            $collection->joinAttribute('status', 'catalog_product/status', 'entity_id', null, 'inner');
            $collection->joinAttribute('visibility', 'catalog_product/visibility', 'entity_id', null, 'inner');
        }
        $this->setCollection($collection);

        return parent::_prepareCollection();
    }

    protected function _prepareColumns()
    {
        $this->addColumn(
            'in_products',
            [
                'type' => 'checkbox',
                'html_name' => 'products_id',
                'required' => true,
                'values' => $this->_getSelectedProducts(),
                'align' => 'center',
                'index' => 'entity_id',
            ]
        );
        $this->addColumn(
            'entity_id',
            [
                'header' => __('ID'),
                'width' => '50px',
                'index' => 'entity_id',
                'type' => 'number',
            ]
        );
        $this->addColumn(
            'name',
            [
                'header' => __('Name'),
                'index' => 'name',
                'header_css_class' => 'col-type',
                'column_css_class' => 'col-type',
            ]
        );
        $this->addColumn(
            'sku',
            [
                'header' => __('SKU'),
                'index' => 'sku',
                'header_css_class' => 'col-sku',
                'column_css_class' => 'col-sku',
            ]
        );
        $store = $this->_getStore();
        $this->addColumn(
            'price',
            [
                'header' => __('Price'),
                'type' => 'price',
                'currency_code' => $store->getBaseCurrency()->getCode(),
                'index' => 'price',
                'header_css_class' => 'col-price',
                'column_css_class' => 'col-price',
            ]
        );
        $this->addColumn(
            'position',
            [
                'header' => __('Position'),
                'name' => 'position',
                'width' => 60,
                'type' => 'number',
                'validate_class' => 'validate-number',
                'index' => 'position',
                'editable' => true,
                'edit_only' => true,
            ]
        );
        $this->addColumn(
            'brand',
            [
                'header' => __('Brand'),
                'type' => 'options',
                'index' => 'brand',
                'name' => 'brand',
                'options' => $this->getBrandsOptionArray(),
                'header_css_class' => 'col-brand',
                'column_css_class' => 'col-brand',
            ]
        );

        $this->addColumn('category_name',
            array(
                'header' => 'Category Name',
                'type' => 'options',
                'align' => 'left',
                'index' => 'category_name'
            )
        );

        return parent::_prepareColumns();
    }

enter image description here

3 Answers 3

0

First add the column Category in product grid. You have inserted the Category column but expand the product_listing.xml file as below in your module.

1. Add product_listing.xml app\code\YourVendor\YourModule\view\adminhtml\ui_component\product_listing.xml

<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <columns name="product_columns" class="Magento\Catalog\Ui\Component\Listing\Columns">
        <column name="category_id" class="YourVendor\YourModule\Ui\Component\Listing\Column\Category">
            <argument name="data" xsi:type="array">
                <item name="options" xsi:type="object">YourVendor\YourModule\Model\Category\Categorylist</item>
                <item name="config" xsi:type="array">
                    <item name="label" xsi:type="string" translate="true">Category Name</item>
                    <item name="sortOrder" xsi:type="number">99</item>
                    <item name="dataType" xsi:type="string">select</item>
                </item>
            </argument>
        </column>
    </columns>
</listing>

2. Add Categorylist.php app\code\YourVendor\YourModule\Model\Category\Categorylist.php

namespace YourVendor\YourModule\Model\Category;
 
class CategoryList implements \Magento\Framework\Option\ArrayInterface
{
    public function __construct(
        \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $collectionFactory
    ) {
        $this->_categoryCollectionFactory = $collectionFactory;
 
    }
    public function toOptionArray($addEmpty = true)
    {
 
         $collection = $this->_categoryCollectionFactory->create();
        $collection->addAttributeToSelect('name');
        $options = [];
        if ($addEmpty) {
            $options[] = ['label' => __('-- Please Select a Category --'), 'value' => ''];
        }
        foreach ($collection as $category) {
            $options[] = ['label' => $category->getName(), 'value' => $category->getId()];
        }
        return $options;
    }
}

3. Add Category.php and override the prepareDataSource Method. Get category values to the in prepareDataSource like below app\code\YourVendor\YourModule\Ui\Component\Listing\Column\Category.php

namespace YourVendor\YourModule\Ui\Component\Listing\Column;
 
use Magento\Framework\View\Element\UiComponentFactory;
use Magento\Framework\View\Element\UiComponent\ContextInterface;
 
class Category extends \Magento\Ui\Component\Listing\Columns\Column
{
 
    public function prepareDataSource(array $dataSource)
    {
        $fieldName = $this->getData('name');
        if (isset($dataSource['data']['items'])) {
            foreach ($dataSource['data']['items'] as & $item) {
                $productId = $item['entity_id'];
 
                $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
                $product = $objectManager->create('Magento\Catalog\Model\Product')->load($productId);
                $cats = $product->getCategoryIds();
                $categories = array();
                if (count($cats)) {
                    foreach ($cats as $cat) {
                        $category = $objectManager->create('Magento\Catalog\Model\Category')->load($cat);
                        $categories[] = $category->getName();
                    }
                }
                $item[$fieldName] = implode(',', $categories);
            }
        }
        return $dataSource;
    }
}

I hope it helps.

0

you can use this:

Create app\code\Vendor\Extension\view\adminhtml\ui_component\product_listing.xml

<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
<columns name="product_columns" class="Magento\Catalog\Ui\Component\Listing\Columns">
    <column name="category_id" class="Vendor\Extension\Ui\Component\Listing\Column\Category">
        <argument name="data" xsi:type="array">
            <item name="options" xsi:type="object">Vendor\Extension\Model\Category\Categorylist</item>
            <item name="config" xsi:type="array">
                <item name="filter" xsi:type="string">select</item>
                <item name="add_field" xsi:type="boolean">true</item>
                <item name="label" xsi:type="string" translate="true">Categories</item>
                <item name="sortOrder" xsi:type="number">75</item>
                <item name="dataType" xsi:type="string">select</item>
            </item>
        </argument>
    </column>
    <column name="created_at" class="Magento\Ui\Component\Listing\Columns\Date">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="filter" xsi:type="string">dateRange</item>
                <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/date</item>
                <item name="dataType" xsi:type="string">date</item>
                <item name="label" xsi:type="string" translate="true">Created At</item>
            </item>
        </argument>
    </column>
    <column name="updated_at" class="Magento\Ui\Component\Listing\Columns\Date">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="filter" xsi:type="string">dateRange</item>
                <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/date</item>
                <item name="dataType" xsi:type="string">date</item>
                <item name="label" xsi:type="string" translate="true">Updated At</item>
            </item>
        </argument>
    </column>
</columns>

Create app\code\Vendor\Extension\Ui\DataProvider\Product\ProductDataProvider.php

<?php
namespace Vendor\Extension\Ui\DataProvider\Product;
class ProductDataProvider extends \Magento\Catalog\Ui\DataProvider\Product\ProductDataProvider
{
    public function addFilter(\Magento\Framework\Api\Filter $filter)
    {
        if ($filter->getField() == 'category_id') {
            $this->getCollection()->addCategoriesFilter(array('in' => $filter->getValue()));
        } elseif (isset($this->addFilterStrategies[$filter->getField()])) {
            $this->addFilterStrategies[$filter->getField()]
                ->addFilter(
                    $this->getCollection(),
                    $filter->getField(),
                    [$filter->getConditionType() => $filter->getValue()]
                );
        } else {
            parent::addFilter($filter);
        }
    }
}

Create app\code\Vendor\Extension\Ui\Component\Listing\Column\Category.php

<?php 
namespace Vendor\Extension\Ui\Component\Listing\Column;
 
use Magento\Framework\View\Element\UiComponentFactory;
use Magento\Framework\View\Element\UiComponent\ContextInterface;
 
class Category extends \Magento\Ui\Component\Listing\Columns\Column
{
 
    public function prepareDataSource(array $dataSource)
    {
        $fieldName = $this->getData('name');
        if (isset($dataSource['data']['items'])) {
            foreach ($dataSource['data']['items'] as & $item) {
                $productId = $item['entity_id'];
 
                $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
                $product = $objectManager->create('Magento\Catalog\Model\Product')->load($productId);
                $cats = $product->getCategoryIds();
                $categories = array();
                if (count($cats)) {
                    foreach ($cats as $cat) {
                        $category = $objectManager->create('Magento\Catalog\Model\Category')->load($cat);
                        $categories[] = $category->getName();
                    }
                }
                $item[$fieldName] = implode(',', $categories);
            }
        }
        return $dataSource;
    }
}

Create app\code\Vendor\Extension\Model\Category\Categorylist.php

<?php 
namespace Vendor\Extension\Model\Category;
 
class CategoryList implements \Magento\Framework\Option\ArrayInterface
{
    public function __construct(
        \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $collectionFactory
    ) {
        $this->_categoryCollectionFactory = $collectionFactory;
 
    }
    public function toOptionArray($addEmpty = true)
    {
 
         $collection = $this->_categoryCollectionFactory->create();
        $collection->addAttributeToSelect('name');//->addRootLevelFilter()->load();
        $options = [];
        if ($addEmpty) {
            $options[] = ['label' => __('-- Please Select a Category --'), 'value' => ''];
        }
        foreach ($collection as $category) {
            $options[] = ['label' => $category->getName(), 'value' => $category->getId()];
        }
        return $options;
    }
}

Create app\code\Vendor\Extension\etc\di.xml

<?xml version="1.0"?>
 
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\Catalog\Ui\DataProvider\Product\ProductDataProvider" type="Vendor\Extension\Ui\DataProvider\Product\ProductDataProvider" />
</config>
0

Try This It will work For Your Block Grid

Replace the category column with the below code

$this->addColumn(
            'category',
            [
                'header' => __('Category'),
                'index' => 'category',
                'sortable' => false,
                'type' => 'options',
                'align' => 'left',
                'options' => $this->_objectManager->create(\Vendor\Module\Model\Source\Category::class)
                    ->getAllOptions() ,
                'renderer' => \Vendor\Module\Block\Adminhtml\Renderer\Category::class,
                'filter_condition_callback' => array($this, 'filterCategory'),
            ]
        );

Now add the Filter callback condition in the same file as function

public function filterCategory($collection, $column)
    {
        $value = $column->getFilter()->getValue();
        $_category = $this->_objectManager->create(\Magento\Catalog\Model\Category::class)->load($value);
        $collection->addCategoryFilter($_category);
        return $collection;
    }

Now Option File : Vendor\Module\Model\Source\Category.php

<?php

namespace Vendor\Module\Model\Source;

use Magento\Framework\Data\OptionSourceInterface;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory;

class Category implements OptionSourceInterface
{
    /**
     * @var CollectionFactory
     */
    public $category;

    public $storeManager;

    public $allowedLevels = [1, 2, 3, 4, 5, 6, 7];

    /**
     * Category constructor.
     * @param StoreManagerInterface $storeManager
     * @param CollectionFactory $collectionFactory
     */
    public function __construct(
        StoreManagerInterface $storeManager,
        CollectionFactory $collectionFactory
    ) {
        $this->storeManager = $storeManager;
        $this->category = $collectionFactory;
    }

    public function toOptionArray()
    {
        $categories = $this->category->create()
            ->addAttributeToSelect('entity_id')
            ->addAttributeToSelect('name')
            ->addAttributeToSelect('level')
            ->addAttributeToFilter('level', ['in', $this->allowedLevels])
            ->setStore($this->storeManager->getStore());
        $options = [
            [
                'label' => '',
                'value' => '',
            ]
        ];

        /** @var \Magento\Catalog\Model\Category $category */
        foreach ($categories as $category) {
            $space = str_repeat('&nbsp;', $category->getLevel() * 3);
            $option['label'] = $space . $category->getName() . " [{$category->getEntityId()}]";
            $option['value'] = $category->getEntityId();
            $options[] = $option;
        }
        return $options;
    }

    public function getAllOptions()
    {
        return $this->getOptionArray();
    }

    /**
     * @return array
     */
    public function getOptionArray()
    {
        $options = [];
        foreach ($this->toOptionArray() as $option) {
            $options[$option['value']] = (string)$option['label'];
        }
        return $options;
    }
}

Renderer File : Vendor\Module\Block\Adminhtml\Renderer\Category.php

<?php

namespace Vendor\Module\Block\Adminhtml\Renderer;

class Category extends \Magento\Backend\Block\Widget\Grid\Column\Renderer\AbstractRenderer
{
    public $categoryFactory;

    public function __construct(
        \Magento\Backend\Block\Context $context,
        \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryFactory,
        array $data = []
    ) {
        parent::__construct($context, $data);

        $this->categoryFactory = $categoryFactory;
    }

    public function render(\Magento\Framework\DataObject $row)
    {
        $categoryIds = $row->getCategoryIds();
        $categories = $this->categoryFactory->create()
            ->addAttributeToSelect('name')
            ->addAttributeToFilter('entity_id', ['in' => $categoryIds]);
        $html = [];
        foreach ($categories as $category) {
            $html[] = $category->getName();
        }

        $html = implode(',<br/>', $html);
        return $html;
    }
}

After that Cache Flush

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.