@@ -475,7 +475,7 @@ last decorator.
475475:::
476476:::{php: attr } totals
477477:::
478- :::{php: method } addTotals()
478+ :::{php: method } addTotals($plan, $plan_id = null )
479479:::
480480
481481
@@ -495,6 +495,16 @@ but here is what actually happens:
495495or uses {php: class }` Paginator ` you should calculate totals differently. See {php: meth }` Grid::addGrandTotals `
496496::
497497
498+ Method addTotals() can be executed multiple times and every time it defines a new plan and
499+ will be reflected as an extra row for totals.
500+
501+ To illustrate the need for multiple totals plans, here are some the scenarios which Table allows
502+ you to cover:
503+
504+ - Add "subtotal" then "tax" and then "total" row to your table.
505+ - Create "group totals" which will appear in the middle of the table.
506+ - Display per-page total and grand totals (for entire table).
507+
498508### Definition of a "totals plan"
499509
500510Each column may have a different plan, which consists of stages:
@@ -526,18 +536,135 @@ is set. The above example can therefore be shortened:
526536$table->addTotals(['client' => 'Totals for {$clients} client(s)']);
527537```
528538
539+ In addition to the plans you define, there is also going to be ` {$_row_count} ` which automatically counts
540+ number of rows in your table.
541+
529542### Possible values for total plan stages
530543
531544` init ` value is typically a number, but can be any value, especially if you are going to control it's
532545increment / formatting.
533546
534- ` update ` can be string - either "sum" or "increment". Other values are not supported. You can also pass
535- a callable which gives you an option to perform update yourself.
547+ ` update ` can be string. Supported built-ins are:
548+
549+ - min
550+ - inc
551+ - max
552+ - sum
553+ - avg
554+
555+ You can use a callable which gives you an option to perform update yourself. Also, make note that ` inc `
556+ will ONLY increment when value of the column it's associated with is not empty. If you need to get
557+ total number of rows, use a special value ` {$_row_count} `
558+
559+ Update can also be set to ` false ` if you don't want update to take place. If not set, or set to ` null `
560+ then default action (based on column type) will be invoked.
536561
537562` format ` uses a template in a format suitable for {php: class }` Template ` . Within the template you can
538563reference other fields too. A benefit for using template is that type formatting is done automatically
539564for you.
540565
566+ If ` format ` set to ` null ` or omitted then default action will be used which is to display totals only
567+ ` money ` / ` numeric ` and title column ("Totals for 123 record(s)")
568+
569+ ### Using Callbacks
570+
571+ Value of any stage may also be a callback. Callbacks will be executed during the appropriate stage execution
572+ and the value will be used:
573+
574+ ` init ` defines callback like this:
575+
576+ ```
577+ function($model) {
578+
579+ // $model is not loaded yet!!
580+
581+ return 0; // initial value
582+ }
583+ ```
584+
585+ ` update ` defines callback like this:
586+
587+ ```
588+ function($total, $value, $model) {
589+
590+ // $total is previous value
591+ // $value is value of the column
592+ // $model will be loaded to current column
593+ }
594+ ```
595+
596+ Here is example how you can implement "longest value" function:
597+
598+ ```
599+ function ($total, $value) {
600+ return strlen($value) > strlen($total) ? $value : $total;
601+ }
602+ ```
603+
604+ ` format ` defines callback like this:
605+
606+ ```
607+ function ($total, $model) {
608+ return 'Total is: '.$total;
609+ }
610+ ```
611+
612+ :::{important} when defining format as a string, template engine performs value
613+ formatting. If you define it through the callback, it's up to you.
614+ ::
615+
616+ ### Some examples
617+
618+ Calculate total salary yourself:
619+
620+
621+ ```
622+ $salary_value = my_calc_salary();
623+
624+ $table->addTotals(['salary'=> money_format($salary_value]));
625+ ```
626+
627+ :::{important} The value for the format above is passed through Template, so if user has control over
628+ the value, he may reference model field you don't want him to see. Keep your security tight!!
629+ ::
630+
631+ Safer version of the above code would be:
632+
633+ ```
634+ $salary_value = my_calc_salary();
635+
636+ $table->addTotals(['salary'=> function() use($salary_value) { money_format($salary_value]); });
637+ ```
638+
639+ Here is another alternative:
640+
641+ ```
642+ $salary_value = my_calc_salary();
643+
644+ $table->addTotals(['salary'=> [
645+ 'init'=> $salary_value,
646+ 'update'=>false,
647+ ]);
648+ ```
649+
650+ Combine output into single column:
651+
652+ ```
653+ $table->addTotals([
654+ 'name'=>['update'=>'increment', 'format'=>'Total salary for {$name} employees is {$salary}'],
655+ 'salary'=>['update'=>'sum', 'format'=>false]
656+ ]);
657+ ```
658+
659+ With introduciton of callbacks you can show average value too:
660+
661+ ```
662+ $table->addTotals([
663+ 'name'=>['update'=>'increment', 'format'=>'Total salary for {$name} employees is {$salary}'],
664+ 'salary'=>['update'=>'sum', 'format'=>false]
665+ ]);
666+ ```
667+
541668## Advanced Usage
542669
543670Table is a very flexible object and can be extended through various means. This chapter will focus
0 commit comments