Commit b3b11514 by Qiang Xue

Finished draft implementation of GridView.

parent ca35bb05
...@@ -169,7 +169,7 @@ abstract class Application extends Module ...@@ -169,7 +169,7 @@ abstract class Application extends Module
public function registerErrorHandlers() public function registerErrorHandlers()
{ {
if (YII_ENABLE_ERROR_HANDLER) { if (YII_ENABLE_ERROR_HANDLER) {
ini_set('display_errors', 0); //ini_set('display_errors', 0);
set_exception_handler(array($this, 'handleException')); set_exception_handler(array($this, 'handleException'));
set_error_handler(array($this, 'handleError'), error_reporting()); set_error_handler(array($this, 'handleError'), error_reporting());
if ($this->memoryReserveSize > 0) { if ($this->memoryReserveSize > 0) {
......
...@@ -230,10 +230,10 @@ return array( ...@@ -230,10 +230,10 @@ return array(
'yii\widgets\ContentDecorator' => YII_PATH . '/widgets/ContentDecorator.php', 'yii\widgets\ContentDecorator' => YII_PATH . '/widgets/ContentDecorator.php',
'yii\widgets\DetailView' => YII_PATH . '/widgets/DetailView.php', 'yii\widgets\DetailView' => YII_PATH . '/widgets/DetailView.php',
'yii\widgets\FragmentCache' => YII_PATH . '/widgets/FragmentCache.php', 'yii\widgets\FragmentCache' => YII_PATH . '/widgets/FragmentCache.php',
'yii\widgets\grid\CheckboxColumn' => YII_PATH . '/widgets/grid/CheckboxColumn.php', 'yii\grid\CheckboxColumn' => YII_PATH . '/grid/CheckboxColumn.php',
'yii\widgets\grid\Column' => YII_PATH . '/widgets/grid/Column.php', 'yii\grid\Column' => YII_PATH . '/grid/Column.php',
'yii\widgets\grid\DataColumn' => YII_PATH . '/widgets/grid/DataColumn.php', 'yii\grid\DataColumn' => YII_PATH . '/grid/DataColumn.php',
'yii\widgets\GridView' => YII_PATH . '/widgets/GridView.php', 'yii\grid\GridView' => YII_PATH . '/grid/GridView.php',
'yii\widgets\InputWidget' => YII_PATH . '/widgets/InputWidget.php', 'yii\widgets\InputWidget' => YII_PATH . '/widgets/InputWidget.php',
'yii\widgets\LinkPager' => YII_PATH . '/widgets/LinkPager.php', 'yii\widgets\LinkPager' => YII_PATH . '/widgets/LinkPager.php',
'yii\widgets\LinkSorter' => YII_PATH . '/widgets/LinkSorter.php', 'yii\widgets\LinkSorter' => YII_PATH . '/widgets/LinkSorter.php',
......
...@@ -5,19 +5,28 @@ ...@@ -5,19 +5,28 @@
* @license http://www.yiiframework.com/license/ * @license http://www.yiiframework.com/license/
*/ */
namespace yii\widgets\grid; namespace yii\grid;
use Closure; use Closure;
use yii\base\InvalidConfigException; use yii\base\InvalidConfigException;
use yii\helpers\Html; use yii\helpers\Html;
/** /**
* CheckboxColumn displays a column of checkboxes in a grid view.
* Users may click on the checkboxes to select rows of the grid. The selected rows may be
* obtained by calling the following JavaScript code:
*
* ~~~
* var keys = $('#grid').yiiGridView('getSelectedRows');
* // keys is an array consisting of the keys associated with the selected rows
* ~~~
*
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @since 2.0
*/ */
class CheckboxColumn extends Column class CheckboxColumn extends Column
{ {
public $name; public $name = 'selection';
public $checkboxOptions = array(); public $checkboxOptions = array();
public $multiple = true; public $multiple = true;
......
...@@ -5,14 +5,14 @@ ...@@ -5,14 +5,14 @@
* @license http://www.yiiframework.com/license/ * @license http://www.yiiframework.com/license/
*/ */
namespace yii\widgets\grid; namespace yii\grid;
use Closure; use Closure;
use yii\base\Object; use yii\base\Object;
use yii\helpers\Html; use yii\helpers\Html;
use yii\widgets\GridView;
/** /**
* Column is the base class of all [[GridView]] column classes.
* *
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @since 2.0
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
* @license http://www.yiiframework.com/license/ * @license http://www.yiiframework.com/license/
*/ */
namespace yii\widgets\grid; namespace yii\grid;
use yii\base\InvalidConfigException;
use yii\base\Model; use yii\base\Model;
use yii\data\ActiveDataProvider; use yii\data\ActiveDataProvider;
use yii\db\ActiveQuery; use yii\db\ActiveQuery;
...@@ -20,8 +20,22 @@ use yii\helpers\Inflector; ...@@ -20,8 +20,22 @@ use yii\helpers\Inflector;
*/ */
class DataColumn extends Column class DataColumn extends Column
{ {
/**
* @var string the attribute name associated with this column. When neither [[content]] nor [[value]]
* is specified, the value of the specified attribute will be retrieved from each data model and displayed.
*
* Also, if [[header]] is not specified, the label associated with the attribute will be displayed.
*/
public $attribute; public $attribute;
/**
* @var \Closure an anonymous function that returns the value to be displayed for every data model.
* If this is not set, `$model[$attribute]` will be used to obtain the value.
*/
public $value; public $value;
/**
* @var string in which format should the value of each data model be displayed as (e.g. "text", "html").
* Supported formats are determined by the [[GridView::formatter|formatter]] used by the [[GridView]].
*/
public $format; public $format;
/** /**
* @var boolean whether to allow sorting by this column. If true and [[attribute]] is found in * @var boolean whether to allow sorting by this column. If true and [[attribute]] is found in
...@@ -30,13 +44,13 @@ class DataColumn extends Column ...@@ -30,13 +44,13 @@ class DataColumn extends Column
*/ */
public $enableSorting = true; public $enableSorting = true;
/** /**
* @var string|array|boolean the HTML code representing a filter input (eg a text field, a dropdown list) * @var string|array|boolean the HTML code representing a filter input (e.g. a text field, a dropdown list)
* that is used for this data column. This property is effective only when * that is used for this data column. This property is effective only when [[GridView::filterModel]] is set.
* {@link CGridView::filter} is set. *
* If this property is not set, a text field will be generated as the filter input; * - If this property is not set, a text field will be generated as the filter input;
* If this property is an array, a dropdown list will be generated that uses this property value as * - If this property is an array, a dropdown list will be generated that uses this property value as
* the list options. * the list options.
* If you don't want a filter for this data column, set this value to false. * - If you don't want a filter for this data column, set this value to be false.
*/ */
public $filter; public $filter;
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* @license http://www.yiiframework.com/license/ * @license http://www.yiiframework.com/license/
*/ */
namespace yii\widgets; namespace yii\grid;
use Yii; use Yii;
use Closure; use Closure;
...@@ -14,8 +14,7 @@ use yii\base\InvalidConfigException; ...@@ -14,8 +14,7 @@ use yii\base\InvalidConfigException;
use yii\base\Widget; use yii\base\Widget;
use yii\db\ActiveRecord; use yii\db\ActiveRecord;
use yii\helpers\Html; use yii\helpers\Html;
use yii\widgets\grid\DataColumn; use yii\widgets\ListViewBase;
use yii\widgets\grid\GridViewAsset;
/** /**
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
...@@ -27,20 +26,69 @@ class GridView extends ListViewBase ...@@ -27,20 +26,69 @@ class GridView extends ListViewBase
const FILTER_POS_FOOTER = 'footer'; const FILTER_POS_FOOTER = 'footer';
const FILTER_POS_BODY = 'body'; const FILTER_POS_BODY = 'body';
/**
* @var string the default data column class if the class name is not explicitly specified when configuring a data column.
* Defaults to 'yii\grid\DataColumn'.
*/
public $dataColumnClass; public $dataColumnClass;
/**
* @var string the caption of the grid table
* @see captionOptions
*/
public $caption; public $caption;
/**
* @var array the HTML attributes for the caption element
* @see caption
*/
public $captionOptions = array(); public $captionOptions = array();
/**
* @var array the HTML attributes for the grid table element
*/
public $tableOptions = array('class' => 'table table-striped table-bordered'); public $tableOptions = array('class' => 'table table-striped table-bordered');
/**
* @var array the HTML attributes for the table header row
*/
public $headerRowOptions = array(); public $headerRowOptions = array();
/**
* @var array the HTML attributes for the table footer row
*/
public $footerRowOptions = array(); public $footerRowOptions = array();
/**
* @var array|Closure the HTML attributes for the table body rows. This can be either an array
* specifying the common HTML attributes for all body rows, or an anonymous function that
* returns an array of the HTML attributes. The anonymous function will be called once for every
* data model returned by [[dataProvider]]. It should have the following signature:
*
* ~~~php
* function ($model, $key, $index, $grid)
* ~~~
*
* - `$model`: the current data model being rendered
* - `$key`: the key value associated with the current data model
* - `$index`: the zero-based index of the data model in the model array returned by [[dataProvider]]
* - `$grid`: the GridView object
*/
public $rowOptions = array();
/**
* @var Closure an anonymous function that is called once BEFORE rendering each data model.
* It should have the similar signature as [[rowOptions]]. The return result of the function
* will be rendered directly.
*/
public $beforeRow; public $beforeRow;
/**
* @var Closure an anonymous function that is called once AFTER rendering each data model.
* It should have the similar signature as [[rowOptions]]. The return result of the function
* will be rendered directly.
*/
public $afterRow; public $afterRow;
/**
* @var boolean whether to show the header section of the grid table.
*/
public $showHeader = true; public $showHeader = true;
public $showFooter = false;
/** /**
* @var array|Closure * @var boolean whether to show the footer section of the grid table.
*/ */
public $rowOptions = array(); public $showFooter = false;
/** /**
* @var array|Formatter the formatter used to format model attribute values into displayable texts. * @var array|Formatter the formatter used to format model attribute values into displayable texts.
* This can be either an instance of [[Formatter]] or an configuration array for creating the [[Formatter]] * This can be either an instance of [[Formatter]] or an configuration array for creating the [[Formatter]]
...@@ -49,17 +97,31 @@ class GridView extends ListViewBase ...@@ -49,17 +97,31 @@ class GridView extends ListViewBase
public $formatter; public $formatter;
/** /**
* @var array grid column configuration. Each array element represents the configuration * @var array grid column configuration. Each array element represents the configuration
* for one particular grid column which can be either a string or an array. * for one particular grid column. For example,
* *
* When a column is specified as a string, it should be in the format of "name:type:header", * ~~~php
* where "type" and "header" are optional. A {@link CDataColumn} instance will be created in this case, * array(
* whose {@link CDataColumn::name}, {@link CDataColumn::type} and {@link CDataColumn::header} * array(
* properties will be initialized accordingly. * 'class' => SerialColumn::className(),
* ),
* array(
* 'class' => DataColumn::className(),
* 'attribute' => 'name',
* 'format' => 'text',
* 'header' => 'Name',
* ),
* array(
* 'class' => CheckboxColumn::className(),
* ),
* )
* ~~~
* *
* When a column is specified as an array, it will be used to create a grid column instance, where * If a column is of class [[DataColumn]], the "class" element can be omitted.
* the 'class' element specifies the column class name (defaults to {@link CDataColumn} if absent). *
* Currently, these official column classes are provided: {@link CDataColumn}, * As a shortcut format, a string may be used to specify the configuration of a data column
* {@link CLinkColumn}, {@link CButtonColumn} and {@link CCheckBoxColumn}. * which only contains "attribute", "format", and/or "header" options: `"attribute:format:header"`.
* For example, the above "name" column can also be specified as: `"name:text:Name"`.
* Both "format" and "header" are optional. They will take default values if absent.
*/ */
public $columns = array(); public $columns = array();
/** /**
...@@ -74,24 +136,28 @@ class GridView extends ListViewBase ...@@ -74,24 +136,28 @@ class GridView extends ListViewBase
public $layout = "{items}\n{summary}\n{pager}"; public $layout = "{items}\n{summary}\n{pager}";
public $emptyCell = '&nbsp;'; public $emptyCell = '&nbsp;';
/** /**
* @var \yii\base\Model the model instance that keeps the user-entered filter data. When this property is set, * @var \yii\base\Model the model that keeps the user-entered filter data. When this property is set,
* the grid view will enable column-based filtering. Each data column by default will display a text field * the grid view will enable column-based filtering. Each data column by default will display a text field
* at the top that users can fill in to filter the data. * at the top that users can fill in to filter the data.
* Note that in order to show an input field for filtering, a column must have its {@link CDataColumn::name} *
* property set or have {@link CDataColumn::filter} as the HTML code for the input field. * Note that in order to show an input field for filtering, a column must have its [[DataColumn::attribute]]
* When this property is not set (null) the filtering is disabled. * property set or have [[DataColumn::filter]] set as the HTML code for the input field.
*
* When this property is not set (null) the filtering feature is disabled.
*/ */
public $filterModel; public $filterModel;
/** /**
* @var string whether the filters should be displayed in the grid view. Valid values include: * @var string whether the filters should be displayed in the grid view. Valid values include:
* <ul> *
* <li>header: the filters will be displayed on top of each column's header cell.</li> * - [[FILTER_POS_HEADER]]: the filters will be displayed on top of each column's header cell.
* <li>body: the filters will be displayed right below each column's header cell.</li> * - [[FILTER_POS_BODY]]: the filters will be displayed right below each column's header cell.
* <li>footer: the filters will be displayed below each column's footer cell.</li> * - [[FILTER_POS_FOOTER]]: the filters will be displayed below each column's footer cell.
* </ul> */
public $filterPosition = self::FILTER_POS_BODY;
/**
* @var array the HTML attributes for the filter row element
*/ */
public $filterPosition = 'body'; public $filterRowOptions = array('class' => 'filters');
public $filterOptions = array('class' => 'filters');
/** /**
* Initializes the grid view. * Initializes the grid view.
...@@ -155,7 +221,7 @@ class GridView extends ListViewBase ...@@ -155,7 +221,7 @@ class GridView extends ListViewBase
{ {
$requireColumnGroup = false; $requireColumnGroup = false;
foreach ($this->columns as $column) { foreach ($this->columns as $column) {
/** @var \yii\widgets\grid\Column $column */ /** @var Column $column */
if (!empty($column->options)) { if (!empty($column->options)) {
$requireColumnGroup = true; $requireColumnGroup = true;
break; break;
...@@ -180,7 +246,7 @@ class GridView extends ListViewBase ...@@ -180,7 +246,7 @@ class GridView extends ListViewBase
{ {
$cells = array(); $cells = array();
foreach ($this->columns as $column) { foreach ($this->columns as $column) {
/** @var \yii\widgets\grid\Column $column */ /** @var Column $column */
$cells[] = $column->renderHeaderCell(); $cells[] = $column->renderHeaderCell();
} }
$content = implode('', $cells); $content = implode('', $cells);
...@@ -200,7 +266,7 @@ class GridView extends ListViewBase ...@@ -200,7 +266,7 @@ class GridView extends ListViewBase
{ {
$cells = array(); $cells = array();
foreach ($this->columns as $column) { foreach ($this->columns as $column) {
/** @var \yii\widgets\grid\Column $column */ /** @var Column $column */
$cells[] = $column->renderFooterCell(); $cells[] = $column->renderFooterCell();
} }
$content = implode('', $cells); $content = implode('', $cells);
...@@ -218,10 +284,10 @@ class GridView extends ListViewBase ...@@ -218,10 +284,10 @@ class GridView extends ListViewBase
if ($this->filterModel !== null) { if ($this->filterModel !== null) {
$cells = array(); $cells = array();
foreach ($this->columns as $column) { foreach ($this->columns as $column) {
/** @var \yii\widgets\grid\Column $column */ /** @var Column $column */
$cells[] = $column->renderFilterCell(); $cells[] = $column->renderFilterCell();
} }
return Html::tag('tr', implode('', $cells), $this->filterOptions); return Html::tag('tr', implode('', $cells), $this->filterRowOptions);
} else { } else {
return ''; return '';
} }
...@@ -239,7 +305,7 @@ class GridView extends ListViewBase ...@@ -239,7 +305,7 @@ class GridView extends ListViewBase
foreach ($models as $index => $model) { foreach ($models as $index => $model) {
$key = $keys[$index]; $key = $keys[$index];
if ($this->beforeRow !== null) { if ($this->beforeRow !== null) {
$row = call_user_func($this->beforeRow, $model, $key, $index); $row = call_user_func($this->beforeRow, $model, $key, $index, $this);
if (!empty($row)) { if (!empty($row)) {
$rows[] = $row; $rows[] = $row;
} }
...@@ -248,7 +314,7 @@ class GridView extends ListViewBase ...@@ -248,7 +314,7 @@ class GridView extends ListViewBase
$rows[] = $this->renderTableRow($model, $key, $index); $rows[] = $this->renderTableRow($model, $key, $index);
if ($this->afterRow !== null) { if ($this->afterRow !== null) {
$row = call_user_func($this->afterRow, $model, $key, $index); $row = call_user_func($this->afterRow, $model, $key, $index, $this);
if (!empty($row)) { if (!empty($row)) {
$rows[] = $row; $rows[] = $row;
} }
...@@ -267,12 +333,12 @@ class GridView extends ListViewBase ...@@ -267,12 +333,12 @@ class GridView extends ListViewBase
public function renderTableRow($model, $key, $index) public function renderTableRow($model, $key, $index)
{ {
$cells = array(); $cells = array();
/** @var \yii\widgets\grid\Column $column */ /** @var Column $column */
foreach ($this->columns as $column) { foreach ($this->columns as $column) {
$cells[] = $column->renderDataCell($model, $index); $cells[] = $column->renderDataCell($model, $index);
} }
if ($this->rowOptions instanceof Closure) { if ($this->rowOptions instanceof Closure) {
$options = call_user_func($this->rowOptions, $model, $key, $index); $options = call_user_func($this->rowOptions, $model, $key, $index, $this);
} else { } else {
$options = $this->rowOptions; $options = $this->rowOptions;
} }
...@@ -306,7 +372,7 @@ class GridView extends ListViewBase ...@@ -306,7 +372,7 @@ class GridView extends ListViewBase
} }
/** /**
* Creates a {@link CDataColumn} based on a shortcut column specification string. * Creates a [[DataColumn]] object based on a string in the format of "attribute:format:header".
* @param string $text the column specification string * @param string $text the column specification string
* @return DataColumn the column instance * @return DataColumn the column instance
* @throws InvalidConfigException if the column specification is invalid * @throws InvalidConfigException if the column specification is invalid
...@@ -314,7 +380,7 @@ class GridView extends ListViewBase ...@@ -314,7 +380,7 @@ class GridView extends ListViewBase
protected function createDataColumn($text) protected function createDataColumn($text)
{ {
if (!preg_match('/^([\w\.]+)(:(\w*))?(:(.*))?$/', $text, $matches)) { if (!preg_match('/^([\w\.]+)(:(\w*))?(:(.*))?$/', $text, $matches)) {
throw new InvalidConfigException('The column must be specified in the format of "Attribute", "Attribute:Format" or "Attribute:Format:Header'); throw new InvalidConfigException('The column must be specified in the format of "attribute", "attribute:format" or "attribute:format:header');
} }
return Yii::createObject(array( return Yii::createObject(array(
'class' => $this->dataColumnClass ?: DataColumn::className(), 'class' => $this->dataColumnClass ?: DataColumn::className(),
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* @license http://www.yiiframework.com/license/ * @license http://www.yiiframework.com/license/
*/ */
namespace yii\widgets\grid; namespace yii\grid;
use yii\web\AssetBundle; use yii\web\AssetBundle;
......
...@@ -5,10 +5,11 @@ ...@@ -5,10 +5,11 @@
* @license http://www.yiiframework.com/license/ * @license http://www.yiiframework.com/license/
*/ */
namespace yii\widgets\grid; namespace yii\grid;
/** /**
* SerialColumn displays a column of row numbers (1-based). * SerialColumn displays a column of row numbers (1-based).
*
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @since 2.0
*/ */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment