# 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
<?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
<?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.

```php
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`:

```php
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.

```php
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.

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