#php #html #laravel #html-table
#php #HTML #laravel #html-таблица
Вопрос:
Я использую Laravel и пытаюсь заполнить HTML-таблицу из запроса. Таблица из базы данных содержит столбцы, среди прочих, id
, user
и shift
. Существует около 100 записей, и shift
столбец будет содержать букву A
, B
C
или D
. Я хочу вывести его в единую HTML-таблицу, чтобы при выполнении цикла первый столбец в выводимой таблице содержал только записи с A
для этого значения, второй B
и так далее.
Вот мой запрос:
Shift::orderBy('shift', 'ASC')
->get();
Это, конечно, сортирует его по алфавиту, а затем, когда я выполняю цикл, используя это:
...
<tbody>
@foreach ($shifts as $shift)
<tr>
<td>{{ $shift->id }}</td>
...
</tr>
@endforeach
</tbody>
...
Или аналогичные варианты, которых я перепробовал множество, он будет проходить через все записи с помощью A
и создавать эти ячейки / строки в таблице, а затем начинать с B
. Но к тому времени, поскольку они уже созданы, B
записи начинаются независимо от того, сколько A
записей там находится в исходном состоянии.
Я зациклился на нем и создал четыре отдельные таблицы, но я бы предпочел, чтобы это было в одной. Я хочу экспортировать таблицу с помощью Laravel Excel, и если это отдельные таблицы, они просто складываются, но я хочу, чтобы они были рядом. В любом случае, вот что я имею в виду и хочу (строки с буквами будут представлять собой другую информацию в итоговой таблице):
Чего я не понимаю? Я чувствую, что делаю что-то не очень простое. Спасибо за любую помощь.
Комментарии:
1. Вероятно, вам нужно пересмотреть способ хранения и извлечения ваших данных. Но если вы должны достичь этой цели, похоже, вам нужно разделить их на 4 массива, а затем снова объединить их вместе, причем каждое значение массива содержит вложенный массив с потенциальным значением для A-D.
2. Да, я подумал, что мне придется что-то с этим изменить. Я бы предпочел этого не делать, поскольку это нужно только для лучшего отображения при экспорте в электронную таблицу, а перебирать и создавать 4 таблицы намного проще. Но это уже другая тема.
Ответ №1:
Да, вы можете отсортировать их, используя usort
который существует для этой цели. usort()
будет отсортирован массив по значениям с использованием определяемой пользователем функции сравнения.
$arr = [
['letter'=>'C'],
['letter'=>'A'],
['letter'=>'B'],
['letter'=>'A'],
['letter'=>'D'],
];
// Function to sort by provided column name
function cmp($key){
// Returns comparision function to be used with usort
return function($a,$b)use($key){
return strcmp($a[$key], $b[$key]);
};
}
usort($arr, cmp('letter'));
print_r($arr);
Надеюсь, это поможет,
Ответ №2:
Я бы сказал, что наиболее эффективный способ добиться этого — выполнить сортировку на уровне базы данных. Для этого вам следует использовать orderBy()
метод. Также хорошим подходом было бы наличие области для этого.
public function scopeOrderByShiftsAsc($query)
{
return $query->orderBy('shifts', 'asc')->orderBy('created_at', 'desc');
}
// then in your controller
public function index()
{
$users = AppUser::orderByShiftsAsc()->get();
}
Вы можете использовать этот способ ( orderBy()
) либо в построителе запросов, либо в цепочке методов eloquent.
Области действия запроса.
Комментарии:
1. Если я просто сгруппирую по shift (буквы
A
черезD
), он возвращает только одну запись из каждой буквы. Если я продолжу группировать, результат просто будет таким же, как в моем исходном запросе; сначала все As, затем Bs, Cs, а затем Ds. Я делаю что-то не так?2. Попробуйте теперь упорядочить вместо группировки.
3. Примерно таким был мой исходный запрос (за вычетом области видимости), который, я думаю, я должен был опубликовать. Он просто упорядочивает его в алфавитном порядке, так что в нем примерно по ~ 20 букв одна за другой. И все они были импортированы из электронной таблицы, поэтому время создания одинаковое. Я бы подумал, что единственный способ добиться этого путем сортировки — это каким-то образом отсортировать его, сгруппировав фрагменты
A
,B
,C
иD
; например, взять первую запись из каждой буквы, а затем просто повторить это для каждого из них. Но я бы предположил, что это должно быть сделано за пределами уровня базы данных, с массивом.4. Извините, я в замешательстве. Вы смешиваете таблицу в HTML и таблицу в DB. Можете ли вы опубликовать структуру таблицы и жестко закодированный HTML-код или изображение нужного HTML-кода? Вам не нужно использовать реальные данные, но помогите нам лучше понять ваш запрос. Для этого следуйте этим советам.
5. Обновлено исходное сообщение. Извините за мою расплывчатость и путаницу.
Ответ №3:
Используя:
Shift::get()->keyBy('shift')->toArray();
Вы получаете структуру, подобную следующей:
$data = [
"A" = [
['id' => 1, 'shift' => 'A'],
...
],
"B" = [
['id' => 2, 'shift' => 'B'],
...
],
...
]
Далее вы можете выполнить итерацию по самой большой букве и создать желаемую структуру вывода:
$letters = array_keys($data)
$maxLength = 0
foreach($letters as $letter) {
$len = count($data[$letter]);
if ($len > $maxLength) $maxLength = $len;
}
$output = []
for($i = 0; $i < $maxLength: $i ) {
$newRow = [];
foreach($letters as $letter) {
if (isset($data[$letter][$i])) {
$newRow[$letter] = $data[$letter][$i]['id'];
} else {
$newRow[$letter] = '';
}
}
$output[] = $newRow;
}
Затем вы можете просто передать выходные данные в файл blade и создать таблицу в виде:
@foreach ($output as $row)
<tr>
<td>{{ $row['A'] }}</td>
<td>{{ $row['B'] }}</td>
...
</tr>
@endforeach
Комментарии:
1. Спасибо, но разве этот запрос не приводит к тому, что в этом массиве оказываются только четыре записи (по 1 из каждой буквы, поскольку это ключ)? Для каждой буквы есть ~ 25 строк, которые мне нужно было бы собрать, а затем выполнить цикл.
2. Нет, это должно получить все.