Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

1353 lines (1202 sloc) 34.604 kb
<?php // vim:ts=4:sw=4:et:fdm=marker
/**
* This is a Basic Grid implementation, which produces fully
* functional HTML grid capable of filtering, sorting, paginating
* and using multiple column formatters.
*
* @link http://agiletoolkit.org/doc/grid
*
* Use:
* $grid=$this->add('Grid');
* $grid->setModel('User');
*
* @license See http://agiletoolkit.org/about/license
*//*
==ATK4===================================================
This file is part of Agile Toolkit 4
http://agiletoolkit.org/
(c) 2008-2013 Agile Toolkit Limited <info@agiletoolkit.org>
Distributed under Affero General Public License v3 and
commercial license.
See LICENSE or LICENSE_COM for more information
=====================================================ATK4=*/
class Grid_Advanced extends Grid_Basic
{
/** Sorting */
public $sortby = '0';
public $sortby_db = null;
/** For totals */
private $totals_title_field = null;
private $totals_title = "";
/** Static data source? */
public $data = null;
/**
* Paginator object
*
* @see addPaginator()
*/
public $paginator = null;
/**
* Paginator class name
*
* @see enablePaginator()
* */
public $paginator_class = 'Paginator';
/**
* QuickSearch object
*
* @see addQuickSearch()
*/
public $quick_search = null;
/**
* QuickSearch class name
*
* @see enableQuickSearch()
* */
public $quick_search_class = 'QuickSearch';
/**
* $tdparam property is an array with cell parameters specified in td tag.
* This should be a hash: 'param_name'=>'param_value'
* Following parameters treated and processed in a special way:
* 1) 'style': nested array, style parameter.
* items of this nested array converted to a form of style:
* style="param_name: param_value; param_name: param_value"
*
* All the rest are not checked and simply converted to a form of
* param_name="param_value"
*
* This is a tree-like array with the following structure:
* array(
* [level1] => dataset_row = array(
* [level2] => field = array(
* [level3] => tdparam_elements = array(
* param_name => param_value
* )
* )
* )
* )
*/
protected $tdparam = array();
// JavaScript widget
public $js_widget = 'ui.atk4_grid';
public $js_widget_arguments = array();
/** @private used in button formatters to share URL between methods */
public $_url = array();
/**
* Initialization
*
* @return void
*/
function init()
{
parent::init();
// sorting support
$this->sortby =
isset($_GET[$this->name.'_sort'])
? $this->memorize('sortby', $_GET[$this->name.'_sort'])
: $this->recall('sortby', '0');
}
// {{{ Misc features
/**
* Add default paginator to the grid
*
* @param int $rows row count per page
* @param array $options optional options array
*
* @return $this
*/
function enablePaginator($rows = 25, $options = null)
{
$this->addPaginator($rows, $options);
return $this;
}
/**
* Adds paginator to the grid
*
* @param int $rows row count per page
* @param array $options optional options array
* @param string $class optional paginator class name
*
* @return Paginator
*
* @todo decide, maybe we need to add $spot optional template spot like in addQuickSearch()
*/
function addPaginator($rows = 25, $options = null, $class = null)
{
// add only once
// @todo decide, maybe we should destroy and recreate to keep last one
if ($this->paginator) {
return $this->paginator;
}
$this->paginator = $this->add($class ?: $this->paginator_class, $options);
$this->paginator->setRowsPerPage($rows);
return $this->paginator;
}
/**
* Adds default QuickSearch to the grid
*
* @param array $fields array of fieldnames used in quick search
* @param array $options optional options array
*
* @return $this
*/
function enableQuickSearch($fields, $options = null)
{
$this->addQuickSearch($fields, $options);
return $this;
}
/**
* Adds QuickSearch to the grid
*
* @param array $fields array of fieldnames used in quick search
* @param array $options optional options array
* @param string $class optional quick search object class
* @param string $spot optional template spot
*
* @return QuickSearch
*/
function addQuickSearch($fields, $options = null, $class = null, $spot = null)
{
// add only once
// @todo decide, maybe we should destroy and recreate to keep last one
if ($this->quick_search) {
return $this->quick_search;
}
$this->quick_search = $this->add($class ?: $this->quick_search_class, $options, $spot ?: 'quick_search')
->useWith($this)
->useFields($fields);
return $this->quick_search;
}
/**
* Adds column ordering object
*
* With it you can reorder your columns
*
* @return Order
*/
function addOrder()
{
return $this->add('Order', 'columns')
->useArray($this->columns)
;
}
/**
* Adds column with checkboxes on the basis of Model definition
*
* @param mixed $field should be Form_Field object or jQuery selector of
* 1 field. When passing it as jQuery selector don't
* forget to use hash sign like "#myfield"
*/
function addSelectable($field)
{
$this->js_widget = null;
$this->js(true)
->_load('ui.atk4_checkboxes')
->atk4_checkboxes(array('dst_field' => $field));
$this->addColumn('checkbox', 'selected');
$this->addOrder()
->useArray($this->columns)
->move('selected', 'first')
->now();
}
// }}}
// {{{ Sorting
/**
* Returns data source iterator
*
* @return mixed
*/
function getIterator()
{
$iter = parent::getIterator();
// sorting support
if ($this->sortby) {
$desc = ($this->sortby_db[0] == '-');
$order = ltrim($this->sortby_db, '-');
$this->applySorting($iter, $order, $desc);
}
return $iter;
}
/**
* Make sortable
*
* @param string $db_sort
*
* @return $this
*/
function makeSortable($db_sort = null)
{
// reverse sorting
$reverse = false;
if ($db_sort[0] == '-') {
$reverse = true;
$db_sort = substr($db_sort, 1);
}
// used db field
if (!$db_sort) {
$db_sort = $this->last_column;
}
switch ((string)$this->sortby) {
// we are already sorting by this column
case $this->last_column:
$info = array('1', $reverse ? 0 : ("-".$this->last_column));
$this->sortby_db = $db_sort;
break;
// We are sorted reverse by this column
case "-" . $this->last_column:
$info = array('2', $reverse ? $this->last_column : '0');
$this->sortby_db = "-" . $db_sort;
break;
// we are not sorted by this column
default:
$info = array('0', $reverse ? ("-" . $this->last_column) : $this->last_column);
}
$this->columns[$this->last_column]['sortable'] = $info;
return $this;
}
/**
* Compare two strings and return:
* < 0 if str1 is less than str2;
* > 0 if str1 is greater than str2,
* and 0 if they are equal.
*
* Note that this comparison is case sensitive
*
* @param string $str1
* @param string $str2
*
* @return int
*/
function staticSortCompare($str1, $str2)
{
if ($this->sortby[0] == '-') {
return strcmp(
$str2[substr($this->sortby, 1)],
$str1[substr($this->sortby, 1)]
);
}
return strcmp(
$str1[$this->sortby],
$str2[$this->sortby]
);
}
/**
* Apply sorting on particular field
*
* @param Iterator $i
* @param string $field
* @param string $desc
*
* @return void
*/
function applySorting($i, $field, $desc)
{
if ($i instanceof DB_dsql) {
$i->order($field, $desc);
} elseif ($i instanceof SQL_Model) {
$i->setOrder($field, $desc);
} elseif ($i instanceof Model) {
$i->setOrder($field, $desc);
}
}
// }}}
// {{{ Rendering
/**
* Render grid
*
* @return void
*/
function render()
{
if ($this->js_widget) {
$fn = str_replace('ui.', '', $this->js_widget);
$this->js(true)
->_load($this->js_widget)
->$fn($this->js_widget_arguments);
}
parent::render();
}
/**
* Render Totals row
*
* @return void
*/
function renderTotalsRow()
{
parent::renderTotalsRow();
}
// }}}
// {{{ Formatting
/**
* Additional formatting for Totals row
*
* Extends CompleteLister formatTotalsRow method.
*
* Note: in this method you should only add *additional* formatting of
* totals row because standard row formatting will be already applied by
* calling parent::formatTotalsRow().
*
* @return void
*/
function formatTotalsRow()
{
// call CompleteLister formatTotalsRow method
parent::formatTotalsRow();
// additional formatting of totals row
$totals_columns = array_keys($this->totals) ?: array();
foreach ($this->columns as $field=>$column) {
// process formatters (additional to default formatters)
$this->executeFormatters($field, $column, 'format_totals_', true);
// totals title displaying
if ($field == $this->totals_title_field) {
$this->setTDParam($field, 'style/font-weight', 'bold');
}
// apply TD parameters to all columns
$this->applyTDParams($field, $this->totals_t);
}
// set title
if ($this->totals_title_field && $this->totals) {
$this->current_row_html[$this->totals_title_field] = sprintf(
$this->totals_title,
$this->current_row['row_count'],
$this->current_row['plural_s']
);
}
}
/**
* Returns ID of record
*
* @param string $idfield ID field name
*
* @return mixed
*/
public function getCurrentIndex($idfield = 'id')
{
// TODO: think more to optimize this method
if (is_array($this->data)) {
return array_search(current($this->data), $this->data);
}
// else it is dsql dataset...
return $this->current_row[$idfield];
}
/**
* Sets TD params
*
* @param string $field
* @param string $path
* @param string $value
*
* @return void
*/
public function setTDParam($field, $path, $value)
{
// if value is null, then do nothing
if ($value === null) {
return;
}
// adds a parameter. nested ones can be specified like 'style/color'
$path = explode('/', $path);
$current_position = &$this->tdparam[$this->getCurrentIndex()][$field];
if (!is_array($current_position)) {
$current_position = array();
}
foreach ($path as $part) {
if (array_key_exists($part, $current_position)) {
$current_position = &$current_position[$part];
} else {
$current_position[$part] = array();
$current_position = &$current_position[$part];
}
}
$current_position = $value;
}
/**
* Apply TD parameters to appropriate template
*
* You can pass row template to use too. That's useful to set up totals rows, for example.
*
* @param string $field Fieldname
* @param SQLite $row_template Optional row template
*
* @return void
*/
function applyTDParams($field, &$row_template = null)
{
// data row template by default
if (!$row_template) {
$row_template = &$this->row_t;
}
// setting cell parameters (tdparam)
$tdparam = @$this->tdparam[$this->getCurrentIndex()][$field];
$tdparam_str = '';
if (is_array($tdparam)) {
if (is_array($tdparam['style'])) {
$tdparam_str .= 'style="';
foreach ($tdparam['style'] as $key=>$value) {
$tdparam_str .= $key . ':' . $value . ';';
}
$tdparam_str .= '" ';
unset($tdparam['style']);
}
//walking and combining string
foreach ($tdparam as $id=>$value) {
$tdparam_str .= $id . '="' . $value . '" ';
}
// set TD param to appropriate row template
$row_template->set("tdparam_$field", trim($tdparam_str));
}
}
// }}}
// {{{ Totals
/**
* Sets totals title field and text
*
* @param string $field
* @param string $title
*
* @return $this
*/
function setTotalsTitle($field, $title = "Total: %s row%s")
{
$this->totals_title_field = $field;
$this->totals_title = $title;
return $this;
}
/**
* Add current rendered row values to totals
*
* Called before each formatRow() call.
*
* @return void
*/
function updateTotals()
{
parent::updateTotals();
}
/**
* Calculate grand totals of all rows
*
* Called one time on rendering phase - before renderRows() call.
*
* @return void
*/
function updateGrandTotals()
{
parent::updateGrandTotals();
}
/**
* Additional formatting of number fields for totals row
*
* @param string $field
*
* @return void
*/
function format_totals_number($field) {}
/**
* Additional formatting of money fields for totals row
*
* @param string $field
*
* @return void
*/
function format_totals_money($field) {}
/**
* Additional formatting of real number fields for totals row
*
* @param string $field
*
* @return void
*/
function format_totals_real($field) {}
/**
* Additional formatting of expander fields for totals row
*
* Basically we remove everything from such field
*
* @param string $field field name
* @param array $column column configuration
*
* @return void
*/
function format_totals_expander($field, $column) {
@$this->current_row_html[$field] = '';
}
/**
* Additional formatting of custom template fields for totals row
*
* Basically we remove everything from such field
*
* @param string $field field name
* @param array $column column configuration
*
* @return void
*/
function format_totals_template($field, $column) {
@$this->current_row_html[$field] = '';
}
/**
* Additional formatting of checkbox fields column for totals row
*
* Basically we remove everything from such field
*
* @param string $field field name
* @param array $column column configuration
*
* @return void
*/
function format_totals_checkbox($field, $column) {
@$this->current_row_html[$field] = '';
}
/**
* Additional formatting of delete button fields for totals row
*
* Basically we remove everything from such field
*
* @param string $field field name
* @param array $column column configuration
*
* @return void
*/
function format_totals_delete($field, $column) {
@$this->current_row_html[$field] = '';
}
// }}}
// {{{ Expander
/**
* Initialize expander
*
* @param string $field field name
*
* @return void
*/
function init_expander($field)
{
// set column style
@$this->columns[$field]['thparam'] .= ' style="width:40px; text-align:center"';
// set column refid - referenced model table for example
if (!isset($this->columns[$field]['refid'])) {
if ($this->model) {
$refid = $this->model->table;
} elseif ($this->dq) {
$refid = $this->dq->args['table'];
} else {
$refid = preg_replace('/.*_/', '', $this->api->page);
}
$this->columns[$field]['refid'] = $refid;
}
// initialize button widget on page load
$class = $this->name.'_'.$field.'_expander';
$this->js(true)->find('.'.$class)->button();
// initialize expander
$this->js(true)
->_selector('.'.$class)
->_load('ui.atk4_expander')
->atk4_expander();
}
/**
* Format expander
*
* @param string $field field name
* @param array $column column configuration
*
* @return void
*/
function format_expander($field, $column)
{
if (!@$this->current_row[$field]) {
$this->current_row[$field] = $column['descr'];
}
// TODO:
// reformat this using Button, once we have more advanced system to
// bypass rendering of sub-elements.
// $this->current_row[$field] = $this->add('Button',null,false)
$key = $this->name . '_' . $field . '_';
$id = $key . $this->api->normalizeName($this->model->id);
$class = $key . 'expander';
@$this->current_row_html[$field] =
'<input type="checkbox" '.
'class="'.$class.'" '.
'id="'.$id.'" '.
'rel="'.$this->api->url(
$column['page'] ?: './'.$field,
array(
'expander' => $field,
'expanded' => $this->name,
'cut_page' => 1,
// TODO: id is obsolete
//'id' => $this->model->id,
$this->columns[$field]['refid'].'_id' => $this->model->id
)
).'" '.
'/>'.
'<label for="'.$id.'">' . $this->current_row[$field] . '</label>';
}
// }}}
// {{{ Formatters
/**
* Format field as HTML without encoding. Use with care.
*
* @param string $field
*
* @return void
*/
function format_html($field)
{
$this->current_row_html[$field] = $this->current_row[$field];
}
/**
* Format field as number
*
* @param string $field
*
* @return void
*/
function format_number($field) {}
/**
* Initialize column as real number
*
* @param string $field
*
* @return void
*/
function init_float($field)
{
@$this->columns[$field]['thparam'] .= ' style="text-align: right"';
}
/**
* Format field as real number with 2 digit precision
*
* @param string $field
*
* @return void
*/
function format_float($field)
{
$precision = 2;
$m = (float) $this->current_row[$field];
$this->current_row[$field] =
is_null($this->current_row[$field])
? '-'
: number_format($m, $precision);
$this->setTDParam($field, 'align', 'right');
$this->setTDParam($field, 'style/white-space', 'nowrap');
}
function init_real($field)
{
return $this->init_float($field);
}
function format_real($field)
{
return $this->format_float($field);
}
/**
* Initialize column as money
*
* @param string $field
*
* @return void
*/
function init_money($field)
{
@$this->columns[$field]['thparam'] .= ' style="text-align: right"';
}
/**
* Format field as money with 2 digit precision
*
* @param string $field
*
* @return void
*/
function format_money($field)
{
// use real number formatter
$this->format_real($field);
// negative values show in red color
if ($this->current_row[$field] < 0) {
$this->setTDParam($field, 'style/color', 'red');
}
}
/**
* Initialize column as boolean
*
* @param string $field
*
* @return void
*/
function init_boolean($field)
{
@$this->columns[$field]['thparam'] .= ' style="text-align: center"';
}
/**
* Format field as boolean
*
* @param string $field
*
* @return void
*/
function format_boolean($field)
{
if ($this->current_row[$field] && $this->current_row[$field] !== 'N') {
$this->current_row_html[$field] =
'<div align=center>'.
'<i class="icon-check">'.$this->api->_('yes').'</i>'.
'</div>';
} else {
$this->current_row_html[$field] = '';
}
}
/**
* Format field as object
*
* @param string $field
*
* @return void
*/
function format_object($field)
{
$this->current_row[$field] = (string)$this->current_row[$field];
return $this->format_shorttext($field);
}
/**
* Format field as date
*
* @param string $field
*
* @return void
*/
function format_date($field)
{
if (!$this->current_row[$field]) {
$this->current_row[$field] = '-';
} else {
$this->current_row[$field] = date(
$this->api->getConfig('locale/date', 'd/m/Y'),
strtotime($this->current_row[$field])
);
}
}
/**
* Format field as time
*
* @param string $field
*
* @return void
*/
function format_time($field)
{
$this->current_row[$field] = date(
$this->api->getConfig('locale/time', 'H:i:s'),
strtotime($this->current_row[$field])
);
}
/**
* Format field as datetime
*
* @param string $field
*
* @return void
*/
function format_datetime($field)
{
$d = $this->current_row[$field];
if (!$d) {
$this->current_row[$field] = '-';
} else {
if ($d instanceof MongoDate) {
$this->current_row[$field] = date(
$this->api->getConfig('locale/datetime', 'd/m/Y H:i:s'),
$d->sec
);
} elseif (is_numeric($d)) {
$this->current_row[$field] = date(
$this->api->getConfig('locale/datetime', 'd/m/Y H:i:s'),
$d
);
} else {
$d = strtotime($d);
$this->current_row[$field] = $d
? date(
$this->api->getConfig('locale/datetime', 'd/m/Y H:i:s'),
$d
)
: '-';
}
}
}
/**
* Format field as timestamp
*
* @param string $field
*
* @return void
*/
function format_timestamp($field)
{
$this->format_datetime($field);
}
/**
* Initialize column as fullwidth
*
* @param string $field
*
* @return void
*/
function init_fullwidth($field)
{
@$this->columns[$field]['thparam'] .= ' style="width: 100%"';
}
/**
* Format field as full width field
*
* @param string $field
*
* @return void
*/
function format_fullwidth($field){}
/**
* Format field as no-wrap field
*
* @param string $field
*
* @return void
*/
function format_nowrap($field)
{
$this->setTDParam($field, 'class', 'atk-text-nowrap');
}
/**
* Format field as wrap field
*
* @param string $field
*
* @return void
*/
function format_wrap($field)
{
$this->setTDParam($field, 'class', 'atk-text-wrap');
}
/**
* Format shorttext field
*
* @param string $field
*
* @return void
*/
function format_shorttext($field)
{
$text = $this->current_row[$field];
if (strlen($text) > 60) {
// Not sure about multi-byte support and execution speed of this
$a = explode(PHP_EOL, wordwrap($text, 28, PHP_EOL, true), 2);
$b = explode(PHP_EOL, wordwrap(strrev($text), 28, PHP_EOL, true), 2);
$text = $a[0] . ' ~~~ ' . strrev($b[0]);
}
$this->current_row[$field] = $text;
$this->setTDParam($field, 'title',
$this->api->encodeHtmlChars('huj = "'.$this->current_row[$field.'_original'],ENT_QUOTES));
}
/**
* Format password field
*
* @param string $field
*
* @return void
*/
function format_password($field)
{
$this->current_row[$field] = '***';
}
/**
* Format field as New-Line to BR-eak
*
* @param string $field
*
* @return void
*/
function format_nl2br($field)
{
$this->current_row[$field] = nl2br($this->current_row[$field]);
}
/**
* Format field as HTML image tag
*
* @param string $field
*
* @return void
*/
function format_image($field)
{
$this->current_row_html[$field] = '<img src="'.$this->current_row[$field].'" alt="" />';
}
/**
* Format field as checkbox
*
* @param string $field
*
* @return void
*/
function format_checkbox($field)
{
$this->current_row_html[$field] =
'<input type="checkbox" '.
'id="cb_'.$this->current_id.'" '.
'name="cb_'.$this->current_id.'" '.
'value="'.$this->current_id.'" '.
($this->current_row['selected'] == 'Y'
? "checked "
: ""
).
'/>';
$this->setTDParam($field, 'width', '10');
$this->setTDParam($field, 'align', 'center');
}
/**
* Initialize buttons column
*
* @param string $field
*
* @return void
*/
function init_button($field)
{
$this->on('click','.do-'.$field)->univ()->ajaxec(array(
$this->api->url(),
$field=>$a=$this->js()->_selectorThis()->data('id'),
$this->name.'_'.$field => $a
));
/*
@$this->columns[$field]['thparam'] .= ' style="width: 40px; text-align: center"';
$this->js(true)->find('.button_'.$field)->button();
*/
}
/**
* Initialize confirm buttons column
*
* @param string $field
*
* @return void
*/
function init_confirm($field)
{
$this->on('click','.do-'.$field)->univ()->confirm('Are you sure?')->ajaxec(array(
$this->api->url(),
$field=>$a=$this->js()->_selectorThis()->data('id'),
$this->name.'_'.$field => $a
));
}
/**
* Initialize prompt buttons column
*
* @param string $field
*
* @return void
*/
function init_prompt($field)
{
@$this->columns[$field]['thparam'] .= ' style="width: 40px; text-align: center"';
//$this->js(true)->find('.button_'.$field)->button();
}
/**
* Format field as button
*
* @param string $field
*
* @return void
*/
function format_button($field)
{
$class = $this->columns[$field]['button_class'];
$icon=$this->columns[$field]['icon'];
if($icon) {
if($icon[0]!='<')$icon='<span class="icon-'.$icon.'"></span>';
$icon.='&nbsp;';
}
$this->current_row_html[$field] =
'<button class="atk-button-small do-'.$field.' '.$class.'" data-id="'.$this->model->id.'">'.
$icon.$this->columns[$field]['descr'].
'</button>';
}
/**
* Format field as confirm button
*
* @param string $field
*
* @return void
*/
function format_confirm($field)
{
return $this->format_button($field);
$url = clone $this->_url[$field];
$class = $this->columns[$field]['button_class'].' button_'.$field;
$icon = isset($this->columns[$field]['icon'])
? $this->columns[$field]['icon']
: '';
$message = 'Are you sure?';
$this->current_row_html[$field] =
'<button type="button" class="'.$class.'" '.
'onclick="$(this).univ().confirm(\''.$message.'\').ajaxec(\'' .
$url->set(array(
$field => $this->current_id,
$this->name.'_'.$field => $this->current_id
)).'\')"'.
'>'.
$icon.
$this->columns[$field]['descr'].
'</button>';
}
/**
* Format field as prompt button
*
* @param string $field
*
* @return void
*/
function format_prompt($field)
{
$class = $this->columns[$field]['button_class'].' button_'.$field;
$icon = isset($this->columns[$field]['icon'])
? $this->columns[$field]['icon']
: '';
$message = 'Enter value: ';
$this->current_row_html[$field] =
'<button type="button" class="'.$class.'" '.
'onclick="value=prompt(\''.$message.'\');$(this).univ().ajaxec(\'' .
$this->api->url(null, array(
$field => $this->current_id,
$this->name.'_'.$field => $this->current_id
)) .
'&value=\'+value)"'.
'>'.
$icon.
$this->columns[$field]['descr'].
'</button>';
}
/**
* Initialize column with delete buttons
*
* @param string $field
*
* @return void
*/
function init_delete($field)
{
// set special CSS class for delete buttons to add some styling
$this->columns[$field]['button_class'] = 'atk-effect-danger atk-delete-button';
$this->columns[$field]['icon'] = 'trash';
// if this was clicked, then delete record
if ($id = @$_GET[$this->name.'_'.$field]) {
// delete record
$this->_performDelete($id);
// show message
$this->js()->univ()
->successMessage('Deleted Successfully')
->reload()
->execute();
}
// move button column at the end (to the right)
$self = $this;
$this->api->addHook('post-init', function() use($self, $field) {
if ($self->hasColumn($field)) {
$self->addOrder()->move($field, 'last')->now();
}
});
// ask for confirmation
$this->init_confirm($field);
}
/**
* Delete record from DB
*
* Formatter init_delete() calls this to delete current record from DB
*
* @param string $id ID of record
*
* @return void
*/
function _performDelete($id)
{
if ($this->model) {
$this->model->delete($id);
} else {
$this->dq->where('id', $id)->delete();
}
}
/**
* Format field as delete button
*
* @param string $field
*
* @return void
*/
function format_delete($field)
{
if (!$this->model) {
throw new BaseException('delete column requires $model to be set');
}
$this->format_confirm($field);
}
/**
* This allows you to use Template
*
* @param string $template template as a string
*
* @return $this
*/
function setTemplate($template, $field=null)
{
if($field === null)$field=$this->last_column;
$this->columns[$field]['template'] = $this->add('SMlite')
->loadTemplateFromString($template);
return $this;
}
/**
* Format field using template
*
* @param string $field
*
* @return void
*/
function format_template($field)
{
if (! ($t = $this->columns[$field]['template']) ) {
throw new BaseException('use setTemplate() for field '.$field);
}
$this->current_row_html[$field] = $t
->trySet('id',$this->current_id)
->set($this->current_row)
->trySet('_value_', $this->current_row[$field])
->render();
}
/**
* Initialize column with links using template
*
* @param string $field
*
* @return void
*/
function init_link($field)
{
$this->setTemplate('<a href="<?$_link?>"><?$'.$field.'?></a>',$field);
}
/**
* Format field as link
*
* @param string $field
*
* @return void
*/
function format_link($field)
{
$page = $this->columns[$field]['page'] ?: './'.$field;
$attr = $this->columns[$field]['id_field'] ?: 'id';
$this->current_row['_link'] =
$this->api->url($page, array($attr =>
$this->columns[$field]['id_value']
? $this->model[$this->columns[$field]['id_value']]
: $this->current_id));
if (!$this->current_row[$field]) {
$this->current_row[$field] = $this->columns[$field]['descr'];
}
return $this->format_template($field);
}
// }}}
}
Jump to Line
Something went wrong with that request. Please try again.