2

In Magento 2.1.8 I trying to add a custom column to the admin order grid, that contains the cc_type field.

Long story short, I managed to make the column appear, display the correct data, and be updated dynamically via di.xml.

What I could not achieve yet is the filter in the grid. I need the filter to display an option list based on existing values in cc_type.

Cc_type is a field that is populated by payment methods, so it is not possible to provide a list of all the possible values. I want the filter to provide only the options that actually are stored in the table.

app/code/Vendor/Module/view/adminhtml/ui_component/sales_order_grid.xml

<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <columns name="sales_order_columns">
        <column name="cc_type">
            <argument name="data" xsi:type="array">
                <item name="options" xsi:type="object">Vendor\Module\Model\Ui\Component\Listing\Column\CcType\CcType</item>
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">select</item>
                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/select</item>
                    <item name="dataType" xsi:type="string">select</item>
                    <item name="label" xsi:type="string" translate="true">Payment Details</item>
                </item>
            </argument>
        </column>
    </columns>
</listing>

app/code/Vendor/Module/Model/Ui/Component/Listing/Column/CcType/CcType.php

<?php

namespace Vendor\Module\Model\Ui\Component\Listing\Column\CcType;

use Magento\Framework\Data\OptionSourceInterface;
use Magento\Sales\Model\ResourceModel\Order\Status\CollectionFactory;

/**
 * Class Options
 */
class CcType implements OptionSourceInterface
{

    public function toOptionArray() {
        $optionList = [];
        //retrive options with some kind of collection?
        return $optionList;
    }

}

Anyone has any hints on how to retrieve the existing values and populate the filter options?

Thanks!

1 Answer 1

2

You could get the data collection being used by the sales order grid, extract the field data, and create an option for each unique result:

class CcTypes implements OptionSourceInterface
{

    /**
     * @var \Magento\Sales\Model\ResourceModel\Order\Grid\Collection
     */
    protected $salesCollection;

    protected $options;

    public function __construct(
        \Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory $collectionFactory
    ) {
        $this->salesCollection = $collectionFactory->getReport("sales_order_grid_data_source");
    }

    public function toOptionArray()
    {
        if ($this->options === null) {

            foreach ($this->salesCollection->addOrder('cc_type')->addFieldToSelect('cc_type')->distinct(true) as $order) {
                $ccType = $order->getCcType();
                $this->options[] = [
                    'value' => $ccType,
                    'label' => $ccType
                ];
            }
        }

        return $this->options;
    }
}
3
  • Awesome, thanks! I slightly optimized the query: $this->salesCollection->setOrder('cc_type', 'ASC')->addFieldToSelect('cc_type')->distinct(true) and then skipped the ($lastItem !== $ccType) check altogether.
    – ermannob
    Aug 30, 2017 at 13:02
  • Have you got any hints on how to cache the results? I noticed that the collection is loaded twice when loading the grid, and the ($this->options === null) check is irrelevant, unfortunately. Thanks!
    – ermannob
    Aug 30, 2017 at 13:19
  • The core registry could be used to store the collection using some plugin so it can be reused. Other than that I don't really know. Aug 31, 2017 at 1:12

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.