array_groupBy and show categories labels.
6 posts by 3 authors in: Forums > CMS Builder
Last Post: April 14, 2021 (RSS)
By Mikey - April 13, 2021
Hello folks,
I have a section editor for uploading documents. As I create a new document record, I can assign one or multiple categories to the document using a multi-select dropdown. I am trying to sort all my documents into groupings by the categories assigned to the documents.
The code below works, but I am unable to get the categories' label to display... this code only works with the numeric value of the categories. I've tried everything I can think of to get the categories' labels to appear.
<?php $documentsGroupedRecords = array_groupBy($documentsRecords, 'categories', true); ?>
<?php foreach ($documentsGroupedRecords as $cats => $records): ?>
<div class="small-12 medium-4 large-3 cell gray-panel media-panel">
<h3><?php echo $cats; ?></h3>
<?php foreach ($records as $record): ?>
<?php foreach ($record['document'] as $upload): ?>
<?php $recordTitle = ucwords(strtolower($record['title'])); ?>
<div>
<?php if($upload = (@$record['document'][0])){ // WORKS
echo '<h5><a href="download.php?num='.$record['num'].'" >'.$recordTitle.'</a></h5>'; } ?>
</div>
<?php endforeach; ?>
<?php endforeach; ?>
</div>
<?php endforeach ?>
I've tried the following with no luck.
<?php $documentsGroupedRecords = array_groupBy($documentsRecords, 'categories:labels', true); ?>
<?php $documentsGroupedRecords = array_groupBy($documentsRecords, 'categories:label', true); ?>
I also tried:
<h3><?php echo join(', ', $records['categories:labels']); ?></h3>
<h3><?php echo join(', ', $records['categories:label']); ?></h3>
<h3><?php echo join(', ', $records['categories']); ?></h3>
Nothing seems to work... maybe I've been looking at this too long.
Any suggestions on how I can get this working so that the categories' labels will appear between the Heading 3 html?
Thanks, Zicky
By Deborah - April 13, 2021
Hi, Zicky.
I've used the following code with success. It has the added benefit of not displaying a heading for categories that don't contain at least one record.
<?php $documentsByCategory = array_groupBy($documentsRecords, 'category', true); ?>
<?php foreach (getListOptions('documents', 'category') as $value => $label): ?>
<?php $documents = @$documentsByCategory[$value]; ?>
<?php if (!$documents) { continue; } // skip empty categories ?>
<h2><?php echo $label;?></h2>
<?php foreach ($documents as $document): ?>
<?php if ($document['document_pdf']): ?>
<?php foreach ($document['document_pdf'] as $index => $upload): ?>
<p><a href="<?php echo htmlencode($upload['urlPath']) ?><?php echo htmlencode($document['title']) ?></a></p>
<?php endforeach ?>
<?php endif ?>
<?php endif ?>
<?php endforeach ?>
<?php endforeach ?>
I'm hoping you'll be able to make something out of that. I believe I got assistance in the forum for this years ago, but can't locate the post.
Good luck!
Deborah
By Mikey - April 13, 2021
Hey Deborah,
No joy. I'm still unable to get it to work.
I copied and pasted your code, updated it to my field names but it wouldn't work. I think it has to do with the fact that my "categories" are a multi-value pillbox. I also tried quite a few various changes to the code you provided - but had no luck getting it to work.
Thanks for the suggestion.
By Deborah - April 13, 2021
Zicky, sorry that didn't help, but you're probably on the right track re: multi-value categories being the challenge. I've not had experience with that yet.
I'll bow out now and look forward to a solution from another forum member or Interactive Tools.
~ Deborah
By Steve99 - April 14, 2021
Hey Zicky,
This code should work for what you're looking to accomplish (with using a multi-value category field):
<?php
foreach (getListOptions('documents', 'categories') as $value => $label) {
echo '<h2>'.$label.'</h2>';
foreach ($documentsRecords as $document) {
if (($document['document']) && (in_array($value, explode("\t",$document['categories'])))) {
foreach ($document['document'] as $index => $upload) {
echo '<p><a href="'.htmlencode($upload['urlPath']).'">'.htmlencode($document['title']).'</a></p>';
}
}
}
}
?>
Let me know how you make out.
Best,
Steve
By Mikey - April 14, 2021 - edited: April 14, 2021
Thanks Deborah & Steve,
Between your two suggestions I came up with something that works... though I wouldn't say it's clean. Basically your suggestions worked, but the code was still showing categories - even if an available category was not assigned to a document. So I wrote a little comparison to find it there's a match and if YES, then show the category. I then wrapped it in some CSS masonry columns.
<div class="masonry">
<?php $documentsGroupedRecords = array_groupBy($documentsRecords, 'categories', true); ?>
<?php foreach ($documentsGroupedRecords as $cats => $records): ?>
<div class="brick">
<?php foreach (getListOptions('documents', 'categories') as $value => $label): ?>
<?php if ($value == $cats): ?>
<h2><?php echo $label; ?></h2>
<?php endif; ?>
<?php endforeach ?>
<?php foreach ($records as $record): ?>
<?php foreach ($record['document'] as $upload): ?>
<?php $recordTitle = ucwords(strtolower($record['title'])); ?>
<?php if($upload = (@$record['document'][0])){
echo '<h5><a href="download.php?num='.$record['num'].'" >'.$recordTitle.'</a></h5>'; } ?>
<?php endforeach; ?>
<?php endforeach; ?>
</div>
<?php endforeach ?>
</div>
Here's the CSS
/* @media screen based on Foundation 6 framework */
/* Small only */
@media screen and (max-width: 39.9375em) {
.masonry {
column-count: 1;
column-gap: 1em;
}
.brick {
display: inline-block;
padding: 0 0 1em;
width: 100%;
}
}
/* Medium only */
@media screen and (min-width: 40em) and (max-width: 63.9375em) {
.masonry {
column-count: 2;
column-gap: 1em;
}
.brick {
display: inline-block;
padding: 0 0 1em;
width: 100%;
}
}
/* Large and up */
@media screen and (min-width: 64em) {
.masonry {
column-count: 3;
column-gap: 1em;
}
.brick {
display: inline-block;
padding: 0 0 1em;
width: 100%;
}
}
Thanks,
Zicky