5.7.4.2 - Multiple image picker

Permalink
Hi

How can I get access for a dashboard block to a multiple image picker? My code from 5.6.x and lower does not work anymore....

 
MrKDilkington replied on at Permalink Reply
MrKDilkington
Hi Kiesel,

Can you include more details about what you are trying to do and where?
Kiesel replied on at Permalink Reply
Hi

I've created a dashboard module. It's used to store some data (names, adresses, etc...) and it also should store 1-n images per entry.

I simply need now an

"add images" button that brings me to the filemanager, lets me pick a few images and includes them in the dataset.

Basically all I need to know is how to access the filemanager so that it gives me the possibility to choose more than one image. If I use the standard picker and choose more images it returns a message (something along the lines of: "Please pick only one image")....
MrKDilkington replied on at Permalink Reply
MrKDilkington
There might be a way to do it in 5.7.4.x, but I am not familiar with how it is done.

In the release notes there was a feature update for this:
"You may now choose multiple files from the file manager if a block or editing interface supports it (thanks olsgreen!)"
https://www.concrete5.org/documentation/developers/5.7/background/ve...

Here is the pull request by olsgreen that added the feature.
https://github.com/concrete5/concrete5/pull/2055...

This feature looks very useful, so I will be looking into this too.
Kiesel replied on at Permalink Reply
Thanks for the links. I'll look into this all. I need it, that's for sure. Will post if I found a solution.
MrKDilkington replied on at Permalink Best Answer Reply
MrKDilkington
I think I have an idea of how to do select multiple images.

I believe it requires manually launching the ConcreteFileManager.

Here is an example:
- put a page in edit mode
- add a block
- while the block form is displayed, paste this code into the browser console
ConcreteFileManager.launchDialog(function(data) {
    ConcreteFileManager.getFileDetails(data.fID, function(r) {
        console.log(data.fID);
    });
}, { 'multipleSelection' : true });

- this will launch the ConcreteFileManager
- tick the checkbox for 2 or more images
- in the "Items Selected" drop down, select "Choose"
- in the console, you will see an array of the file ID's of the images selected

This array could be added to a hidden input field.

This isn't without problems though.
- ticked checkboxes do not persist between pages (e.g. - go to the second page of files and any images checked on the first page will be unchecked)
- there is no image preview in the block form of the selected images (multiple image previews will need to be added)

The core Image Slider block is a good example of manually launching the ConcreteFileManager and saving the output.
Kiesel replied on at Permalink Reply
It's for a custom dashboard module. There's a ton of form fields and one field should manage multiple images. The link you provided earlier does the trick.

I've used it like this (simplified):
<a href="javascript:;" onclick="addImages()">Add images</a>
<div id="container"></div>
<script>
function addImages(){
  ConcreteFileManager.launchDialog(function (data) {
    ConcreteFileManager.getFileDetails(data.fID, function(r) {
      r.files.forEach(function(e){
        var addImage = e.resultsThumbnailImg + '<br />'; 
        addImage  += 'File-Name: '+e.title+' ';      
        $('#container').append(addImage);
      });
    });
  }, { 'multipleSelection' : true });
}
</script>


Hope that helps someone else. I've just made a nice styling around it and some sorting and delete options. Gave hidden ids and when the form is saved the images can be saved with it.
MrKDilkington replied on at Permalink Reply
MrKDilkington
The author of the pull request (olsgreen) was very generous and sent me this code that explains how he handles multiple selections.

// Wire the trigger to show the file manager dialog
$('#addImageBtn').click(function () {
    // Launch the dialog
    ConcreteFileManager.launchDialog(function (data) {
        // Parse the callback data to get more file detail
        ConcreteFileManager.getFileDetails(data.fID, function(r) {
            // Loop over each file and do whatever you want with it
            for(var i = 0; i < r.files.length; i++) {
                // Do whatever with each file
                console.log(r.files[i]);
                /* Above will output
                {
                    canCopyFile: 1
                    canDeleteFile: 1
                    canEditFile: true

Did you look into how to handle checkbox value persistence when changing pages in the file manager?
Kiesel replied on at Permalink Reply
I ignore the missing check boxes when the page gets turned for now. In the worst case they can just use the picker again and add the rest of the images.

They work so far with proper file-sets. So there shouldn't be to much page turning.
Kiesel replied on at Permalink Reply
Okay, after I've spent quite a lot more time trying to figure things out I feel like what may help others in the same situation quite a lot is the following:

Instead of giving just the multipleSelection parameter, filters can be given to limit the initial files that are shown. Type 5 for example shows only documents in the file manager. The user can still change that and choose other files, so it may need other checks. But that needs a conscious effort of the user.
var options = {
  filters: [{ type: 5, submitSearch: 1, field: 'type' }], 
  'multipleSelection' : true 
};
Took me ages to find that one out.

Also with the data you get back you can do something like this to get it's type:
$fileobj = File::getByID($file['fID']); 
$filetypeobject = $fileobj->getTypeObject($fileobj);
if($filetypeobject->type == 1){
  //it's an image
}


And to get a thumbnail of images or the generic file type icon (eg. pdf icon):
$fileobj = File::getByID($file['fID']); 
$img =  $fileobj->getListingThumbnailImage($fileobj);
MrKDilkington replied on at Permalink Reply
MrKDilkington
Thanks for posting this, I can see it coming in handy.