Виджеты для данных
============
Yii предоставляет набор [виджетов](structure-widgets.md), которые могут быть использованы для отображения данных.
В то время как виджет [DetailView](#detail-view) может быть использован для отображения данных по одной записи, то
виджеты [ListView](#list-view) и [GridView](#grid-view) могут быть использованы для показа данных в виде списка или
таблицы с возможностью сортировки, фильтрации и разбивки данных постранично.
DetailView 
----------
Виджет [[yii\widgets\DetailView|DetailView]] отображает детали по данным для одной [[yii\widgets\DetailView::$model|model]].
Этот виджет лучше использовать для отображения данных модели в обычном формате(т.е. каждый атрибут модели будет представлен
в виде строки в таблице). Модель может быть либо объектом класса [[\yii\base\Model]] или его наследником, таких как
[active record](db-active-record.md) , либо ассоциативным массивом.
DetailView использует свойство [[yii\widgets\DetailView::$attributes|$attributes]] для определений, какие атрибуты модели
должны быть показаны и в каком формате. Обратитесь к разделу [Форматирование данных](output-formatting.md) за возможными
настройками форматирования.
Обычное использование DetailView сводится к следующему коду:
```php
echo DetailView::widget([
    'model' => $model,
    'attributes' => [
        'title',                                           // title свойство (обычный текст)
        'description:html',                                // description свойство, как HTML
        [                                                  // name свойство зависимой модели owner
            'label' => 'Owner',
            'value' => $model->owner->name,            
            'contentOptions' => ['class' => 'bg-red'],     // настройка HTML атрибутов для тега, соответсвующего value
            'captionOptions' => ['tooltip' => 'Tooltip'],  // настройка HTML атрибутов для тега, соответсвующего label
        ],
        'created_at:datetime',                             // дата создания в формате datetime
    ],
]);
```
ListView 
--------
Виджет [[yii\widgets\ListView|ListView]] использует для отображения информации [провайдера данных](output-data-providers.md).
Каждая модель отображается, используя определённый [[yii\widgets\ListView::$itemView|вид]]. Поскольку провайдер включает
в себя разбивку на страницы, сортировку и фильтрацию, то его использование удобно для отображения информации конечному
пользователю и создания интерфейса управления данными.
Обычное использование сводится к следующему коду:
```php
use yii\widgets\ListView;
use yii\data\ActiveDataProvider;
$dataProvider = new ActiveDataProvider([
    'query' => Post::find(),
    'pagination' => [
        'pageSize' => 20,
    ],
]);
echo ListView::widget([
    'dataProvider' => $dataProvider,
    'itemView' => '_post',
]);
```
`_post` файл вид, который может содержать следующее:
```php
    
= Html::encode($model->title) ?>
    = HtmlPurifier::process($model->text) ?>
```
В вышеописанном коде текущая модель доступна как `$model`. Кроме этого доступны дополнительные переменные:
- `$key`: mixed, значение ключа в соответствии с данными.
- `$index`: integer, индекс элемента данных в массиве элементов, возвращенных поставщику данных, который начинается с 0.
- `$widget`: ListView, это экземпляр виджета.
Если необходимо послать дополнительные данные в каждый вид, то можно использовать свойство [[yii\widgets\ListView::$viewParams|$viewParams]]
как ключ-значение, например:
```php
echo ListView::widget([
    'dataProvider' => $dataProvider,
    'itemView' => '_post',
    'viewParams' => [
        'fullView' => true,
        'context' => 'main-page',
        // ...
    ],
]);
```
Они также станут доступны в виде в качестве переменных.
GridView 
--------
Таблица данных или GridView - это один из сверхмощных Yii виджетов. Он может быть полезен, если необходимо быстро создать
административный раздел системы. GridView использует данные, как [провайдер данных](output-data-providers.md) и отображает
каждую строку используя [[yii\grid\GridView::columns|columns]] для предоставления данных в таблице.
Каждая строка из таблицы представлена данными из одиночной записи и колонка, как правило, представляет собой атрибут
записи (некоторые столбцы могут соответствовать сложным выражениям атрибутов или статическому тексту).
Минимальный код, который необходим для использования GridView:
```php
use yii\grid\GridView;
use yii\data\ActiveDataProvider;
$dataProvider = new ActiveDataProvider([
    'query' => Post::find(),
    'pagination' => [
        'pageSize' => 20,
    ],
]);
echo GridView::widget([
    'dataProvider' => $dataProvider,
]);
```
В вышеприведённом коде сначала создаётся провайдер данных и затем используется GridView для отображения атрибутов для
каждого элемента из провайдера данных. Отображенная таблица оснащена функционалом сортировки и разбивки на страницы из
коробки.
### Колонки таблицы
Колонки таблицы настраиваются с помощью определённых [[yii\grid\Column]] классов, которые настраиваются в свойстве
[[yii\grid\GridView::columns|columns]] виджета GridView. В зависимости от типа колонки и их настроек, данные отображаются
по разному. По умолчанию это класс [[yii\grid\DataColumn]], который представляет атрибут модели с возможностью сортировки
и фильтрации по нему.
```php
echo GridView::widget([
    'dataProvider' => $dataProvider,
    'columns' => [
        ['class' => 'yii\grid\SerialColumn'],
        // Обычные поля определенные данными содержащимися в $dataProvider.
        // Будут использованы данные из полей модели.
        'id',
        'username',
        // Более сложный пример.
        [
            'class' => 'yii\grid\DataColumn', // может быть опущено, поскольку является значением по умолчанию
            'value' => function ($data) {
                return $data->name; // $data['name'] для массивов, например, при использовании SqlDataProvider.
            },
        ],
    ],
]);
```
Учтите, что если [[yii\grid\GridView::columns|columns]] не сконфигурирована, то Yii попытается отобразить все возможные
колонки из провайдера данных.
### Классы колонок
Колонки таблицы могут быть настроены, используя различные классы колонок:
```php
echo GridView::widget([
    'dataProvider' => $dataProvider,
    'columns' => [
        [
            'class' => 'yii\grid\SerialColumn', // <-- тут
            // тут можно настроить дополнительные свойства
        ],
```
В дополнение к классам колонок от Yii, вы можете самостоятельно создать свой собственный класс.
Каждый класс колонки наследуется от [[yii\grid\Column]], так что есть некоторые общие параметры, которые можно установить
при настройке колонок.
- [[yii\grid\Column::header|header]] позволяет установить содержание для строки заголовка.
- [[yii\grid\Column::footer|footer]] позволяет установить содержание для "подвала".
- [[yii\grid\Column::visible|visible]] определяет, должен ли столбец быть видимым.
- [[yii\grid\Column::content|content]] позволяет передавать действительный обратный вызов, который будет возвращать данные для строки.Формат следующий:
  ```php
  function ($model, $key, $index, $column) {
      return 'a string';
  }
  ```
Вы можете задать различные параметры контейнера HTML через массивы:
- [[yii\grid\Column::headerOptions|headerOptions]]
- [[yii\grid\Column::footerOptions|footerOptions]]
- [[yii\grid\Column::filterOptions|filterOptions]]
- [[yii\grid\Column::contentOptions|contentOptions]]
#### DataColumn 
[[yii\grid\DataColumn|Data column]] используется для отображения и сортировки данных. По умолчанию этот тип
используется для всех колонок.
Основная настройка этой колонки - это свойство [[yii\grid\DataColumn::format|format]]. Значение этого свойства посылается
в методы `formatter` [компонента](structure-application-components.md), который по умолчанию [[\yii\i18n\Formatter|Formatter]]
```php
echo GridView::widget([
    'columns' => [
        [
            'attribute' => 'name',
            'format' => 'text'
        ],
        [
            'attribute' => 'birthday',
            'format' => ['date', 'php:Y-m-d']
        ],
        'created_at:datetime', // короткий вид записи формата
        [
            'label' => 'Education',
            'attribute' => 'education',
            'filter' => ['0' => 'Elementary', '1' => 'Secondary', '2' => 'Higher'],
            'filterInputOptions' => ['prompt' => 'All educations', 'class' => 'form-control', 'id' => null]
        ],
    ],
]);
```
В вышеприведённом коде  `text` соответствует [[\yii\i18n\Formatter::asText()]]. В качестве первого аргумента для этого
метода будет передаваться значение колонки. Во второй колонки описано  `date`, которая соответствует [[\yii\i18n\Formatter::asDate()]].
В качестве первого аргумента, опять же, будет передаваться значение колонки, в то время как второй аргумент будет
'php:Y-m-d'.
Доступный список форматов смотрите в разделе [Форматирование данных](output-formatting.md).
Для конфигурации колонок данных также доступен короткий вид записи, который описан в API документации для [[yii\grid\GridView::columns|колонок]].
Используйте [[yii\grid\DataColumn::filter|filter]] и [[yii\grid\DataColumn::filterInputOptions|filterInputOptions]] для
настройки HTML кода фильтра.
По умолчанию заголовки колонок генерируются используя [[yii\data\Sort::link]]. Это можно изменить через свойство
[[yii\grid\Column::header]]. Для изменения заголовка нужно задать [[yii\grid\DataColumn::$label]], как в
примере выше. По умолчанию текст будет взят из модели данных. Подробное описание ищите в [[yii\grid\DataColumn::getHeaderCellLabel]].
#### ActionColumn
[[yii\grid\ActionColumn|ActionColumn]] отображает кнопки действия, такие как изменение или удаление для каждой строки.
```php
echo GridView::widget([
    'dataProvider' => $dataProvider,
    'columns' => [
        [
            'class' => 'yii\grid\ActionColumn',
            // вы можете настроить дополнительные свойства здесь.
        ],
```
Доступные свойства для конфигурации:
- [[yii\grid\ActionColumn::controller|controller]] это идентификатор контроллера, который должен обрабатывать действия.
 Если не установлен, то будет использоваться текущий активный контроллер.
- [[yii\grid\ActionColumn::template|template]] определяет шаблон для каждой ячейки в колонке действия. Маркеры заключённые
 в фигурные скобки являются ID действием контроллера (также называются *именами кнопок* в контексте колонки действия).
 Они могут быть заменены, через свойство [[yii\grid\ActionColumn::$buttons|buttons]]. Например, маркер `{view}` будет
 заменён результатом из функции, определённой в `buttons['view']`. Если такая функция не может быть найдена, то маркер
 заменяется на пустую строку. По умолчанию шаблон имеет вид `{view} {update} {delete}`.
- [[yii\grid\ActionColumn::buttons|buttons]] массив из функций для отображения кнопок. Ключи массива представлены как
 имена кнопок (как описывалось выше), а значения представлены в качестве анонимных функций, которые выводят кнопки. Замыкания
 должны использоваться в следующем виде:
  ```php
  function ($url, $model, $key) {
      // возвращаем HTML код для кнопки
  }
  ```
  где, `$url` - это URL, который будет повешен как ссылка на кнопку, `$model` - это объект модели для текущей строки и
  `$key` - это ключ для модели из провайдера данных.
- [[yii\grid\ActionColumn::urlCreator|urlCreator]] замыкание, которое создаёт URL используя информацию из модели. Вид
 замыкания должен быть таким же как и в [[yii\grid\ActionColumn::createUrl()]]. Если свойство не задано, то URL для кнопки
 будет создана используя метод [[yii\grid\ActionColumn::createUrl()]].
- [[yii\grid\ActionColumn::visibleButtons|visibleButtons]] это массив условий видимости каждой из кнопок.
 Ключи массива представлены как имена кнопок (как описывалось выше), а значения представлены как булево значение или
 анонимная функция. Если имя кнопки не описано в массиве, она будет отображена по умолчанию.
 Замыкания должны использоваться в следующем виде:
 ```php
 function ($model, $key, $index) {
   return $model->status === 'editable'; // отображать ли кнопку
 }
 ```
 Или вы можете передать булево значение:
 ```php
 [
     'update' => \Yii::$app->user->can('update')
 ]
 ```
#### CheckboxColumn
[[yii\grid\CheckboxColumn|Checkbox column]] отображает колонку как флаг (сheckbox).
Для добавления CheckboxColumn в виджет GridView, необходимо добавить его в  [[yii\grid\GridView::$columns|columns]]:
```php
echo GridView::widget([
    'dataProvider' => $dataProvider,
    'columns' => [
        // ...
        [
            'class' => 'yii\grid\CheckboxColumn',
            // вы можете настроить дополнительные свойства здесь.
        ],
    ],
```
Пользователи могут нажимать на флаги для выделения строк в таблице. Отмеченные строки могут быть обработаны с помощью
JavaScript кода:
```javascript
var keys = $('#grid').yiiGridView('getSelectedRows');
// массив ключей для отмеченных строк
```
#### SerialColumn
[[yii\grid\SerialColumn|Serial column]] выводит в строках номера начиная с `1` и увеличивая их по мере вывода строк.
Использование очень простое :
```php
echo GridView::widget([
    'dataProvider' => $dataProvider,
    'columns' => [
        ['class' => 'yii\grid\SerialColumn'], // <-- тут
        // ...
```
### Сортировка данных
> Note: Эта секция под разработкой
>
> - https://github.com/yiisoft/yii2/issues/1576
### Фильтрация данных
Для фильтрации данных в GridView необходима [модель](structure-models.md), которая описывает форму для фильтрации, внося
условия в запрос поиска для провайдера данных.
Общепринятой практикой считается использование [active records](db-active-record.md) и создание для неё класса модели для
поиска, которая содержит необходимую функциональность(может быть сгенерирована через [Gii](start-gii.md)). Класс модели
для поиска должен описывать правила валидации и реализовать метод `search()`, который будет возвращать провайдер данных.
Для поиска возможных `Post` моделей, можно создать `PostSearch` наподобие следующего примера:
```php
 $query,
        ]);
        // загружаем данные формы поиска и производим валидацию
        if (!($this->load($params) && $this->validate())) {
            return $dataProvider;
        }
        // изменяем запрос добавляя в его фильтрацию
        $query->andFilterWhere(['id' => $this->id]);
        $query->andFilterWhere(['like', 'title', $this->title])
              ->andFilterWhere(['like', 'creation_date', $this->creation_date]);
        return $dataProvider;
    }
}
```
Теперь можно использовать этот метод в контроллере, чтобы получить провайдер данных для GridView:
```php
$searchModel = new PostSearch();
$dataProvider = $searchModel->search(Yii::$app->request->get());
return $this->render('myview', [
    'dataProvider' => $dataProvider,
    'searchModel' => $searchModel,
]);
```
и в виде присвоить их  `$dataProvider` и `$searchModel` в виджете GridView:
```php
echo GridView::widget([
    'dataProvider' => $dataProvider,
    'filterModel' => $searchModel,
    'columns' => [
        // ...
    ],
]);
```
### Отдельная форма фильтрации
Фильтров в шапке GridView достаточно для большинства задач, но добавление отдельной формы фильтрации не представляет
особой сложности. Она бывает полезна в случае необходимости фильтрации по полям, которые не отображаются в GridView
или особых условий фильтрации, например по диапазону дат.
Создайте частичное представление `_search.php` со следующим содержимым:
```php
     ['index'],
        'method' => 'get',
    ]); ?>
    = $form->field($model, 'title') ?>
    = $form->field($model, 'creation_date') ?>
    
        = Html::submitButton('Искать', ['class' => 'btn btn-primary']) ?>
        = Html::resetButton('Сбросить', ['class' => 'btn btn-default']) ?>
    
    
Users
';
echo GridView::widget([
    'dataProvider' => $userProvider,
]);
echo 'Posts
';
echo GridView::widget([
    'dataProvider' => $postProvider,
]);
```
### Использование GridView с Pjax
> Note: Секция находится в стадии разработки
TBD