This solution shows how to add a custom column to the sales order grid, but to add a custom column you need to add the column via XML, the problem is i need to read data collection to get available column data and add it as a custom column in sales order grid, in conclusion, I want to add multiple columns which will be generated dynamically from database collection data, is there any way to do this?
-
If you want to add column you have to add column using XML and also you need to add that in datasource.– Ronak ChauhanJul 10, 2017 at 4:49
-
@idham-choudry , did you find any solution of the problem?– VishalOct 16, 2018 at 9:17
-
1//Useful /vendor/magento/module-catalog/Ui/Component/Listing/Columns.php /vendor/magento/module-catalog/view/adminhtml/ui_component/product_listing.xml– VishalOct 16, 2018 at 14:57
-
did you find any solution for the problem? –@Vishal– Divya SekarOct 15, 2020 at 9:17
2 Answers
I have a solution that consists in taking over both columns and dataprovider for sales grid.
<?xml version="1.0" encoding="UTF-8"?>
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
<dataSource name="sales_order_grid_data_source">
<dataProvider class="Mbs\SalesGrid\Ui\Component\Listing\DataProvider" name="sales_order_grid_data_source" />
</dataSource>
<columns name="sales_order_columns" class="Mbs\SalesGrid\Ui\Component\Listing\Columns" />
</listing>
data provider below:
class DataProvider extends \Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider
{
public function __construct(
$name,
$primaryFieldName,
$requestFieldName,
ReportingInterface $reporting,
SearchCriteriaBuilder $searchCriteriaBuilder,
RequestInterface $request,
FilterBuilder $filterBuilder,
array $meta = [],
array $data = []
) {
parent::__construct($name, $primaryFieldName, $requestFieldName, $reporting, $searchCriteriaBuilder, $request, $filterBuilder, $meta, $data);
}
public function getData()
{
$data = parent::getData();
foreach ($data['items'] as &$item) {
$item['sales_day_created'] = $this->extraDayFromDate($item['created_at']);
$item['sales_time_created'] = $this->extraTimeFromDate($item['created_at']);
}
return $data;
}
}
**columns below:**
class Columns extends \Magento\Ui\Component\Listing\Columns
{
/**
* @var CustomColumnCreator
*/
private $columnCreator;
public function __construct(
ContextInterface $context,
CustomColumnCreator $columnCreator,
array $components = [],
array $data = []
) {
parent::__construct($context, $components, $data);
$this->columnCreator = $columnCreator;
}
public function prepare()
{
if (isset($this->components['created_at'])) {
$billingNameColumn = $this->components['billing_name'];
$column = $this->columnCreator->addColumnFromExistingColumn(
$billingNameColumn,
'sales_day_created',
'Sales Day',
11
);
$this->addComponent('sales_day_created', $column);
$column = $this->columnCreator->addColumnFromExistingColumn(
$billingNameColumn,
'sales_time_created',
'Sales Time',
11
);
$this->addComponent('sales_time_created', $column);
}
parent::prepare();
}
I did not put all the details as it is pretty much about parsing and I can add the full module if you need.
UPDATE: the customColumnCreator is responsible to create a column in the grid dynamically. It takes an existing column and does use its configuration to generate the new column. This is a convenient way to clone a column when we are happy about its basic configuration.
full code: https://bitbucket.org/magstaging/salesgrid/src/master/
-
-
In Columns.php i don't understand what is
CustomColumnCreator
can you please explain @Herve Tribouilloy Oct 16, 2020 at 7:07 -
-
ya I have a collection if I just use the collection instead of
CustomColumnCreator
if I m wright Oct 16, 2020 at 7:21 -
I suggest paste all your code or module and then I can comment but the collection and the column creator are 2 different things Oct 16, 2020 at 7:23
Make new sales_order_grid.xml file in app/code/YourVendor/YourModule/view/adminhtml/ui_component/
and try to do there something like this:
<?xml version="1.0" encoding="UTF-8"?>
<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="your_column" class="YourVendor\YourModule\Ui\Component\YourColumn">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="sortOrder" xsi:type="number">10</item>
</item>
</argument>
</column>
</columns>
</listing>
That class
property inside column tag allows you to write your very own renderer that will take care of the custom column. You can do it simply like that:
<?php
declare(strict_types=1);
namespace YourVendor\YourModule\Ui\Component;
use Magento\Ui\Component\Listing\Columns\Column;
class YourColumn extends Column
{
/**
* @param array $dataSource
*
* @return array
*/
public function prepareDataSource(array $dataSource): array
{
parent::prepareDataSource($dataSource);
if (!isset($dataSource['data']['items'])) {
return $dataSource;
}
/*
In this method the `$dataSource` array contains informations from order grid.
To access your dynamic field name you don't need to refer to the xml file,
you can just simply use $this->getData('name') to obtain the name of your renderer column.
*/
foreach ($dataSource['data']['items'] as & $item) {
//for example:
$item[$this->getData('name')] = 'HelloWorld'; //will display the "HelloWorld" string at every row of your custom column
$item[$this->getData('name')] = $item['increment_id'];//will display increment_id value at every row of your custom column
//you can also perform simple operations, for example:
if($item['increment_id'] === '123456789'){
$item[$this->getData('name')] = 'Increment id is fake';
}
}
return $dataSource;
}
}
Let me know if it's what you've wanted.
-
No, I want for the custom column not for custom data but your answer will help me in future Oct 16, 2020 at 6:28