Contents

Table

Drawing a table may seem like a trivial task however in a normal browser application a table needs to handle large lists smartly.

At its most basic the Table component receives a Stem Collection and an array of column definitions. When rendered it will generate an HTML table to present the data in the collection with this configuration. However in addition it provides pagination, column sorting and a range of events to allow XHR interaction with events on individual rows. Tables can also be summarised through footers.

Basic Usage

Create a Table control, with a collection and set the columns structure:

Job Title Status Sent
Job A Incoming Yes
Job B Incoming No
Job C Outgoing Yes
Job D Outgoing No
Job E Stale Yes
Job F Stale No
<?php

namespace Rhubarb\Leaf\Table\Examples\BasicUsage;

use Rhubarb\Leaf\Table\Leaves\Table;
use Rhubarb\Leaf\Views\View;

class StringColumnsView extends View
{
    private $table;

    protected function createSubLeaves()
    {
        $this->registerSubLeaf(
            $this->table = new Table(Job::all())
        );

        $this->table->columns = [
            "JobTitle",
            "Status",
            "Sent"
        ];
    }

    protected function printViewContent()
    {
        print $this->table;
    }

}
                                    

In this example our column definitions are just strings but because they match columns defined in our model's schema, the Table class upscales these to ModelColumn objects. In fact some columns may map to more specific specification types based on their column type. In this example the Boolean "Sent" column is being upscaled to a BooleanColumn. Time and date are also treated in this way.

When columns are upscaled in this way the label will interpret camelCaseColumnNames and convert them to space separated title cased strings.

Labels and templates

Each column has a label used in the header row. This can be changed by supplying a string key for your column definition:

Title Status Sent
Job A Incoming Yes
Job B Incoming No
Job C Outgoing Yes
Job D Outgoing No
Job E Stale Yes
Job F Stale No
<?php

namespace Rhubarb\Leaf\Table\Examples\BasicUsage;

use Rhubarb\Leaf\Table\Leaves\Table;
use Rhubarb\Leaf\Views\View;

class LabelMappingView extends View
{
    private $table;

    protected function createSubLeaves()
    {
        $this->registerSubLeaf(
            $this->table = new Table(Job::all())
        );

        $this->table->columns = [
            'Title' => 'JobTitle',                                                  // This one is re-labelled
            'Status' => '<a href="https://google.com/?q={Status}">{Status}</a>',    // This one is a template
            'Sent'
        ];
    }

    protected function printViewContent()
    {
        print $this->table;
    }

}
                                    

Note how the Status column has been changed to a string including placeholders using braces. As this string no longer matches a model column name it will be upscaled to a TemplateColumn. A TemplateColumn will replace all matching placeholders that exist in the model with their appropriate values. Implemented in this way however you loose the ability to sort on this column as the Table no longer can guess which column should be sorted on.

Being specific with column types.

Instead of passing strings in the columns array you can pass TableColumn objects. These encapsulate the full specification of a column and so give you full control. You can of course create your own column objects to provide very specific and custom behaviours.

Built into the Table module are the following Column types:

TableColumn
The base column type. Abstract so it must be extended. It provides a pattern of two main functions for returning and formatting values discussed in more detail below.
Template
Passed a template string with {} placeholders, it will replace those placeholders that match columns on the model.
SortableColumn
Not actually a class but an interface which if implemented on a column provides the Table with the name of the column to sort by when the column is clicked.
ModelColumn
Implements SortableColumn and takes a column name as a constructor argument. Will present that value in the model. Registers the same column as the column to sort by.
BooleanColumn
Extends ModelColumn and formats boolean values into "Yes" or "No"
TimeColumn
Formats model values using a supplied PHP date format. Defaults to H:i
DateColumn
Formats model values using a supplied PHP date format. Defaults to jS F Y
ClosureColumn
Takes a closure function in the constructor and calls this passing in the model for every row. The return value of the function is printed as the cell value.
LeafColumn
Takes a reference to a Leaf object (usually a control) and prints it using a view index of the unique identifier of the model for the row. Discussed in more detail below.
# Title Sent #2
View Job Job A Yes 1
View Job Job B No 4
View Job Job C Yes 9
View Job Job D No 16
View Job Job E Yes 25
View Job Job F No 36
<?php

namespace Rhubarb\Leaf\Table\Examples\BasicUsage;

use Rhubarb\Leaf\Controls\Common\Checkbox\Checkbox;
use Rhubarb\Leaf\Table\Leaves\Columns\ClosureColumn;
use Rhubarb\Leaf\Table\Leaves\Columns\LeafColumn;
use Rhubarb\Leaf\Table\Leaves\Columns\ModelColumn;
use Rhubarb\Leaf\Table\Leaves\Columns\Template;
use Rhubarb\Leaf\Table\Leaves\Table;
use Rhubarb\Leaf\Views\View;

class MixedColumnsView extends View
{
    private $table;

    protected function createSubLeaves()
    {
        $this->registerSubLeaf(
            $this->table = new Table(Job::all()),
            $checkbox = new Checkbox("selectedJobs")
        );

        $this->table->columns = [
            new Template("<a href='{JobID}'>View Job</a>", '#'),
            new ModelColumn("JobTitle", "Title"),
            "Sent",
            new ClosureColumn("#<sup>2</sup>", function(Job $job){
                return $job->JobID * $job->JobID;
            }),
            new LeafColumn($checkbox)
        ];
    }

    protected function printViewContent()
    {
        print $this->table;
    }

    public function getDeploymentPackage()
    {
        $package = parent::getDeploymentPackage();
        $package->resourcesToDeploy[] = __DIR__.'/Table.css';

        return $package;
    }
}
                                    

Having a reference to the actual column definition lets you also configure custom CSS classes for the <td> and <th> tags.

JobTitle Status Sent
Job A Incoming Yes
Job B Incoming No
Job C Outgoing Yes
Job D Outgoing No
Job E Stale Yes
Job F Stale No
<?php

namespace Rhubarb\Leaf\Table\Examples\BasicUsage;

use Rhubarb\Leaf\Table\Leaves\Columns\ModelColumn;
use Rhubarb\Leaf\Table\Leaves\Table;
use Rhubarb\Leaf\Views\View;

class CellFormattingView extends View
{
    private $table;

    protected function createSubLeaves()
    {
        $this->registerSubLeaf(
            $this->table = new Table(Job::all())
        );

        $this->table->columns = [
            $title = new ModelColumn("JobTitle"),
            "Status",
            "Sent"
        ];

        $title->addCssClass("red");
    }

    protected function printViewContent()
    {
        print $this->table;
    }

}
                                    

Handling related values

Building a custom column definition

Changing the sort behaviour

Adding interactive elements