forked from kartik-v/yii2-grid
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDataColumn.php
executable file
·383 lines (351 loc) · 17.5 KB
/
DataColumn.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
<?php
/**
* @package yii2-grid
* @author Kartik Visweswaran <kartikv2@gmail.com>
* @copyright Copyright © Kartik Visweswaran, Krajee.com, 2014 - 2017
* @version 3.1.7
*/
namespace kartik\grid;
use Closure;
use yii\grid\DataColumn as YiiDataColumn;
use kartik\base\Config;
use yii\helpers\Html;
/**
* The DataColumn is the default column type for the [[GridView]] widget and extends the [[YiiDataColumn]] with various
* enhancements.
*
* @author Kartik Visweswaran <kartikv2@gmail.com>
* @since 1.0
*/
class DataColumn extends YiiDataColumn
{
use ColumnTrait;
/**
* @var boolean whether the column is hidden from display. This is different than the `visible` property, in the
* sense, that the column is rendered, but hidden from display. This will allow you to still export the column
* using the export function.
*/
public $hidden;
/**
* @var boolean|array whether the column is hidden in export output. If set to boolean `true`, it will hide the
* column for all export formats. If set as an array, it will accept the list of GridView export `formats` and
* hide output only for them.
*/
public $hiddenFromExport = false;
/**
* @var string the horizontal alignment of each column. Should be one of [[GridView::ALIGN_LEFT]],
* [[GridView::ALIGN_RIGHT]], or [[GridView::ALIGN_CENTER]].
*/
public $hAlign;
/**
* @var string the vertical alignment of each column. Should be one of [[GridView::ALIGN_TOP]],
* [[GridView::ALIGN_BOTTOM]], or [[GridView::ALIGN_MIDDLE]].
*/
public $vAlign;
/**
* @var boolean whether to force no wrapping on all table cells in the column
* @see http://www.w3schools.com/cssref/pr_text_white-space.asp
*/
public $noWrap = false;
/**
* @var string the width of each column (matches the CSS width property).
* @see http://www.w3schools.com/cssref/pr_dim_width.asp
*/
public $width;
/**
* @var string the filter input type for each filter input. You can use one of the `GridView::FILTER_` constants or
* pass any widget classname (extending the Yii Input Widget).
*/
public $filterType;
/**
* @var array the options/settings for the filter widget. Will be used only if you set `filterType` to a widget
* classname that exists.
*/
public $filterWidgetOptions = [];
/**
* @var boolean|string|Closure the page summary that is displayed above the footer. You can set it to one of the
* following:
* - `false`: the summary will not be displayed.
* - `true`: the page summary for the column will be calculated and displayed using the
* [[pageSummaryFunc]] setting.
* - `string`: will be displayed as is.
* - `Closure`: you can set it to an anonymous function with the following signature:
*
* ```php
* // example 1
* function ($summary, $data, $widget) { return 'Count is ' . $summary; }
* // example 2
* function ($summary, $data, $widget) { return 'Range ' . min($data) . ' to ' . max($data); }
* ```
*
* where:
*
* - the `$summary` variable will be replaced with the calculated summary using the [[pageSummaryFunc]] setting.
* - the `$data` variable will contain array of the selected page rows for the column.
*/
public $pageSummary = false;
/**
* @var string|Closure the summary function that will be used to calculate the page summary for the column. If
* setting as `Closure`, you can set it to an anonymous function with the following signature:
*
* ```php
* function ($data)
* ```
*
* - the `$data` variable will contain array of the selected page rows for the column.
*/
public $pageSummaryFunc = GridView::F_SUM;
/**
* @var array HTML attributes for the page summary cell. The following special attributes are available:
* - `prepend`: _string_, a prefix string that will be prepended before the pageSummary content
* - `append`: _string_, a suffix string that will be appended after the pageSummary content
*/
public $pageSummaryOptions = [];
/**
* @var boolean whether to just hide the page summary display but still calculate the summary based on
* [[pageSummary]] settings
*/
public $hidePageSummary = false;
/**
* @var boolean whether to merge the header title row and the filter row. This will not render the filter for the
* column and can be used when `filter` is set to `false`. Defaults to `false`. This is only applicable when
* [[GridView::filterPosition]] for the grid is set to [[GridView::FILTER_POS_BODY]].
*/
public $mergeHeader = false;
/**
* @var boolean whether to group grid data by this column. Defaults to `false`. Note that your query must sort the
* data by this column for it to be effective.
*/
public $group = false;
/**
* @var boolean|Closure, whether to add a separate group row for grouping. This is applicable only when `group`
* property is `true`. Defaults to `false`. If set to `true`, the column will be hidden and its value will be
* displayed in a separate row above. The default behavior is to show the grouped content in a separate column
* (when this property is `false`). If setup as a Closure, the signature of the function should be: `function
* ($model, $key, $index, $column)`, where `$model`, `$key`, and `$index` refer to the model, key and index of
* the row currently being rendered, and `$column` is a reference to the [[DataColumn]] object.
*/
public $groupedRow = false;
/**
* @var string|Closure, the odd group css class. Defaults to 'kv-group-odd'. If setup as a Closure, the signature
* of the function should be: `function ($model, $key, $index, $column)`, where `$model`, `$key`, and `$index`
* refer to the model, key and index of the row currently being rendered, and `$column` is a reference to the
* [[DataColumn]] object.
*/
public $groupOddCssClass = 'kv-group-odd';
/**
* @var string|Closure, the even group css class. Defaults to 'kv-group-even'. If setup as a Closure, the signature
* of the function should be: `function ($model, $key, $index, $column)`, where `$model`, `$key`, and `$index`
* refer to the model, key and index of the row currently being rendered, and `$column` is a reference to the
* [[DataColumn]] object.
*/
public $groupEvenCssClass = 'kv-group-even';
/**
* @var integer|Closure the column index of which this group is a sub group of. This is validated only if `group`
* is set to `true`. If setup as a Closure, the signature of the function should be: `function ($model, $key,
* $index, $column)`, where `$model`, `$key`, and `$index` refer to the model, key and index of the row
* currently being rendered, and `$column` is a reference to the [[DataColumn]] object.
*/
public $subGroupOf;
/**
* @var array|Closure configuration of the group header which will be displayed as a separate row above the group.
* If this is empty, no group header will be rendered. If setup as a Closure, the signature of the function
* should be: `function ($model, $key, $index, $column)`, where `$model`, `$key`, and `$index` refer to the
* model, key and index of the row currently being rendered, and `$column` is a reference to the [[DataColumn]]
* object. The following array keys are recognized:
*
* - `mergeColumns`: `array`, of columns that will be merged as `from, to` pairs. For example if you need to merge
* column numbers 0 to 2 and column numbers 3 to 6, you can set this as:
* ```php
* [
* [0, 2], [3, 6]
* ]
* ```
* - `content`: `array`, header content for each column. You must set this as `$key => $value`, where `$key` is the
* zero based index for the column, and `$value` is the content to display for the column. The `$value` can take in
* special function names to summarize values for the column. If set to one of [[GridView::F_COUNT]],
* [[GridView::F_SUM]], [[GridView::F_AVG]], [[GridView::F_MAX]], [[GridView::F_MIN]], the values will be auto summarized.
* - `contentFormats`: `array`, header content formats for each column. This is only applicable currently only for
* number type or a custom type using a javascript callback. You must set this as `$key => $value`, where
* `$key` is the 0 based index for the column, and `$value` is the format settings for the column. The
* `$value` is a format specification setup as an array containing one or more of the following options:
* - `format`: string, whether `number` or `callback`
* - `decimals`: number, number of decimals (for number format only)
* - `decPoint`: string, decimals point character (for number format only). Defaults to `.`.
* - `thousandSep`: string, thousands separator character (for number format only). Defaults to `,`.
* - `func`: string, the javascript callback function name (for callback format only). This should be set to a
* globally accessible javascript function name. For example if you set this to `customCallback`, the function
* should be of the signature: `function customCallback(source, data) { return custom_convert(source, data);}`.
* The parameters for the callback function that will be passed are:
* - `source`: string, the summary column source as set in `content` section if available
* - `data`: `array`, the text values of each of the child columns in this group.
* An example of setting the `content`:
* ```php
* [
* 7 => ['format'=>'callback', 'func'=>'customCallback']
* 8 => ['format'=>'number', 'decimals'=>2, 'decPoint'=>'.', 'thousandSep'=>',']
* ]
* ```
* - `contentOptions`: `array`, header HTML attributes for each column. You must set this as `$key => $value`, where
* `$key` is the 0 based index for the column, and `$value` is the HTML attributes to apply for the column. The
* `$value` must be an array of HTML attributes for the table column. An example of setting the `contentOptions`:
* ```php
* [
* 0 => ['style'=>'font-weight:bold'],
* 8 => ['style'=>'text-align:right']
* ]
* ```
* - `options`: `array`, HTML attributes for the group header row.
*/
public $groupHeader = [];
/**
* @var array|Closure configuration of the group footer which will be displayed as a separate row. If this is
* empty, no group footer will be rendered. If setup as a Closure, the signature of the function should be:
* `function ($model, $key, $index, $column)`, where `$model`, `$key`, and `$index` refer to the model, key and
* index of the row currently being rendered, and `$column` is a reference to the [[DataColumn]] object.
* `$column` is a reference to the [[DataColumn]] object. The following array keys are recognized:
* - `mergeColumns`: `array`, of columns that will be merged as `from, to` pairs. For example if you need to merge
* column numbers 0 to 2 and column numbers 3 to 6, you can set this as:
* ```php
* [
* [0, 2], [3, 6]
* ]
* ```
* - `content`: `array`, footer content for each column. You must set this as `$key => $value`, where `$key` is the 0
* based index for the column, and `$value` is the content to display for the column. The `$value` can take in
* special function names to summarize values for the column. If set to one of `GridView::F_COUNT`,
* `GridView::F_SUM`, `GridView::F_AVG`, `GridView::F_MAX`, `GridView::F_MIN`, the values will be auto
* summarized. For example:
* ```php
* [
* 0 => 'Total',
* 8 => GridView::F_SUM
* ]
* ```
* - `contentFormats`: `array`, footer content formats for each column. This is only applicable currently only for
* number type or a custom type using a javascript callback. You must set this as `$key => $value`, where
* `$key` is the 0 based index for the column, and `$value` is the format settings for the column. The
* `$value` is a format specification setup as an array containing one or more of the following options:
* - `format`: string, whether `number` or `callback`
* - `decimals`: number, number of decimals (for number format only)
* - `decPoint`: string, decimals point character (for number format only). Defaults to `.`.
* - `thousandSep`: string, thousands separator character (for number format only). Defaults to `,`.
* - `func`: string, the javascript callback function name (for callback format only). This should be set to a
* globally accessible javascript function name. For example if you set this to `customCallback`, the function
* should be of the signature: `function customCallback(source, data) { return custom_convert(source, data); }`.
* The parameters for the callback function that will be passed are:
* - `source`: string, the summary column source as set in `content` section if available
* - `data`: `array`, the text values of each of the child columns in this group.
* An example of setting the `content`:
* ```php
* [
* 7 => ['format'=>'callback', 'func'=>'customCallback']
* 8 => ['format'=>'number', 'decimals'=>2, 'decPoint'=>'.', 'thousandSep'=>',']
* ]
* ```
* - `contentOptions`: `array`, footer HTML attributes for each column. You must set this as `$key => $value`, where
* `$key` is the 0 based index for the column, and `$value` is the HTML attributes to apply for the column. The
* `$value` must be an array of HTML attributes for the table column. An example of setting the `contentOptions`:
* ```php
* [
* 0 => ['style'=>'font-weight:bold'],
* 8 => ['style'=>'text-align:right']
* ]
* ```
* - `options`: `array`, HTML attributes for the group footer row.
*/
public $groupFooter = [];
/**
* @var string the cell format for EXCEL exported content.
* @see http://cosicimiento.blogspot.in/2008/11/styling-excel-cells-with-mso-number.html
*/
public $xlFormat;
/**
* @var array collection of row data for the column for the current page
*/
protected $_rows = [];
/**
* @var \yii\web\View the view instance
*/
protected $_view;
/**
* @var string the internally generated client script to initialize
*/
protected $_clientScript = '';
/**
* @var string the internally generated column key
*/
protected $_columnKey = '';
/**
* @inheritdoc
*/
public function init()
{
$this->_view = $this->grid->getView();
if ($this->mergeHeader && !isset($this->vAlign)) {
$this->vAlign = GridView::ALIGN_MIDDLE;
}
if ($this->grid->bootstrap === false) {
Html::removeCssClass($this->filterInputOptions, 'form-control');
}
$this->parseFormat();
$this->parseVisibility();
$this->checkValidFilters();
parent::init();
$this->setPageRows();
$this->initGrouping();
}
/**
* @inheritdoc
*/
public function renderDataCell($model, $key, $index)
{
$options = $this->fetchContentOptions($model, $key, $index);
$this->parseGrouping($options, $model, $key, $index);
$this->parseExcelFormats($options, $model, $key, $index);
$this->initPjax($this->_clientScript);
return Html::tag('td', $this->renderDataCellContent($model, $key, $index), $options);
}
/**
* Renders filter inputs based on the `filterType`
*
* @return string
*/
protected function renderFilterCellContent()
{
$content = parent::renderFilterCellContent();
$chkType = !empty($this->filterType) && $this->filterType !== GridView::FILTER_CHECKBOX &&
$this->filterType !== GridView::FILTER_RADIO && !class_exists($this->filterType);
if ($this->filter === false || empty($this->filterType) || $content === $this->grid->emptyCell || $chkType) {
return $content;
}
$widgetClass = $this->filterType;
$options = [
'model' => $this->grid->filterModel,
'attribute' => $this->attribute,
'options' => $this->filterInputOptions,
];
if (is_array($this->filter)) {
if (Config::isInputWidget($this->filterType) && $this->grid->pjax) {
$options['pjaxContainerId'] = $this->grid->pjaxSettings['options']['id'];
}
if ($this->filterType === GridView::FILTER_SELECT2 || $this->filterType === GridView::FILTER_TYPEAHEAD) {
$options['data'] = $this->filter;
}
if ($this->filterType === GridView::FILTER_RADIO) {
return Html::activeRadioList(
$this->grid->filterModel,
$this->attribute,
$this->filter,
$this->filterInputOptions
);
}
}
if ($this->filterType === GridView::FILTER_CHECKBOX) {
return Html::activeCheckbox($this->grid->filterModel, $this->attribute, $this->filterInputOptions);
}
$options = array_replace_recursive($this->filterWidgetOptions, $options);
/** @var \kartik\base\Widget $widgetClass */
return $widgetClass::widget($options);
}
}