Lançado Adianti Framework 7.6!
Clique aqui para saber mais
menu

Adianti Solutions

API

Adianti, Framework, PHP, MVC, Active record, Front controller, IDE, RAD, Web, multiplataforma, geração de código, desenvolvimento rápido, relatórios, formulários, listagens, datagrids, gráficos, banco de dados, padrões de projeto, design patterns API do Adianti Framework.
API Docs
code
Selecione a classe

Source for file TDataGrid.php

Documentation is available at TDataGrid.php

  1. <?php
  2. namespace Adianti\Widget\Datagrid;
  3.  
  4. use Adianti\Control\TAction;
  5. use Adianti\Core\AdiantiCoreTranslator;
  6. use Adianti\Widget\Container\TTable;
  7. use Adianti\Widget\Util\TDropDown;
  8. use Adianti\Widget\Base\TElement;
  9. use Adianti\Widget\Base\TScript;
  10. use Adianti\Widget\Form\TField;
  11. use Adianti\Widget\Form\THidden;
  12. use Adianti\Widget\Util\TImage;
  13. use Adianti\Util\AdiantiTemplateHandler;
  14.  
  15. use Math\Parser;
  16. use Exception;
  17.  
  18. /**
  19.  * DataGrid Widget: Allows to create datagrids with rows, columns and actions
  20.  *
  21.  * @version    7.4
  22.  * @package    widget
  23.  * @subpackage datagrid
  24.  * @author     Pablo Dall'Oglio
  25.  * @copyright  Copyright (c) 2006 Adianti Solutions Ltd. (http://www.adianti.com.br)
  26.  * @license    http://www.adianti.com.br/framework-license
  27.  */
  28. class TDataGrid extends TTable
  29. {
  30.     protected $columns;
  31.     protected $actions;
  32.     protected $action_groups;
  33.     protected $rowcount;
  34.     protected $thead;
  35.     protected $tbody;
  36.     protected $tfoot;
  37.     protected $height;
  38.     protected $scrollable;
  39.     protected $modelCreated;
  40.     protected $pageNavigation;
  41.     protected $defaultClick;
  42.     protected $groupColumn;
  43.     protected $groupContent;
  44.     protected $groupMask;
  45.     protected $popover;
  46.     protected $poptitle;
  47.     protected $popside;
  48.     protected $popcontent;
  49.     protected $popcondition;
  50.     protected $objects;
  51.     protected $actionWidth;
  52.     protected $groupCount;
  53.     protected $groupRowCount;
  54.     protected $columnValues;
  55.     protected $HTMLOutputConversion;
  56.     protected $searchAttributes;
  57.     protected $outputData;
  58.     protected $hiddenFields;
  59.     protected $prependRows;
  60.     protected $hasInlineEditing;
  61.     protected $hasTotalFunction;
  62.     protected $actionSide;
  63.     protected $mutationAction;
  64.     
  65.     /**
  66.      * Class Constructor
  67.      */
  68.     public function __construct()
  69.     {
  70.         parent::__construct();
  71.         $this->modelCreated = FALSE;
  72.         $this->defaultClick = TRUE;
  73.         $this->popover = FALSE;
  74.         $this->groupColumn = NULL;
  75.         $this->groupContent = NULL;
  76.         $this->groupMask = NULL;
  77.         $this->groupCount = 0;
  78.         $this->actions = array();
  79.         $this->action_groups = array();
  80.         $this->actionWidth = '28px';
  81.         $this->objects = array();
  82.         $this->columnValues = array();
  83.         $this->HTMLOutputConversion = true;
  84.         $this->searchAttributes = [];
  85.         $this->outputData = [];
  86.         $this->hiddenFields = false;
  87.         $this->prependRows = 0;
  88.         $this->hasInlineEditing = false;
  89.         $this->hasTotalFunction = false;
  90.         $this->actionSide = 'left';
  91.         
  92.         $this->rowcount = 0;
  93.         $this->{'class''tdatagrid_table';
  94.         $this->{'id'}    'tdatagrid_' mt_rand(10000000001999999999);
  95.     }
  96.     
  97.     /**
  98.      * Set id
  99.      */
  100.     public function setId($id)
  101.     {
  102.         $this->{'id'$id;
  103.     }
  104.     
  105.     /**
  106.      * Define mutation action
  107.      */
  108.     public function setMutationAction(TAction $action)
  109.     {
  110.         $this->mutationAction $action;
  111.     }
  112.     
  113.     /**
  114.      * Set actions side
  115.      */
  116.     public function setActionSide($side)
  117.     {
  118.         $this->actionSide $side;
  119.     }
  120.     
  121.     /**
  122.      * Generate hidden fields
  123.      */
  124.     public function generateHiddenFields()
  125.     {
  126.         $this->hiddenFields true;
  127.     }
  128.     
  129.     /**
  130.      * Disable htmlspecialchars on output
  131.      */
  132.     public function disableHtmlConversion()
  133.     {
  134.         $this->HTMLOutputConversion false;
  135.     }
  136.     
  137.     /**
  138.      * Get raw processed output data
  139.      */
  140.     public function getOutputData()
  141.     {
  142.         return $this->outputData;
  143.     }
  144.     
  145.     /**
  146.      * Enable popover
  147.      * @param $title Title
  148.      * @param $content Content
  149.      */
  150.     public function enablePopover($title$content$popside null$popcondition null)
  151.     {
  152.         $this->popover TRUE;
  153.         $this->poptitle $title;
  154.         $this->popcontent $content;
  155.         $this->popside $popside;
  156.         $this->popcondition $popcondition;
  157.     }
  158.     
  159.     /**
  160.      * Make the datagrid scrollable
  161.      */
  162.     public function makeScrollable()
  163.     {
  164.         $this->scrollable TRUE;
  165.         
  166.         if (isset($this->thead))
  167.         {
  168.             $this->thead->{'style''display: block';
  169.         }
  170.     }
  171.     
  172.     /**
  173.      * Returns if datagrid is scrollable
  174.      */
  175.     public function isScrollable()
  176.     {
  177.         return $this->scrollable;
  178.     }
  179.     
  180.     /**
  181.      * Returns true if has custom width
  182.      */
  183.     private function hasCustomWidth()
  184.     {
  185.         return ( (strpos((string) $this->getProperty('style')'width'!== falseOR !empty($this->getProperty('width')));
  186.     }
  187.     
  188.     /**
  189.      * Set the column action width
  190.      */
  191.     public function setActionWidth($width)
  192.     {
  193.         $this->actionWidth $width;
  194.     }
  195.     
  196.     /**
  197.      * disable the default click action
  198.      */
  199.     public function disableDefaultClick()
  200.     {
  201.         $this->defaultClick FALSE;
  202.     }
  203.     
  204.     /**
  205.      * Define the Height
  206.      * @param $height An integer containing the height
  207.      */
  208.     public function setHeight($height)
  209.     {
  210.         if (is_numeric($height))
  211.         {
  212.             $this->height $height 'px';
  213.         }
  214.         else
  215.         {
  216.             $this->height $height;
  217.         }
  218.     }
  219.     
  220.     /**
  221.      * Return datagrid height
  222.      */
  223.     public function getHeight()
  224.     {
  225.         return $this->height;
  226.     }
  227.     
  228.     /**
  229.      * Add a Column to the DataGrid
  230.      * @param $object A TDataGridColumn object
  231.      */
  232.     public function addColumn(TDataGridColumn $objectTAction $action null)
  233.     {
  234.         if ($this->modelCreated)
  235.         {
  236.             throw new Exception(AdiantiCoreTranslator::translate('You must call ^1 before ^2'__METHOD__ 'createModel') );
  237.         }
  238.         else
  239.         {
  240.             $this->columns[$object;
  241.             
  242.             if (!empty($action))
  243.             {
  244.                 $object->setAction($action);
  245.             }
  246.         }
  247.         
  248.         return $object;
  249.     }
  250.     
  251.     /**
  252.      * Returns an array of TDataGridColumn
  253.      */
  254.     public function getColumns()
  255.     {
  256.         return $this->columns;
  257.     }
  258.     
  259.     /**
  260.      * Add an Action to the DataGrid
  261.      * @param $object A TDataGridAction object
  262.      */
  263.     public function addAction(TDataGridAction $action$label null$image null)
  264.     {
  265.         if (!$action->fieldDefined())
  266.         {
  267.             throw new Exception(AdiantiCoreTranslator::translate('You must define the field for the action (^1)'$action->toString()) );
  268.         }
  269.         
  270.         if ($this->modelCreated)
  271.         {
  272.             throw new Exception(AdiantiCoreTranslator::translate('You must call ^1 before ^2'__METHOD__ 'createModel') );
  273.         }
  274.         else
  275.         {
  276.             $this->actions[$action;
  277.             
  278.             if (!empty($label))
  279.             {
  280.                 $action->setLabel($label);
  281.             }
  282.             
  283.             if (!empty($image))
  284.             {
  285.                 $action->setImage($image);
  286.             }
  287.         }
  288.     }
  289.     
  290.     /**
  291.      * Prepare for printing
  292.      */
  293.     public function prepareForPrinting()
  294.     {
  295.         parent::clearChildren();
  296.         $this->actions [];
  297.         $this->prependRows 0;
  298.         
  299.         if ($this->columns)
  300.         {
  301.             foreach ($this->columns as $column)
  302.             {
  303.                 $column->removeAction();
  304.             }
  305.         }
  306.         
  307.         $this->createModel();
  308.     }
  309.     
  310.     /**
  311.      * Add an Action Group to the DataGrid
  312.      * @param $object A TDataGridActionGroup object
  313.      */
  314.     public function addActionGroup(TDataGridActionGroup $object)
  315.     {
  316.         if ($this->modelCreated)
  317.         {
  318.             throw new Exception(AdiantiCoreTranslator::translate('You must call ^1 before ^2'__METHOD__ 'createModel') );
  319.         }
  320.         else
  321.         {
  322.             $this->action_groups[$object;
  323.         }
  324.     }
  325.     
  326.     /**
  327.      * Returns the total columns
  328.      */
  329.     public function getTotalColumns()
  330.     {
  331.         return count($this->columnscount($this->actionscount($this->action_groups);
  332.     }
  333.     
  334.     /**
  335.      * Set the group column for break
  336.      */
  337.     public function setGroupColumn($column$mask)
  338.     {
  339.         $this->groupColumn $column;
  340.         $this->groupMask   $mask;
  341.     }
  342.     
  343.     /**
  344.      * Clear the DataGrid contents
  345.      */
  346.     public function clear$preserveHeader TRUE$rows 0)
  347.     {
  348.         if ($this->prependRows 0)
  349.         {
  350.             $rows += $this->prependRows;
  351.         }
  352.         
  353.         if ($this->modelCreated)
  354.         {
  355.             // copy the headers
  356.             $current_header $this->children[0];
  357.             $current_body   $this->children[1];
  358.             
  359.             if ($preserveHeader)
  360.             {
  361.                 // reset the row array
  362.                 $this->children array();
  363.                 // add the header again
  364.                 $this->children[$current_header;
  365.             }
  366.             else
  367.             {
  368.                 // reset the row array
  369.                 $this->children array();
  370.             }
  371.             
  372.             // add an empty body
  373.             $this->tbody new TElement('tbody');
  374.             $this->tbody->{'class''tdatagrid_body';
  375.             if ($this->scrollable)
  376.             {
  377.                 $this->tbody->{'style'"height: {$this->height}; display: block; overflow-y:scroll; overflow-x:hidden;";
  378.             }
  379.             parent::add($this->tbody);
  380.             
  381.             if ($rows)
  382.             {
  383.                 for ($n=0$n $rows$n++)
  384.                 {
  385.                     $this->tbody->add($current_body->getChildren()[$n]);
  386.                 }
  387.             }
  388.             
  389.             // restart the row count
  390.             $this->rowcount 0;
  391.             $this->objects array();
  392.             $this->columnValues array();
  393.             $this->groupContent NULL;
  394.         }
  395.     }
  396.     
  397.     /**
  398.      * Create header action cells
  399.      */
  400.     private function createHeaderActionCells$row )
  401.     {
  402.         $actions_count count($this->actionscount($this->action_groups);
  403.         
  404.         if ($actions_count >0)
  405.         {
  406.             for ($n=0$n $actions_count$n++)
  407.             {
  408.                 $cell new TElement('th');
  409.                 $row->add($cell);
  410.                 $cell->add('<span style="min-width:calc('.$this->actionWidth.' - 2px);display:block"></span>');
  411.                 $cell->{'class''tdatagrid_action';
  412.                 $cell->{'style''padding:0';
  413.                 $cell->{'width'$this->actionWidth;
  414.             }
  415.         }
  416.     }
  417.     
  418.     /**
  419.      * Creates the DataGrid Structure
  420.      */
  421.     public function createModel$create_header true )
  422.     {
  423.         if (!$this->columns)
  424.         {
  425.             return;
  426.         }
  427.         
  428.         if ($create_header)
  429.         {
  430.             $this->thead new TElement('thead');
  431.             $this->thead->{'class''tdatagrid_head';
  432.             parent::add($this->thead);
  433.             
  434.             $row new TElement('tr');
  435.             if ($this->scrollable)
  436.             {
  437.                 $this->thead->{'style''display:block';
  438.                 if ($this->hasCustomWidth())
  439.                 {
  440.                     $row->{'style''display: inline-table; width: calc(100% - 20px)';
  441.                 }
  442.             }
  443.             $this->thead->add($row);
  444.             
  445.             if ($this->actionSide == 'left')
  446.             {
  447.                 $this->createHeaderActionCells($row);
  448.             }
  449.             
  450.             // add some cells for the data
  451.             if ($this->columns)
  452.             {
  453.                 $output_row [];
  454.                 // iterate the DataGrid columns
  455.                 foreach ($this->columns as $column)
  456.                 {
  457.                     // get the column properties
  458.                     $name  $column->getName();
  459.                     $label $column->getLabel();
  460.                     $align $column->getAlign();
  461.                     $width $column->getWidth();
  462.                     $props $column->getProperties();
  463.                     
  464.                     if ($column->isSearchable())
  465.                     {
  466.                         $input_search $column->getInputSearch();
  467.                         $this->enableSearch($input_search$name);
  468.                         $label .= '&nbsp;'.$input_search;
  469.                     }
  470.                     
  471.                     $col_action $column->getAction();
  472.                     if ($col_action)
  473.                     {
  474.                         $action_params $col_action->getParameters();
  475.                     }
  476.                     else
  477.                     {
  478.                         $action_params null;
  479.                     }
  480.                     
  481.                     $output_row[$column->getLabel();
  482.                     
  483.                     if (isset($_GET['order']))
  484.                     {
  485.                         if ($_GET['order'== $name || (isset($action_params['order']&& $action_params['order'== $_GET['order']))
  486.                         {
  487.                             if (isset($_GET['direction']AND $_GET['direction'== 'asc')
  488.                             {
  489.                                 $label .= '<span class="fa fa-chevron-down blue" aria-hidden="true"></span>';
  490.                             }
  491.                             else
  492.                             {
  493.                                 $label .= '<span class="fa fa-chevron-up blue" aria-hidden="true"></span>';
  494.                             }
  495.                         }
  496.                     }
  497.                     // add a cell with the columns label
  498.                     $cell new TElement('th');
  499.                     $row->add($cell);
  500.                     $cell->add($label);
  501.                     
  502.                     $cell->{'class''tdatagrid_col';
  503.                     $cell->{'style'"text-align:$align;user-select:none";
  504.                     
  505.                     if ($props)
  506.                     {
  507.                         $cell->setProperties($props);
  508.                     }
  509.                     
  510.                     if ($width)
  511.                     {
  512.                         $cell->{'width'(strpos($width'%'!== false || strpos($width'px'!== false$width ($width 8).'px';
  513.                     }
  514.                     
  515.                     // verify if the column has an attached action
  516.                     if ($column->getAction())
  517.                     {
  518.                         $action $column->getAction();
  519.                         if (isset($_GET['direction']AND $_GET['direction'== 'asc' AND isset($_GET['order']AND ($_GET['order'== $name || (isset($action_params['order']&& $action_params['order'== $_GET['order'])) )
  520.                         {
  521.                             $action->setParameter('direction''desc');
  522.                         }
  523.                         else
  524.                         {
  525.                             $action->setParameter('direction''asc');
  526.                         }
  527.                         $url    $action->serialize();
  528.                         $cell->{'href'}        htmlspecialchars($url);
  529.                         $cell->{'style'}      .= ";cursor:pointer;";
  530.                         $cell->{'generator'}   'adianti';
  531.                     }
  532.                 }
  533.                 
  534.                 $this->outputData[$output_row;
  535.             }
  536.             
  537.             if ($this->actionSide == 'right')
  538.             {
  539.                 $this->createHeaderActionCells($row);
  540.             }
  541.         }
  542.         
  543.         // add one row to the DataGrid
  544.         $this->tbody new TElement('tbody');
  545.         $this->tbody->{'class''tdatagrid_body';
  546.         if ($this->scrollable)
  547.         {
  548.             $this->tbody->{'style'"height: {$this->height}; display: block; overflow-y:scroll; overflow-x:hidden;";
  549.         }
  550.         parent::add($this->tbody);
  551.         
  552.         $this->modelCreated TRUE;
  553.     }
  554.     
  555.     /**
  556.      * Return thead
  557.      */
  558.     public function getHead()
  559.     {
  560.         return $this->thead;
  561.     }
  562.     
  563.     /**
  564.      * Return tbody
  565.      */
  566.     public function getBody()
  567.     {
  568.         return $this->tbody;
  569.     }
  570.     
  571.     /**
  572.      * Prepend row
  573.      */
  574.     public function prependRow($row)
  575.     {
  576.         $this->getBody()->add($row);
  577.         $this->getHead()->{'noborder''1';
  578.         $this->prependRows ++;
  579.     }
  580.     
  581.     /**
  582.      * insert content
  583.      */
  584.     public function insert($position$content)
  585.     {
  586.         $this->tbody->insert($position$content);
  587.     }
  588.     
  589.     /**
  590.      * Add objects to the DataGrid
  591.      * @param $objects An array of Objects
  592.      */
  593.     public function addItems($objects)
  594.     {
  595.         if ($objects)
  596.         {
  597.             foreach ($objects as $object)
  598.             {
  599.                 $this->addItem($object);
  600.             }
  601.         }
  602.     }
  603.     
  604.     /**
  605.      * Create item actions
  606.      * @param $row DOM Row
  607.      * @param $object Data Object
  608.      */
  609.     private function createItemActions($row$object)
  610.     {
  611.         $first_url null;
  612.         
  613.         if ($this->actions)
  614.         {
  615.             // iterate the actions
  616.             foreach ($this->actions as $action_template)
  617.             {
  618.                 // validate, clone, and inject object parameters
  619.                 $action $action_template->prepare($object);
  620.                 
  621.                 // get the action properties
  622.                 $label     $action->getLabel();
  623.                 $image     $action->getImage();
  624.                 $condition $action->getDisplayCondition();
  625.                 
  626.                 if (empty($conditionOR call_user_func($condition$object))
  627.                 {
  628.                     $url       $action->serialize();
  629.                     $first_url = isset($first_url$first_url $url;
  630.                     
  631.                     // creates a link
  632.                     $link new TElement('a');
  633.                     $link->{'href'}      htmlspecialchars($url);
  634.                     $link->{'generator''adianti';
  635.                     
  636.                     // verify if the link will have an icon or a label
  637.                     if ($image)
  638.                     {
  639.                         $image_tag is_object($imageclone $image new TImage($image);
  640.                         $image_tag->{'title'$label;
  641.                         
  642.                         if ($action->getUseButton())
  643.                         {
  644.                             // add the label to the link
  645.                             $span new TElement('span');
  646.                             $span->{'class'$action->getButtonClass($action->getButtonClass('btn btn-default';
  647.                             $span->add($image_tag);
  648.                             $span->add($label);
  649.                             $link->add($span);
  650.                         }
  651.                         else
  652.                         {
  653.                             $link->add$image_tag );
  654.                         }
  655.                     }
  656.                     else
  657.                     {
  658.                         // add the label to the link
  659.                         $span new TElement('span');
  660.                         $span->{'class'$action->getButtonClass($action->getButtonClass('btn btn-default';
  661.                         $span->add($label);
  662.                         $link->add($span);
  663.                     }
  664.                 }
  665.                 else
  666.                 {
  667.                     $link '';
  668.                 }
  669.                 
  670.                 // add the cell to the row
  671.                 $cell new TElement('td');
  672.                 $row->add($cell);
  673.                 $cell->add($link);
  674.                 $cell->{'style''min-width:'$this->actionWidth;
  675.                 $cell->{'class''tdatagrid_cell action';
  676.             }
  677.         }
  678.         
  679.         if ($this->action_groups)
  680.         {
  681.             foreach ($this->action_groups as $action_group)
  682.             {
  683.                 $actions    $action_group->getActions();
  684.                 $headers    $action_group->getHeaders();
  685.                 $separators $action_group->getSeparators();
  686.                 
  687.                 if ($actions)
  688.                 {
  689.                     $dropdown new TDropDown($action_group->getLabel()$action_group->getIcon());
  690.                     $last_index 0;
  691.                     foreach ($actions as $index => $action_template)
  692.                     {
  693.                         $action $action_template->prepare($object);
  694.                         
  695.                         // add intermediate headers and separators
  696.                         for ($n=$last_index$n<$index$n++)
  697.                         {
  698.                             if (isset($headers[$n]))
  699.                             {
  700.                                 $dropdown->addHeader($headers[$n]);
  701.                             }
  702.                             if (isset($separators[$n]))
  703.                             {
  704.                                 $dropdown->addSeparator();
  705.                             }
  706.                         }
  707.                         
  708.                         // get the action properties
  709.                         $label  $action->getLabel();
  710.                         $image  $action->getImage();
  711.                         $condition $action->getDisplayCondition();
  712.                         
  713.                         if (empty($conditionOR call_user_func($condition$object))
  714.                         {
  715.                             $url       $action->serialize();
  716.                             $first_url = isset($first_url$first_url $url;
  717.                             $dropdown->addAction($label$action$image);
  718.                         }
  719.                         $last_index $index;
  720.                     }
  721.                     // add the cell to the row
  722.                     $cell new TElement('td');
  723.                     $row->add($cell);
  724.                     $cell->add($dropdown);
  725.                     $cell->{'class''tdatagrid_cell action';
  726.                 }
  727.             }
  728.         }
  729.         
  730.         return $first_url;
  731.     }
  732.     
  733.     /**
  734.      * Add an object to the DataGrid
  735.      * @param $object An Active Record Object
  736.      */
  737.     public function addItem($object)
  738.     {
  739.         if ($this->modelCreated)
  740.         {
  741.             if ($this->groupColumn AND
  742.                 (is_null($this->groupContentOR $this->groupContent !== $object->{$this->groupColumn) )
  743.             {
  744.                 $row new TElement('tr');
  745.                 $row->{'class''tdatagrid_group';
  746.                 $row->{'level'= ++ $this->groupCount;
  747.                 $this->groupRowCount 0;
  748.                 if ($this->isScrollable(AND $this->hasCustomWidth())
  749.                 {
  750.                     $row->{'style''display: inline-table; width: 100%';
  751.                 }
  752.                 $this->tbody->add($row);
  753.                 $cell new TElement('td');
  754.                 $cell->addAdiantiTemplateHandler::replace($this->groupMask$object) );
  755.                 $cell->colspan count($this->actions)+count($this->action_groups)+count($this->columns);
  756.                 $row->add($cell);
  757.                 $this->groupContent $object->{$this->groupColumn};
  758.             }
  759.             
  760.             // define the background color for that line
  761.             $classname ($this->rowcount 2== 'tdatagrid_row_even' 'tdatagrid_row_odd';
  762.             
  763.             $row new TElement('tr');
  764.             $this->tbody->add($row);
  765.             $row->{'class'$classname;
  766.             
  767.             if ($this->isScrollable(AND $this->hasCustomWidth())
  768.             {
  769.                 $row->{'style''display: inline-table; width: 100%';
  770.             }
  771.             
  772.             if ($this->groupColumn)
  773.             {
  774.                 $this->groupRowCount ++;
  775.                 $row->{'childof'$this->groupCount;
  776.                 $row->{'level'}   $this->groupCount '.'$this->groupRowCount;
  777.             }
  778.             
  779.             if ($this->actionSide == 'left')
  780.             {
  781.                 $first_url $this->createItemActions$row$object );
  782.             }
  783.             
  784.             $output_row [];
  785.             $used_hidden [];
  786.             
  787.             if ($this->columns)
  788.             {
  789.                 // iterate the DataGrid columns
  790.                 foreach ($this->columns as $column)
  791.                 {
  792.                     // get the column properties
  793.                     $name     $column->getName();
  794.                     $align    $column->getAlign();
  795.                     $width    $column->getWidth();
  796.                     $function $column->getTransformer();
  797.                     $props    $column->getDataProperties();
  798.                     
  799.                     // calculated column
  800.                     if (substr($name,0,1== '=')
  801.                     {
  802.                         $content AdiantiTemplateHandler::replace($name$object'float');
  803.                         $content AdiantiTemplateHandler::evaluateExpression(substr($content,1));
  804.                         $object->$name $content;
  805.                     }
  806.                     else
  807.                     {
  808.                         try
  809.                         {
  810.                             @$content  $object->$name// fire magic methods
  811.                             
  812.                             if (is_null($content))
  813.                             {
  814.                                 $content AdiantiTemplateHandler::replace($name$object);
  815.                                 
  816.                                 if ($content === $name)
  817.                                 {
  818.                                     $content '';
  819.                                 }
  820.                             }
  821.                         }
  822.                         catch (Exception $e)
  823.                         {
  824.                             $content AdiantiTemplateHandler::replace($name$object);
  825.                             
  826.                             if (empty(trim($content)) OR $content === $name)
  827.                             {
  828.                                 $content $e->getMessage();
  829.                             }
  830.                         }
  831.                     }
  832.                     
  833.                     if (isset($this->columnValues[$name]))
  834.                     {
  835.                         $this->columnValues[$name][$content;
  836.                     }
  837.                     else
  838.                     {
  839.                         $this->columnValues[$name[$content];
  840.                     }
  841.                     
  842.                     $data is_null($content'' $content;
  843.                     $raw_data $data;
  844.                     
  845.                     if ($this->HTMLOutputConversion && is_scalar($data))
  846.                     {
  847.                         $data htmlspecialchars($dataENT_QUOTES ENT_HTML5'UTF-8');   // TAG value
  848.                     }
  849.                     
  850.                     $cell new TElement('td');
  851.                     
  852.                     // verify if there's a transformer function
  853.                     if ($function)
  854.                     {
  855.                         $last_row = isset($this->objects$this->rowcount -])$this->objects$this->rowcount -null;
  856.                         // apply the transformer functions over the data
  857.                         $data call_user_func($function$raw_data$object$row$cell$last_row);
  858.                     }
  859.                     
  860.                     $output_row[is_scalar($datastrip_tags($data'';
  861.                     
  862.                     if ($editaction $column->getEditAction())
  863.                     {
  864.                         $editaction_field $editaction->getField();
  865.                         $div new TElement('div');
  866.                         $div->{'class'}  'inlineediting';
  867.                         $div->{'style'}  'padding-left:5px;padding-right:5px';
  868.                         $div->{'action'$editaction->serialize();
  869.                         $div->{'field'}  $name;
  870.                         $div->{'key'}    = isset($object->{$editaction_field}$object->{$editaction_fieldNULL;
  871.                         $div->{'pkey'}   $editaction_field;
  872.                         $div->add($data);
  873.                         
  874.                         $this->hasInlineEditing true;
  875.                         
  876.                         $row->add($cell);
  877.                         $cell->add($div);
  878.                         $cell->{'class''tdatagrid_cell';
  879.                     }
  880.                     else
  881.                     {
  882.                         // add the cell to the row
  883.                         $row->add($cell);
  884.                         $cell->add($data);
  885.                         
  886.                         if ($this->hiddenFields AND !isset($used_hidden[$name]))
  887.                         {
  888.                             $hidden new THidden($this->id '_' $name.'[]');
  889.                             $hidden->{'data-hidden-field''true';
  890.                             $hidden->setValue($raw_data);
  891.                             $cell->add($hidden);
  892.                             $used_hidden[$nametrue;
  893.                         }
  894.                         
  895.                         $cell->{'class''tdatagrid_cell';
  896.                         $cell->{'align'$align;
  897.                         
  898.                         if (isset($first_urlAND $this->defaultClick)
  899.                         {
  900.                             $cell->{'href'}      $first_url;
  901.                             $cell->{'generator''adianti';
  902.                             $cell->{'class'}     'tdatagrid_cell';
  903.                         }
  904.                     }
  905.                     
  906.                     if ($props)
  907.                     {
  908.                         $cell->setProperties($props);
  909.                     }
  910.                     
  911.                     if ($width)
  912.                     {
  913.                         $cell->{'width'(strpos($width'%'!== false || strpos($width'px'!== false$width ($width 8).'px';
  914.                     }
  915.                 }
  916.                 
  917.                 $this->outputData[$output_row;
  918.             }
  919.             
  920.             if ($this->actionSide == 'right')
  921.             {
  922.                 $this->createItemActions$row$object );
  923.             }
  924.             
  925.             if ($this->popover && (empty($this->popconditionOR call_user_func($this->popcondition$object)))
  926.             {
  927.                 $poptitle   $this->poptitle;
  928.                 $popcontent $this->popcontent;
  929.                 $poptitle   AdiantiTemplateHandler::replace($poptitle$object);
  930.                 $popcontent AdiantiTemplateHandler::replace($popcontent$objectnulltrue);
  931.                 
  932.                 $row->{'popover''true';
  933.                 $row->{'poptitle'$poptitle;
  934.                 $row->{'popcontent'htmlspecialchars(str_replace("\n"''nl2br($popcontent)));
  935.                 
  936.                 if ($this->popside)
  937.                 {
  938.                     $row->{'popside'$this->popside;
  939.                 }
  940.             }
  941.             
  942.             if (count($this->searchAttributes0)
  943.             {
  944.                 $row->{'id''row_' mt_rand(10000000001999999999);
  945.                 
  946.                 foreach ($this->searchAttributes as $search_att)
  947.                 {
  948.                     @$search_content $object->$search_att// fire magic methods
  949.                     if (!empty($search_content))
  950.                     {
  951.                         $row_dom_search_att 'search_' str_replace(['-''>'],['_'''],$search_att);
  952.                         $row->$row_dom_search_att $search_content;
  953.                     }
  954.                 }
  955.             }
  956.             
  957.             $this->objects$this->rowcount $object;
  958.             
  959.             // increments the row counter
  960.             $this->rowcount ++;
  961.             
  962.             return $row;
  963.         }
  964.         else
  965.         {
  966.             throw new Exception(AdiantiCoreTranslator::translate('You must call ^1 before ^2''createModel'__METHOD__ ) );
  967.         }
  968.     }
  969.     
  970.     /**
  971.      * Append table row via Javascript
  972.      */
  973.     public static function appendRow$table_id$row )
  974.     {
  975.         $row64 base64_encode($row->getContents());
  976.         TScript::create("ttable_add_row('{$table_id}', 'body', '{$row64}')");
  977.     }
  978.     
  979.     /**
  980.      * Remove row by id
  981.      */
  982.     public static function removeRowById$table_id$id)
  983.     {
  984.         TScript::create("ttable_remove_row_by_id('{$table_id}', '{$id}')");
  985.     }
  986.     
  987.     /**
  988.      * Replace row by id
  989.      */
  990.     public static function replaceRowById$table_id$id$row)
  991.     {
  992.         $row64 base64_encode($row->getContents());
  993.         TScript::create("ttable_replace_row_by_id('{$table_id}', '{$id}', '{$row64}')");
  994.     }
  995.     
  996.     /**
  997.      * Return datagrid items
  998.      */
  999.     public function getItems()
  1000.     {
  1001.         return $this->objects;
  1002.     }
  1003.     
  1004.     /**
  1005.      * Process column totals
  1006.      */
  1007.     private function processTotals()
  1008.     {
  1009.         $has_total false;
  1010.         
  1011.         $this->tfoot new TElement('tfoot');
  1012.         $this->tfoot->{'class''tdatagrid_footer';
  1013.         
  1014.         if ($this->scrollable)
  1015.         {
  1016.             $this->tfoot->{'style'"display: block";
  1017.             $this->tfoot->{'style'"display: block; padding-right: 15px";
  1018.         }
  1019.         
  1020.         $row new TElement('tr');
  1021.         
  1022.         if ($this->isScrollable(AND $this->hasCustomWidth())
  1023.         {
  1024.             $row->{'style''display: inline-table; width: 100%';
  1025.         }
  1026.         $this->tfoot->add($row);
  1027.         
  1028.         if ($this->actionSide == 'left')
  1029.         {
  1030.             if ($this->actions)
  1031.             {
  1032.                 // iterate the actions
  1033.                 foreach ($this->actions as $action)
  1034.                 {
  1035.                     $cell new TElement('td');
  1036.                     $row->add($cell);
  1037.                 }
  1038.             }
  1039.             
  1040.             if ($this->action_groups)
  1041.             {
  1042.                 foreach ($this->action_groups as $action_group)
  1043.                 {
  1044.                     $cell new TElement('td');
  1045.                     $row->add($cell);
  1046.                 }
  1047.             }
  1048.         }
  1049.         
  1050.         if ($this->columns)
  1051.         {
  1052.             // iterate the DataGrid columns
  1053.             foreach ($this->columns as $column)
  1054.             {
  1055.                 $cell new TElement('td');
  1056.                 $row->add($cell);
  1057.                 
  1058.                 // get the column total function
  1059.                 $totalFunction $column->getTotalFunction();
  1060.                 $totalMask     $column->getTotalMask();
  1061.                 $totalCallback $column->getTotalCallback();
  1062.                 $transformer   $column->getTransformer();
  1063.                 $name          $column->getName();
  1064.                 $align         $column->getAlign();
  1065.                 $width         $column->getWidth();
  1066.                 $props         $column->getDataProperties();
  1067.                 $cell->{'style'"text-align:$align";
  1068.                 
  1069.                 if ($width)
  1070.                 {
  1071.                     $cell->{'width'(strpos($width'%'!== false || strpos($width'px'!== false$width ($width 8).'px';
  1072.                 }
  1073.                 
  1074.                 if ($props)
  1075.                 {
  1076.                     $cell->setProperties($props);
  1077.                 }
  1078.                 
  1079.                 if ($totalCallback)
  1080.                 {
  1081.                     $raw_content 0;
  1082.                     $content     0;
  1083.                     
  1084.                     if (count($this->objects0)
  1085.                     {
  1086.                         $raw_content $totalCallback($this->columnValues[$name]$this->objects);
  1087.                         $content     $raw_content;
  1088.                         
  1089.                         if ($transformer && $column->totalTransformed())
  1090.                         {
  1091.                             // apply the transformer functions over the data
  1092.                             $content call_user_func($transformer$contentnullnullnullnull);
  1093.                         }
  1094.                     }
  1095.                     
  1096.                     if (!empty($totalFunction|| !empty($totalCallback))
  1097.                     {
  1098.                         $this->hasTotalFunction true;
  1099.                         $cell->{'data-total-function'$totalFunction;
  1100.                         $cell->{'data-column-name'}    $name;
  1101.                         $cell->{'data-total-mask'}     $totalMask;
  1102.                         $cell->{'data-value'}          $raw_content;
  1103.                     }
  1104.                     $cell->add($content);
  1105.                 }
  1106.                 else
  1107.                 {
  1108.                     $cell->add('&nbsp;');
  1109.                 }
  1110.             }
  1111.         }
  1112.         
  1113.         if ($this->hasTotalFunction)
  1114.         {
  1115.             parent::add($this->tfoot);
  1116.         }
  1117.     }
  1118.     
  1119.     /**
  1120.      * Find the row index by object attribute
  1121.      * @param $attribute Object attribute
  1122.      * @param $value Object value
  1123.      */
  1124.     public function getRowIndex($attribute$value)
  1125.     {
  1126.         foreach ($this->objects as $pos => $object)
  1127.         {
  1128.             if ($object->$attribute == $value)
  1129.             {
  1130.                 return $pos;
  1131.             }
  1132.         }
  1133.         return NULL
  1134.     }
  1135.     
  1136.     /**
  1137.      * Return the row by position
  1138.      * @param $position Row position
  1139.      */
  1140.     public function getRow($position)
  1141.     {
  1142.         return $this->tbody->get($position);
  1143.     }
  1144.     
  1145.     /**
  1146.      * Returns the DataGrid's width
  1147.      * @return An integer containing the DataGrid's width
  1148.      */
  1149.     public function getWidth()
  1150.     {
  1151.         $width=0;
  1152.         if ($this->actions)
  1153.         {
  1154.             // iterate the DataGrid Actions
  1155.             foreach ($this->actions as $action)
  1156.             {
  1157.                 $width += 22;
  1158.             }
  1159.         }
  1160.         
  1161.         if ($this->columns)
  1162.         {
  1163.             // iterate the DataGrid Columns
  1164.             foreach ($this->columns as $column)
  1165.             {
  1166.                 if (is_numeric($column->getWidth()))
  1167.                 {
  1168.                     $width += $column->getWidth();
  1169.                 }
  1170.             }
  1171.         }
  1172.         return $width;
  1173.     }
  1174.     
  1175.     /**
  1176.      * Assign a PageNavigation object
  1177.      * @param $pageNavigation object
  1178.      */
  1179.     public function setPageNavigation($pageNavigation)
  1180.     {
  1181.         $this->pageNavigation $pageNavigation;
  1182.     }
  1183.     
  1184.     /**
  1185.      * Return the assigned PageNavigation object
  1186.      * @return $pageNavigation object
  1187.      */
  1188.     public function getPageNavigation()
  1189.     {
  1190.         return $this->pageNavigation;
  1191.     }
  1192.     
  1193.     /**
  1194.      * Set serach attributes
  1195.      */
  1196.     public function setSearchAttributes($attributes)
  1197.     {
  1198.         $this->searchAttributes $attributes;
  1199.     }
  1200.     
  1201.     /**
  1202.      * Enable fuse search
  1203.      * @param $input Field input for search
  1204.      * @param $attribute Attribute name
  1205.      */
  1206.     public function enableSearch(TField $input$attributes
  1207.     {
  1208.         if (count($this->objects)>0)
  1209.         {
  1210.             throw new Exception(AdiantiCoreTranslator::translate('You must call ^1 before ^2''enableSearch()''addItem()'));
  1211.         }
  1212.         
  1213.         $input_id    $input->getId();
  1214.         $datagrid_id $this->{'id'};
  1215.         $att_names   explode(','$attributes);
  1216.         $dom_atts    [];
  1217.         
  1218.         if ($att_names)
  1219.         {
  1220.             foreach ($att_names as $att_name)
  1221.             {
  1222.                 $att_name trim($att_name);
  1223.                 $this->searchAttributes[$att_name;
  1224.                 $dom_search_atts[str_replace(['-''>']['_''']"search_{$att_name}");
  1225.             }
  1226.             
  1227.             $dom_att_string implode(','$dom_search_atts);
  1228.             TScript::create("__adianti_input_fuse_search('#{$input_id}', '{$dom_att_string}', '#{$datagrid_id} tr')");
  1229.         }
  1230.     }
  1231.     
  1232.     /**
  1233.      * Shows the DataGrid
  1234.      */
  1235.     public function show()
  1236.     {
  1237.         $this->processTotals();
  1238.         
  1239.         if (!$this->hasCustomWidth())
  1240.         {
  1241.             $this->{'style'.= ';width:unset';
  1242.         }
  1243.         
  1244.         // shows the datagrid
  1245.         parent::show();
  1246.         
  1247.         $params $_REQUEST;
  1248.         unset($params['class']);
  1249.         unset($params['method']);
  1250.         // to keep browsing parameters (order, page, first_page, ...)
  1251.         $urlparams='&'.http_build_query($params);
  1252.         
  1253.         // inline editing treatment
  1254.         if ($this->hasInlineEditing)
  1255.         {
  1256.             TScript::create(" tdatagrid_inlineedit( '{$urlparams}' );");
  1257.         }
  1258.         
  1259.         if ($this->groupColumn)
  1260.         {
  1261.             TScript::create(" tdatagrid_enable_groups();");
  1262.         }
  1263.         
  1264.         if ($this->hasTotalFunction)
  1265.         {
  1266.             TScript::create(" tdatagrid_update_total('#{$this->{'id'}}');");
  1267.         }
  1268.         
  1269.         if ($this->mutationAction)
  1270.         {
  1271.             $url $this->mutationAction->serialize(false);
  1272.             TScript::create(" tdatagrid_mutation_action('#{$this->{'id'}}', '$url');");
  1273.         }
  1274.     }
  1275. }