Электронный журнал в GridView

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
sky2high
Сообщения: 7
Зарегистрирован: 2016.03.06, 11:53

Электронный журнал в GridView

Сообщение sky2high »

Здравствуйте. Стоит задача отобразить студенческий журнал успеваемости в GridView.
Ситуация следующая:
Имеется выборка из БД вида:

Код: Выделить всё

Array
        (
            [0] => Array
                (
                    [name] => Петров
                    [date] => 17.04.2016
                    [score] => 5
                )

            [1] => Array
                (
                    [name] => Петров
                    [date] => 16.04.2016
                    [score] => 4
                )

            [2] => Array
                (
                    [name] => Сидоров
                    [date] => 17.04.2016
                    [score] => 3,4
                )

            [3] => Array
                (
                    [name] => Иванов
                    [date] => 15.04.2016
                    [score] => 5
                )

        )
Используя ArrayDataProvider, я передаю этот массив во view, где через виджет GridView пытаюсь вывести в следующем виде:
Изображение

Я понимаю, как динамически создать столбцы с датами, но не знаю как потом заполнить строки.

Код: Выделить всё

            
            foreach(ArrayHelper::index($results, 'date') as $date => $a) {
                $columns[] = [
                    'header' => $date,
                    'value' => function () {
                            ...
                        }
                    ]
                     
                ...
                    
                echo GridView::widget([
                'dataProvider' => $dataProvider,
                'columns' => $columns
            ]);
 

Весь вопрос в том, как заполнить строки, чтобы фамилии студентов не повторялись и ячейки с оценками заполнялись как в примере?
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Электронный журнал в GridView

Сообщение zelenin »

сначала массив сформируйте по принципу:

Код: Выделить всё

$data = [
$userId1 => [ date1 => 5, date2, 3, ...],
$userId2 => [ date1 => 5, date2, 3, ...]
]; 
а потом с этим уже работайте в гриде.
sky2high
Сообщения: 7
Зарегистрирован: 2016.03.06, 11:53

Re: Электронный журнал в GridView

Сообщение sky2high »

zelenin писал(а):сначала массив сформируйте по принципу:

Код: Выделить всё

$data = [
$userId1 => [ date1 => 5, date2, 3, ...],
$userId2 => [ date1 => 5, date2, 3, ...]
];
а потом с этим уже работайте в гриде.
Спасибо за ответ. Сформировал подобным образом. Как теперь выводить фамилии студентов в грид?
Пробовал так, но здесь мы перезапускам цикл и всё время получаем одного и того же студента:

Код: Выделить всё

            
            $columns = [
                ['class' => 'yii\grid\SerialColumn'],
                [
                    'attribute' => 'name',
                    'value' => function() use ($data) {
                        foreach ($data as $student => $result) {
                            return $student;
                        }
                    }
                ]
            ];

Код: Выделить всё

Array
(
    [Петров] => Array
        (
            [16.04.2016] => 4
        )

    [Сидоров] => Array
        (
            [17.04.2016] => 3,4
        )

    [Иванов] => Array
        (
            [15.04.2016] => 5
        )

)
 
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Электронный журнал в GridView

Сообщение zelenin »

так добавьте фамилию с массив к датам.
sky2high
Сообщения: 7
Зарегистрирован: 2016.03.06, 11:53

Re: Электронный журнал в GridView

Сообщение sky2high »

zelenin писал(а):так добавьте фамилию с массив к датам.
Сделал, проблема решилась. Мне удалось получить результат, почти как в моём примере.
Осталась одна проблема.
Обработать ситуацию, когда один студент получал оценки в разные даты. Нужны идеи...

Сейчас view выглядит так:
Изображение

Код: Выделить всё

            
foreach($data as $student => $dateAndScore) {
    $studentDate = array_keys($dateAndScore)[1];
    $studentName = $dateAndScore[array_keys($dateAndScore)[0]];

    $columns[] = [
        'header' => $studentDate,
        'value' => function($model) use ($dateAndScore, $studentName, $studentDate) {

            $modelDate = array_keys($model)[1];

            if ($model['name'] == $studentName && $modelDate == $studentDate) {
                $score = $dateAndScore[array_keys($dateAndScore)[1]];
                return $score;
            }

            return '-';
        }
    ];
}
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Электронный журнал в GridView

Сообщение ElisDN »

Код: Выделить всё

[Петров] => Array
    (
        [16.04.2016] => 4.
        [17.04.2016] => 5.
    )
sky2high
Сообщения: 7
Зарегистрирован: 2016.03.06, 11:53

Re: Электронный журнал в GridView

Сообщение sky2high »

ElisDN писал(а):

Код: Выделить всё

[Петров] => Array
    (
        [16.04.2016] => 4.
        [17.04.2016] => 5.
    ) 
Да, именно это у меня в массиве. Проблема с выводом в GridView.
sky2high
Сообщения: 7
Зарегистрирован: 2016.03.06, 11:53

Re: Электронный журнал в GridView

Сообщение sky2high »

Выходит, что я через foreach прохожу по массиву студентов. Как только дата студента совпадает с датой в названии столбца выводится оценка. А потом цикл перескакивает ко второму студенту. Хотя у первого студента осталась ещё невыведенная оценка за другую дату. Пока не могу придумать, как это решить
Prosto_Tok
Сообщения: 132
Зарегистрирован: 2015.09.30, 20:12

Re: Электронный журнал в GridView

Сообщение Prosto_Tok »

sky2high писал(а):Выходит, что я через foreach прохожу по массиву студентов. Как только дата студента совпадает с датой в названии столбца выводится оценка. А потом цикл перескакивает ко второму студенту. Хотя у первого студента осталась ещё невыведенная оценка за другую дату. Пока не могу придумать, как это решить
2 цикла нужно.
Первый идет по студентам, а второй по датам с оценками.
sky2high
Сообщения: 7
Зарегистрирован: 2016.03.06, 11:53

Re: Электронный журнал в GridView

Сообщение sky2high »

Prosto_Tok писал(а): 2 цикла нужно.
Первый идет по студентам, а второй по датам с оценками.
А как? Я не представляю, как это должно выглядеть в данном контексте. Если я образно напишу это так, то представьте сколько лишних столбиков появится:

Код: Выделить всё

foreach ($students as $student) {
    foreach ($dates as $date) {
        $columns[] = [
            'header' => $date,
            'value' => $function() { ... }
        ]
    }
}
sky2high
Сообщения: 7
Зарегистрирован: 2016.03.06, 11:53

Re: Электронный журнал в GridView

Сообщение sky2high »

Возникла идея в первом цикле писать в $columns[count($columns)] только header, а во вложенном определять value и мерджить с $columns[count($columns)]. Однако два одинаковых value будут заменять друг друга.
var_dump по стандартному columns выплёвывает слишком много нечитабельного кода. Кто-нибудь знает, как можно несколько value примерджить в массив с header?

Сейчас это выглядит примерно так:

Код: Выделить всё

foreach ($uniqueDates as $uniqueDate) {
    $index = count($columns);
    $columns[$index] = [
         'header' => $uniqueDate
    ];

    foreach ($data as $student) {
        $studentScore = [
            'value' => ...
        ];
        $columns[$index] = ArrayHelper::merge($columns[$index], $studentScore);
    }
}
 
oleg.smirnovsync
Сообщения: 4
Зарегистрирован: 2017.12.06, 09:05

Re: Электронный журнал в GridView

Сообщение oleg.smirnovsync »

Добрый день. Проблему решили?
Ответить