Extending the ViewModel

By default, every grid and form of LokiAdminComponents is driven by Loki Components that are defined via a file etc/loki_components.xml. In earlier examples, the Loki\AdminComponents\Component\Grid\GridViewModel and Loki\AdminComponents\Component\Grid\GridRepository classes where used in the definition of those components.

Usually, you DO NOT want to extend the component repository class Loki\AdminComponents\Component\Grid\GridRepository. However, it is quite common to extend the ViewModel class to add your own behaviour to the grid.

Adding your own ViewModel

First of all, a new ViewModel can be defined in the etc/loki_components.xml file as follows:

<?xml version="1.0" encoding="UTF-8" ?>
<components xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Yireo_LokiComponents:etc/loki_components.xsd">
    <component
        name="yireo-training.example-admin.grid"
        viewModel="YireoTraining\ExampleAdmin\Component\Grid\GridViewModel"
        repository="Loki\AdminComponents\Component\Grid\GridRepository">
    </component>
</components>

The new ViewModel class

The new ViewModel class YireoTraining\ExampleAdmin\Component\Grid\GridViewModel is simply extending upon the original class. In this case, we are changing the Index URL from */*/index to example/index/grid. Note the usage of the PHP Attribute Override that is useful to keep track of changes in overridden methods.

<?php declare(strict_types=1);

namespace YireoTraining\ExampleAdmin\Component\Grid;

use Override;
use Loki\AdminComponents\Component\Grid\GridViewModel as OriginalGridViewModel;

class GridViewModel extends OriginalGridViewModel
{
    #[Override]
    public function getIndexUrl(): string
    {
        return $this->urlFactory->create()->getUrl('example/index/grid');
    }
}

In a similar way, the getNewUrl() method could be changed as well.

Changing the row action and other cell actions

Items in a grid are rendered through so-call cell templates. A couple of these cell templates allow for clicking upon the cell content and then being taken to a new page. This redirect is determined by the getRowAction() method.

class GridViewModel extends OriginalGridViewModel
{
    #[Override]
    public function getRowAction(DataObject $item): CellAction
    {
        $editUrl = $this->urlFactory->create()->getUrl('catalog/product/edit', [
            'id' => $item->getId(),
        ]);

        return $this->cellActionFactory->create($editUrl, 'Edit');
    }

The row action is based on an object Loki\AdminComponents\Grid\Cell\CellAction. And the row action is actually also used in an "Actions" cell for each row. You can add other actions here as well, through the method getAdditionalActions:

class GridViewModel extends OriginalGridViewModel
{
    #[Override]
    protected function getAdditionalActions(DataObject $item): array
    {
        $cellActions = [];

        $editUrl = $this->urlFactory->create()->getUrl('loki_admin_products/index/form', [
            'id' => $item->getId(),
        ]);

        $cellActions[] = $this->cellActionFactory->create($editUrl, 'Quick Edit');

        return $cellActions;
    }
}

Changing searchable fields

When dealing with a grid search, Loki AdminComponents tries to determine automatically (via the provider object) what kind of fields (or columns) to search through. With array providers, adding columns is a mandatory step. With collection providers, the columns are determined automatically. With repository providers, the columns are simply not determined at all. And because of this, search is disabled.

To use search, we need to supply searchable_fields. This could be done via the XML layout (as explained elsewhere) but it could also be done by overriding the getSearchableFields method.

class GridViewModel extends OriginalGridViewModel
{
    #[Override]
    public function getSearchableFields(): array
    {
        return [
            'name',
            'description',
            'short_description',
        ];
    }
}

Overriding cell templates

Each cell (so a column in a row) could be styled via a cell template (PHTML). By default, cell templates are either determined via the XML layout or a DI-type configuration of Loki\AdminComponents\Grid\Cell\CellTemplateResolver. However, you could also override the getCellTemplates() method to supply the right cell templates.

class GridViewModel extends OriginalGridViewModel
{
    #[Override]
    public function getCellTemplates(): array
    {
        return [
            ...parent::getCellTemplates(),
            'foobar' => 'YireoTraining_ExampleGrid::grid/cell/foobar.phtml'
        ];
    }
}
Last modified: September 1, 2025