Skip to content

Commit

Permalink
Added lots of documentation for table and particularly totals. added …
Browse files Browse the repository at this point in the history
…afterRow hook
  • Loading branch information
mvorisek committed Aug 12, 2023
1 parent fe9214c commit e53fa7b
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 3 deletions.
133 changes: 130 additions & 3 deletions docs/table.md
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ last decorator.
:::
:::{php:attr} totals
:::
:::{php:method} addTotals()
:::{php:method} addTotals($plan, $plan_id = null)
:::


Expand All @@ -495,6 +495,16 @@ but here is what actually happens:
or uses {php:class}`Paginator` you should calculate totals differently. See {php:meth}`Grid::addGrandTotals`
::

Method addTotals() can be executed multiple times and every time it defines a new plan and
will be reflected as an extra row for totals.

To illustrate the need for multiple totals plans, here are some the scenarios which Table allows
you to cover:

- Add "subtotal" then "tax" and then "total" row to your table.
- Create "group totals" which will appear in the middle of the table.
- Display per-page total and grand totals (for entire table).

### Definition of a "totals plan"

Each column may have a different plan, which consists of stages:
Expand Down Expand Up @@ -526,18 +536,135 @@ is set. The above example can therefore be shortened:
$table->addTotals(['client' => 'Totals for {$clients} client(s)']);
```

In addition to the plans you define, there is also going to be `{$_row_count}` which automatically counts
number of rows in your table.

### Possible values for total plan stages

`init` value is typically a number, but can be any value, especially if you are going to control it's
increment / formatting.

`update` can be string - either "sum" or "increment". Other values are not supported. You can also pass
a callable which gives you an option to perform update yourself.
`update` can be string. Supported built-ins are:

- min
- inc
- max
- sum
- avg

You can use a callable which gives you an option to perform update yourself. Also, make note that `inc`
will ONLY increment when value of the column it's associated with is not empty. If you need to get
total number of rows, use a special value `{$_row_count}`

Update can also be set to `false` if you don't want update to take place. If not set, or set to `null`
then default action (based on column type) will be invoked.

`format` uses a template in a format suitable for {php:class}`Template`. Within the template you can
reference other fields too. A benefit for using template is that type formatting is done automatically
for you.

If `format` set to `null` or omitted then default action will be used which is to display totals only
`money` / `numeric` and title column ("Totals for 123 record(s)")

### Using Callbacks

Value of any stage may also be a callback. Callbacks will be executed during the appropriate stage execution
and the value will be used:

`init` defines callback like this:

```
function($model) {
// $model is not loaded yet!!
return 0; // initial value
}
```

`update` defines callback like this:

```
function($total, $value, $model) {
// $total is previous value
// $value is value of the column
// $model will be loaded to current column
}
```

Here is example how you can implement "longest value" function:

```
function ($total, $value) {
return strlen($value) > strlen($total) ? $value : $total;
}
```

`format` defines callback like this:

```
function ($total, $model) {
return 'Total is: '.$total;
}
```

:::{important} when defining format as a string, template engine performs value
formatting. If you define it through the callback, it's up to you.
::

### Some examples

Calculate total salary yourself:


```
$salary_value = my_calc_salary();
$table->addTotals(['salary'=> money_format($salary_value]));
```

:::{important} The value for the format above is passed through Template, so if user has control over
the value, he may reference model field you don't want him to see. Keep your security tight!!
::

Safer version of the above code would be:

```
$salary_value = my_calc_salary();
$table->addTotals(['salary'=> function() use($salary_value) { money_format($salary_value]); });
```

Here is another alternative:

```
$salary_value = my_calc_salary();
$table->addTotals(['salary'=> [
'init'=> $salary_value,
'update'=>false,
]);
```

Combine output into single column:

```
$table->addTotals([
'name'=>['update'=>'increment', 'format'=>'Total salary for {$name} employees is {$salary}'],
'salary'=>['update'=>'sum', 'format'=>false]
]);
```

With introduciton of callbacks you can show average value too:

```
$table->addTotals([
'name'=>['update'=>'increment', 'format'=>'Total salary for {$name} employees is {$salary}'],
'salary'=>['update'=>'sum', 'format'=>false]
]);
```

## Advanced Usage

Table is a very flexible object and can be extended through various means. This chapter will focus
Expand Down
2 changes: 2 additions & 0 deletions src/Table.php
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,8 @@ public function renderView()
$this->renderRow();

$rows++;

$this->hook('afterRow');
}

// Add totals rows or empty message
Expand Down

0 comments on commit e53fa7b

Please sign in to comment.