listing checkmarked items
Attached a screen shot of the editor where you assign locations from one editor to pdfs from a 3rd.
Need to list out all locations with appropriate PDF. Currently, there would be no way to stop multiple PDFs being assigned to a location. I'm fine with that. An admin can look at the list on the display page and quickly see there should only be one.
Could you just add a pick list to the locations editor? The pick list could be multiple or single only. Then just have a list view of the locations section?
Yes, I could. I forgot to mention that the PDF's will change often though. That would mean I had to go into every location (which will increase) when they changed. Currently, there are only 2 PDF's. I'm trying to make only 2 edits. At some point, 20 locations and 3 PDFs. Having to go into each location works but not the most efficient for the client. I will do this in a pinch to launch though, I appreciate the suggestion.
Although there is one PDF per location, I was also building scheduling where 1 PDF could expire and another would display. You can see in my screenshot that would be easy to add into what I'm trying to do.
I'm always getting confused when I get into these arrays, tab separations, explode, etc. I have it down for categories, listing out items that are checked for one category passed in the URL. Works great.
Hopefully, someone may be listing checkboxes / selections like this and show some code. I'll get back to attempts and post them but it will be pretty bad. I didn't save them.
I think that Tim's suggestion is probably the simplest way to achieve this sort of list, but as you've said, this may not be the most efficient for you to work with. However, the drawback is that the more efficient method is considerably more complex to represent on the front-end.
The following has not been fully tested and makes a few assumptions about how you've set up your lists and field names, but I believe should at least be close to what you're looking for:
<?php // load records from 'assign' list($assignRecords, $assignMetaData) = getRecords(array( 'tableName' => 'assign', 'loadUploads' => true, 'allowSearch' => false, )); // load records from 'pdf_menus' list($pdf_menusRecords, $pdf_menusMetaData) = getRecords(array( 'tableName' => 'pdf_menus', 'loadUploads' => true, 'allowSearch' => false, )); // load records from 'locations' list($locationsRecords, $locationsMetaData) = getRecords(array( 'tableName' => 'locations', 'loadUploads' => true, 'allowSearch' => false, )); // group PDFs by num $pdfsByNum = array_groupBy($pdf_menusRecords, 'num'); ?> <?php foreach ($locationsRecords as $locationRecord): ?> <p> <strong><?php echo $locationRecord['title']; ?>:</strong> <?php foreach ($assignRecords as $assignRecord): ?> <?php // unpack multi-select values for easier searching $assignedLocations = listValues_unpack($assignRecord['locations']); ?> <?php if (array_search($locationRecord['num'], $assignedLocations) !== false): ?> <?php if (isset( $pdfsByNum[ $assignRecord['pdf_menu'] ] )): ?> <a href="<?php echo $pdfsByNum[ $assignRecord['pdf_menu'] ]['pdf']['urlPath']; ?>">PDF Download</a> <?php endif; ?> <?php endif; ?> <?php endforeach; ?> </p> <?php endforeach; ?>
The main things to note are:
- We start by looping through the locations
- We group the PDF records by their num to make it easy to find a PDF if we know its num
- Checking if a record is selected in a multi-select is more complicated (using listValues_unpack() and array_search())
I hope that's helpful; let me know if you have any questions about how this works!
Wow, ok. Thanks for this, it makes a perfect list. There are functions I didn't know existed or understand yet.
However, the upload links are currently coming out as "undefined index: urlPath"
They are uploads in the pdf multi, usually displayed with the standard code:
<?php foreach ($pdf_menusRecords as $record): ?> <?php echo htmlencode($record['title']) ?>: <?php foreach ($record['pdf'] as $index => $upload): ?> <a href="<?php echo htmlencode($upload['urlPath']) ?>" target="_blank">View PDF</a><br/> <?php endforeach; ?> <?php endforeach; ?>
Also, doesn't the code have to loop through possible checkmarks, which could even be more than one PDF per location by mistake? I'll be able to view the page and see that more than one is assigned by mistake but I'm lost adjusting your code.
Probably those assumptions you mentioned?
I will have questions about the functions but I guess i better wait on that or I'll confuse things more.
It looks like what's missing is the middle foreach in the snippet you just listed. Instead of "$record['pdf']" you would use "$pdfsByNum[ $assignRecord['pdf_menu'] ]['pdf']", so I think the modification would look something like this:
... <?php if (isset( $pdfsByNum[ $assignRecord['pdf_menu'] ] )): ?> <?php foreach ($pdfsByNum[ $assignRecord['pdf_menu'] ]['pdf'] as $index => $upload): ?> <a href="<?php echo htmlencode($upload['urlPath']) ?>" target="_blank">View PDF</a> <?php endforeach; ?> <?php endif; ?> ...
We are able to skip looping through possible checkmarks by using listValues_unpack(), which takes the values from a multi-select field (e.g. $assignRecord['locations']) and returns an array of all of the selected values. In this case, it should all be the location record nums. Then we use array_search() to effectively check "if the num for this location is in the array."
Let me know if you have any more questions. In the future, we'd love to create some documentation to make these additional functions more accessible to the average user!
Yes! I was assuming that's what was happening but couldn't get that loop working. I don't quite understand the nested looking array stuff. I was sure you created those functions for this type of thing and I didn't know about them. I searched and found them in the change log.
Well, that was my next question. Documentation. Ok, is there anything I can run or test on functions that are in change logs or that I see in the forum that would sort of list out what they might do?
If not, are there any snippets you can you show me here that might help me experiment with this setup to see more? If not, no worries, I will experiment and just ask specific questions later. I can sort of see whats happening, it's almost "readable" logic but not until I see it already done. I'm pretty sure I will end up understanding it more than %\t tab lists, explode and all of that. Embarrassingly, I get lost every time but have a collection that has worked in repeat situation with minor tweaks.
Working great and really cool, thanks.
Oh, or maybe I need to just to display the contents of the variables you are setting to see more. Something like that?
Confused: So if the unpack already figured out the checkboxes, what does the "isset" do here?
A lot of these internal functions will have some short documentation or usage instructions right in the code if you're able to find where they are defined. array_groupBy() is in cmsb/lib/common.php on line 1204, and listValues_unpack() is in cmsb/lib/schema_functions.php on line 501. array_search() is a native PHP function and the documentation can be found here: http://php.net/manual/en/function.array-search.php
Also, a general tip that I find very helpful for testing is that you can use showme() on arrays, and var_dump() on any variable, to get a better representation of what's in them, like this:
showme( $foo ); // this is a helper function in CMSB; prints array contents var_dump( $bar ); // this is a native PHP function; displays details of any variable (http://php.net/manual/en/function.var-dump.php)
When I'm trying out new code or functions, I find it helpful to use these functions to see a visual representation of my data at various points, such as before and after I use a function on it.
Hopefully, this gives you a good starting place!