Order Grid Configuration
Grid UI Component
<!-- app/code/Vendor/Order/view/adminhtml/ui_component/sales_order_grid.xml -->
<?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">
<settings>
<spinner>listingColumns</spinner>
</settings>
<dataSource name="order_listing_data_source">
<argument name="data" xsi:type="array">
<item name="js_config" xsi:type="array">
<item name="component" xsi:type="string">Magento_Ui/js/data/provider</item>
</item>
</argument>
<dataProvider class="Magento\Sales\Model\DataProvider" name="order_listing_data_source"/>
</dataSource>
<listingColumns name="listing_columns">
<column name="increment_id" class="Magento\Ui\Component\Listing\Columns\Column">
<settings>
<filter>text</filter>
<dataType>text</dataType>
<label translate="true">Order #</label>
<bodyTmpl>ui/grid/cells/html</bodyTmpl>
</settings>
</column>
<column name="created_at" class="Magento\Ui\Component\Listing\Columns\Date">
<settings>
<filter>dateRange</filter>
<dataType>date</dataType>
<label translate="true">Purchase Date</label>
</settings>
</column>
<column name="status" class="Magento\Ui\Component\Listing\Columns\Column">
<settings>
<filter>select</filter>
<dataType>select</dataType>
<label translate="true">Status</label>
</settings>
</column>
</listingColumns>
</listing>
Grid Data Provider
namespace Vendor\Order\Ui\DataProvider;
class OrderDataProvider extends \Magento\Ui\Model\DataProvider
{
public function __construct(
string $name,
string $primaryFieldName,
string $requestFieldName,
\Magento\Sales\Model\ResourceModel\Order\Grid\Collection $collection,
array $meta = [],
array $data = []
) {
parent::__construct($name, $primaryFieldName, $requestFieldName, $collection, $meta, $data);
}
public function getData(): array
{
$items = $this->getCollection()->getItems();
$result = [];
foreach ($items as $item) {
$result[$item->getId()] = $item->getData();
}
return [
'totalRecords' => $this->getCollection()->getSize(),
'items' => $result,
];
}
}
Custom Columns
Adding Custom Columns
<!-- Add column to existing grid -->
<listingColumns>
<column name="custom_field" class="Vendor\Order\Ui\Component\Column\Custom">
<settings>
<filter>text</filter>
<dataType>text</dataType>
<label translate="true">Custom Field</label>
<sortOrder>50</sortOrder>
</settings>
</column>
</listingColumns>
Custom Column Class
namespace Vendor\Order\Ui\Component\Column;
use Magento\Ui\Component\Listing\Columns\Column;
use Magento\Framework\View\Element\UiComponent\ContextInterface;
class Custom extends Column
{
public function prepareDataSource(array $dataSource): array
{
if (!isset($dataSource['data']['items'])) {
return $dataSource;
}
foreach ($dataSource['data']['items'] as &$item) {
$item['custom_field'] = $this->formatCustomValue(
$item['custom_field']
);
}
return $dataSource;
}
private function formatCustomValue($value): string
{
return strtoupper($value);
}
}
Column with Custom Renderer
// Custom column renderer
define([
'Magento_Ui/js/grid/columns/column',
'text'
], function (Column, text) {
'use strict';
return Column.extend({
defaults: {
bodyTmpl: 'ui/grid/cells/html',
component: 'Vendor_Order/js/column/custom'
},
getLabel: function (row) {
return '<span class="custom-badge">' + row.custom_field + '</span>';
}
});
});
Grid Filters
Filter Types
<!-- Different filter types -->
<column name="status">
<settings>
<!-- Text filter -->
<filter>text</filter>
<!-- Select filter -->
<filter>select</filter>
<!-- Date range filter -->
<filter>dateRange</filter>
<!-- Numeric filter -->
<filter>number</filter>
<!-- Boolean filter -->
<filter>boolean</filter>
<options>
<option name="processing" xsi:type="array">
<item name="value" xsi:type="string">processing</item>
<item name="label" xsi:type="string">Processing</item>
</option>
<option name="complete" xsi:type="array">
<item name="value" xsi:type="string">complete</item>
<item name="label" xsi:type="string">Complete</item>
</option>
</options>
</settings>
</column>
Custom Filter
namespace Vendor\Order\Ui\Component\Filter;
class CustomFilter extends \Magento\Ui\Component\Listing\Columns\Column\Filter
{
public function getFilterData(): array
{
$value = $this->request->getParam($this->getData('name'));
if ($value) {
return [
'field' => $this->getData('dataScope'),
'value' => ['like' => '%' . $value . '%'],
'condition_type' => 'like'
];
}
return [];
}
}
Mass Actions
Mass Action Configuration
<!-- Mass actions for order grid -->
<massaction name="listing_massaction">
<action name="delete">
<settings>
<url path="sales/order/massDelete"/>
<confirm>
<message translate="true">Are you sure you want to delete selected orders?</message>
<title translate="true">Delete Orders</title>
</confirm>
</settings>
</action>
<action name="status">
<settings>
<url path="sales/order/massStatus"/>
<confirm>
<message translate="true">Are you sure you want to change status?</message>
<title translate="true">Change Status</title>
</confirm>
</settings>
<argument name="data" xsi:type="array">
<item name="options" xsi:type="array">
<item name="processing" xsi:type="array">
<item name="value" xsi:type="string">processing</item>
<item name="label" xsi:type="string">Processing</item>
</item>
<item name="complete" xsi:type="array">
<item name="value" xsi:type="string">complete</item>
<item name="label" xsi:type="string">Complete</item>
</item>
</item>
</argument>
</action>
</massaction>
Custom Mass Action Controller
namespace Vendor\Order\Controller\Adminhtml\Order\Mass;
class MassCustom extends \Magento\Backend\App\Action
{
public function execute()
{
$selected = $this->getRequest()->getParam('selected');
if (!empty($selected)) {
foreach ($selected as $orderId) {
$order = $this->orderRepository->get($orderId);
$order->setStatus('custom_status');
$this->orderRepository->save($order);
}
$this->messageManager->addSuccessMessage(
__('%1 orders updated successfully.', count($selected))
);
}
return $this->_redirect('sales/order/index');
}
}
Quiz
1. What is a grid data provider?
2. How do you add a custom column to the order grid?
3. What does mass action allow?
Flashcards
Question
Grid root element?
Click to reveal answer
Answer
<listing> in UI component XML
Question
Grid data source?
Click to reveal answer
Answer
dataSource element with PHP DataProvider class
Question
Mass action purpose?
Click to reveal answer
Answer
Bulk operations on selected grid items
Question
Column filter types?
Click to reveal answer
Answer
text, select, dateRange, number, boolean
Revision Notes
Key Takeaways
- 1. Order grids use UI component XML with <listing> root element
- 2. Grid data providers supply data via getData() method
- 3. Custom columns are added via <column> elements with PHP classes
- 4. Mass actions enable bulk operations on selected orders
- 5. Filters support multiple types: text, select, date, number
Interview Tips
- • Explain the grid component architecture: XML → JS → PHP data
- • Describe how to add a custom column with data transformation
- • Discuss mass action implementation and controller handling
Cheat Sheet
Grid Components:
<listing> → root
<dataSource> → PHP provider
<listingColumns> → column definitions
<massaction> → bulk operations
Column Settings:
filter: text, select, dateRange, number
dataType: text, select, date, number
class: PHP column class for rendering
Mass Action:
url: controller path
confirm: confirmation dialog
options: action parameters