Тема вроде как изжеванна вдоль и поперек, но так как просили больше статьей для новичков, расскажу об интересных особенностях виджета GridView, т.к без него у меня еще не обходился ни один проект. В дальнейшем буду пополнять данный FAQ.
Есть таблица с данными, допустим список пользователей, нужно некоторые из строк выделить другим цветом (например заблоченных юзеров выводить на сером фоне), т.к это куда нагляднее, чем просто надпись «вкл/выкл» в отдельном столбце. И реализуется проще простого: нужно добавить анонимную функцию в атрибут rowOptions
echo GridView::widget([ 'dataProvider' => $data, 'rowOptions' => function ($model, $key, $index, $grid) { if($model->is_active == false) { return ['style' => 'background-color:#778899;']; } }, ... ])
Т.к в функцию передается $index — текущий номер строки, можно четные строки раскрасить в один цвет, не четные в другой. Точно также можно передать любые параметры, которые попадут в нутрь тега tr. Если же вычислять ничего не нужно, то можно сразу указать массив параметров без анонимной функции
echo GridView::widget([ 'dataProvider' => $data, 'rowOptions' => ['style' => 'background-color:#778899;'], ... ])
Есть таблица с данными и к примеру нам нужно выводить дату записей с группировкой по месяцам. Январь — дальше строки таблицы за январь. Февраль и тп.Для этого существуют атрибуты beforeRow и afterRow.
Атрибуты beforeRow и afterRow работают по тому же принципу, что и rowOptions за тем исключением, что результат, полученный для этих функций будет выведен до и после тега tr.
$currentDate = date('m'); echo GridView::widget([ 'dataProvider' => $data, 'beforeRow' =>function ($model, $key, $index, $grid) use ($currentDate) { if($model->month != $currentDate) { return '<tr><td colspan=10>'.$model->month.'</td></tr>'; } } ... ])
Если вы используете ActiveDataProvider, то для решения достаточно понимать, что в query у вас экземпляр класса Query. Это такой не выполненный запрос. ActiveDataProvider добавит к нему limit и offset для постраничного вывода. Но вы может использовать этот запрос и сами, так как вам нужно. Например так:
$query = MyModel::find()->where(...); $data = new ActiveDataProvider([ 'query' => $query, ]); $totalSum = $query->sum('amount');
Если у вас используется один контроллер для множества гридов и вам нужно изменить только адрес ссылок для GridView, то сделать это можно передав анонимную функцию в качестве параметра urlCreator. Функция должна возвращать правильно сформированную ссылку:
['class' => 'yii\grid\ActionColumn', 'template' => '{update} {delete}', 'urlCreator'=>function($action, $model, $key, $index){ return \yii\helpers\Url::to(['dashboard/user-'.$action,'id'=>$model->id]); } ]
Как видно из примера — простой способ изменить порядок кнопок или удалить каку-нибудь из стандартных ({update} {delete} {view}) — это передать параметр template.
Спасибо большое, подстроки как раз мне нужны были). Ещё интересует на уровне новичков тема хранения например pdf файлов с возможностью для пользователей их скачки по временному рандомному пути, который они получат в сообщении.
Самое простое решение:
1) генерим ссылку с параметром, по которому можно понять о каком файле речь и даем ее пользователю как ссылка на скачку
2) по ссылке отдаем заголовки с рандомным именем файла и содержимое оригинального файла
Минусы: отсутствие докачки, нагрузка на сервер. Для отдачи статических файлов лучше всего поднять отдельный сервер nginx.
Ещё вспомнил. Как то меня попросили сделать данные в гриде покомпактнее, уменьшить высоту строк и сделать поменьше шрифт. Подскажите, пожалуйста, как лучше это сделать в стандартном гриде в yii2?
Нужно прописать свои CSS-классы или стили. Заставить grid использовать их можно через такие атрибуты как tableOptions, options, captionOptions и тп (см класс yii\grid\GridView)
Т.е будет примерно так:
Добрый день. А возможно ли в GridView сделать так, чтобы колонки были по одним данным, а фильтр по другим. Например табличка с данными по отзывам(отзыв, дата,положительный или отрицательный), а фильтр по пользователям этих отзывов(пол, возраст,…) ?
Или разместить 2 связанных GridView, но в одном убрать фильтр, а в другом как-то скрыть строки, через rowOptions?
Можно. Если фильтровать более чем по 1 полю, то лучше делать форму поиска и результаты выводить в виде GridView (как форму search генерит gii). Если фильтровать столбец по одному параметру, то делаем так
Т.е что происходит:
— метод Users::getYears() возвращает массив возрастов, он будет выпадающим списков сверху в фильтре.
— в search методе нужно обработать это значение. Оно придет как значение аттрибута date
Если массив значений для фильтра не нужен, то параметр filter не добавляем вообще, а просто в search методе обрабатываем значение как нам надо:
Надеюсь смогла объяснить.
Подскажите, пожалуйста, как сделать две таблички.Чтобы при нажатии на любую строчку из первой таблички, например, справа во второй табличке раскрывались подробные характеристики строчки из первой таблицы.
В первой таблице ссылка должна отправлять ajax запрос и отображать результат в том месте где 2-я таблица.
В контроллере нужно не забывать делать renderAjax вместо render. Надеюсь стало понятнее в какую сторону смотреть.
По предыдущему вопросу по двум зависимым табличкам.
А можно решить эту проблему с помощью partial view? Без ajax. Подскажите, пожалуйста
Смотрите как это работает: юзер кликнул на ссылку. Вместо того, чтобы перезагружать страницу, отправляем запрос на сервер (ajax) и в ответ получаем кусочек view (renderPartial или renderAjax) только той части, которая нужна для второй таблицы и с помощью JavaScript выводим полученные данные в нужном месте страницы (нужный яваскрипт уже есть в компоненте yii Pjax). Т.е без ajax запроса на сервер не получится.
Но можно сделать и по другому: загружать на страницу сразу всю информацию и скрывать лишнюю в скрытых css дивах. По клику на ссылку с помощью JavaScript нужный див показывается, а все остальные остаются скрытыми.