Create and configure Zed tables

Edit on GitHub

Spryker has a dedicated component to help you build tables for the Zed UI.

This document helps you start working with tables.

1. Create a new table

To start defining a new table, under the /Communication/Table/ folder that extends the AbstractTable class, create a new class in your module.

Example:

<?php

use Spryker\Zed\Gui\Communication\Table\AbstractTable;

class OrdersTable extends AbstractTable
Note

The query used for fetching the data must be injected into the constructor.

Note

The table class must implement the following methods:

  • function configure (TableConfiguration $configuration): Set up the captions for the tables header, the searchable and sortable fields, and specify the raw fields.
  • function prepareData (TableConfiguration $configuration): Prepare the data retrieved by the query in the way you want it to be shown in the table.

2. Configure the table

Set up the captions for the tables header, the searchable and sortable fields, and specify the raw fields:

<?php

function configure(TableConfiguration $configuration)

The configuration of the table must be done with the following methods:

  • Set up captions for the table headers (setHeader())
  • Set up searchable fields (setSearchable())
  • Set up sortable fields (setSortable())
  • Set up raw fields—for fields containing HTML markup that should not be escaped (addRawColumn)

Code sample:

<?php

protected function configure(TableConfiguration $config)
{
    $config->setHeader([
        SpySalesOrderTableMap::COL_ID_SALES_ORDER => 'Order Id',
        SpySalesOrderTableMap::COL_CREATED_AT => 'Timestamp',
        SpySalesOrderTableMap::COL_FK_CUSTOMER => 'Customer Id',
        SpySalesOrderTableMap::COL_FIRST_NAME => 'Billing Name',
        SpySalesOrderTableMap::COL_GRAND_TOTAL => 'Value'
    ]);
    $config->setSortable([
        SpySalesOrderTableMap::COL_CREATED_AT,
        SpySalesOrderTableMap::COL_GRAND_TOTAL
    ]);
    $config->setSearchable([
        SpySalesOrderTableMap::COL_FIRST_NAME,
        SpySalesOrderTableMap::COL_GRAND_TOTAL
    ]);

    $config->addRawColumn('URL');

    $this->persistFilters($config);

    return $config;
}

Configure the default field for sorting

To configure the field on which the table is sorted by default when it’s initially rendered or when no sorting is applied by the user from the UI, specify the index of the field when configuring the table:

<?php

$config->setDefaultSortColumnIndex(5);

You can also configure the default sort direction (for the initial rendering of the table or for the case it’s not set yet)—for example:

<?php

$config->setDefaultSortDirection(
    \Spryker\Zed\Gui\Communication\Table\TableConfiguration::SORT_DESC);

3. Prepare the data

Prepare the data retrieved by the query in the way you want it to be shown in the table:

<?php

function prepareData(TableConfiguration $configuration)

The query results must be mapped to the table columns, and data transformations such as price formatting must be done here:

<?php

protected function prepareData(TableConfiguration $config)
{
    $query = $this->salesQuery;
    $queryResults = $this->runQuery($query, $config);
    $results = [];
    foreach ($queryResults as $item) {
        $results[] = [
            SpySalesOrderTableMap::COL_ID_SALES_ORDER => $item[SpySalesOrderTableMap::COL_ID_SALES_ORDER],
            SpySalesOrderTableMap::COL_CREATED_AT => $item[SpySalesOrderTableMap::COL_CREATED_AT],
            SpySalesOrderTableMap::COL_FK_CUSTOMER => $item[SpySalesOrderTableMap::COL_FK_CUSTOMER],
            SpySalesOrderTableMap::COL_FIRST_NAME => $item[SpySalesOrderTableMap::COL_FIRST_NAME],
            SpySalesOrderTableMap::COL_GRAND_TOTAL => $this->formatPrice($item[SpySalesOrderTableMap::COL_GRAND_TOTAL])),
        ];
    }
    return $results;
}

4. Render the table

To display the query results in the table, in the controller’s action, retrieve an instance of the table configuration class and call the render() operation:

<?php

public function indexAction(Request $request)
{
    $table = $this->getFactory()->createOrdersTable();
    return [
        'orders' => $table->render(),
    ];
}

5. Download the table

To download the data, follow these steps:

  1. Add the DownloadController class.
  2. Add a link to the DownloadController action into the table view.
  3. Prepare the download of the data.

Add DownloadController

DownloadController calls the module factory to create the table for downloading and start the download stream.

<?php

namespace Spryker\Zed\Module\Communication\Controller;

use Spryker\Zed\Kernel\Communication\Controller\AbstractController;
use Symfony\Component\HttpFoundation\StreamedResponse;

/**
 * @method \Spryker\Zed\Module\Business\ModuleFacadeInterface getFacade()
 * @method \Spryker\Zed\Module\Communication\ModuleCommunicationFactory getFactory()
 * @method \Spryker\Zed\Module\Persistence\ModuleQueryContainerInterface getQueryContainer()
 * @method \Spryker\Zed\Module\Persistence\ModuleRepositoryInterface getRepository()
 */
class DownloadController extends AbstractController
{
    /**
     * @return \Symfony\Component\HttpFoundation\StreamedResponse
     */
    public function indexAction(): StreamedResponse
    {
        return $this->getFactory()->createModuleTable()->streamDownload();
    }
}

To start the download, add a link to the DownloadController action on the table view:

...

{% block action %}
    ...
    {{ createActionButton('/module/download', 'Download as CSV' | trans) }}
    ...
{% endblock %}

Prepare the download of the data

To prepare the CSV file, implement the following methods in the Table class:

  • GetCsvHeaders()
  • GetDownloadQuery()
  • FormatCsvRow()

Implement GetCsvHeaders()

The GetCsvHeaders() method defines the order and the displayed header of the columns.

Return an array that has the column name of the table as the key and the displayed header as the value. The values are translated.

<?php

...

/**
 * @return string[]
 */
protected function getCsvHeaders(): array
{
    return [
        static::COL_A => 'Header a',
        static::COL_B => 'Header b',
        static::COL_C => 'Header c',
    ];
}

Implement getDownloadQuery()

The getDownloadQuery() method returns the query that is used to fetch the data from the database. In the background, \Propel\Runtime\Formatter\OnDemandFormatter is set for performance reasons.

<?php

...

/**
 * @return \Orm\Zed\Module\Persistence\SpyModuleQuery
 */
protected function getDownloadQuery(): ModelCriteria
{
    $moduleQuery = $this->prepareQuery();
    $moduleQuery->orderBy(SpyModuleTableMap::COL_A, Criteria::DESC);

    return $moduleQuery;
}

Implement formatCsvRow()

The formatCsvRow() method receives each \Propel\Runtime\ActiveRecord\ActiveRecordInterface and is responsible for returning a formatted array of the required data.

<?php

...

/**
 * @param \Orm\Zed\Module\Persistence\SpyModule $entity
 *
 * @return array
 */
protected function formatCsvRow(ActiveRecordInterface $entity): array
{
    $moduleRow = $entity->toArray();

    $moduleRow[static::COL_A] = $this->utilDateTimeService->formatDateTime($entity->getCreatedAt());
    $moduleRow[static::COL_B] = $entity->getRegistered() ? 'Verified' : 'Unverified';

    ...

    return $moduleRow;
}