C5-8.0+: how to load and show image in form.php

Permalink
I know how to select an image in the add block form.php which will then be loaded in view.

But how can I show the selected image in the add block form before saving it?

Thank you.

linuxoid
 
brutalnv replied on at Permalink Reply
brutalnv
<span id="output"></span>
<label class="button expanded" for="file">Select image</label><input name="user_image[file]" class="show-for-sr" id="file" type="file">
<script>
        //<![CDATA[
        document.getElementById('file').addEventListener('change', handleFileSelect, false);
        function handleFileSelect(evt) {
            var file = evt.target.files;
            var f = file[0];
            if (!f.type.match('image.*')) {
                alert("Images only!");
                return false;
            } else {
                var reader = new FileReader();
                reader.onload = (function (theFile) {
                    return function (e) {


Regards, Nick.
linuxoid replied on at Permalink Reply
linuxoid
That doesn't work. I have a C5 file select widget. I need to show the picture after selecting that file with the image.

I have a file selector:
echo $al->image('picture', 'pictureID', t('Choose picture'), $pic);

I guess I just need to get the pictureID. I tried the following, but it doesn't work:
<script type="text/javascript" charset="UTF-8">
$(function(){
    $('#pictureID').on('change', function(e) {
        alert($('#pictureID').val());
    });
});
</script>
brutalnv replied on at Permalink Reply 1 Attachment
brutalnv
Got it.Try this snippet:

<?php $al = Core::make('helper/concrete/asset_library'); ?>
<?= $al->image('ccm-image', 'pfID', t('Choose Image'), $pfID ? File::getByID($pfID):null); ?>


Is it what you need?
linuxoid replied on at Permalink Reply
linuxoid
No. I already have the file selector widget. It selects the file just fine.

But what I need is to show that file right beneath the widget after the file is selected.
brutalnv replied on at Permalink Reply 1 Attachment
brutalnv
Something like that?:

<ul class="list-group multi-select-list multi-select-sortable" id="additional-image-list">
                            </ul>
                            <div href="#" id="launch_additional" data-launch="file-manager" class="ccm-file-selector"><div class="ccm-file-selector-choose-new"><?= t('Choose Images'); ?></div></div>
                            <script type="text/javascript">
                                $(function() {
                                    $('#launch_additional').on('click', function(e) {
                                        e.preventDefault();
                                        var options = {
                                            multipleSelection: true,
                                            filters : [{ field : 'type', type: '<?= \Concrete\Core\File\Type\Type::T_IMAGE; ?>'}]
                                        };
                                        ConcreteFileManager.launchDialog(function (data) {
                                            ConcreteFileManager.getFileDetails(data.fID, function(r) {
                                                for(var i in r.files) {
                                                    var file = r.files[i];
linuxoid replied on at Permalink Reply
linuxoid
Maybe, but I don't think that's what I'm after. I understand why that uses a ConcreteFileManager. But as it's already part of the file select widget, I just need to know what the selected picture ID is in order to add an image with that picture to my div.
linuxoid replied on at Permalink Reply
linuxoid
No, I don't even need the picture ID, I need its path in order to make an img tag to add to my div.
brutalnv replied on at Permalink Reply
brutalnv
Take a look at this function:

ConcreteFileManager.getFileDetails(data.fID, function(r) {
                                    for(var i in r.files) {
                                        var file = r.files[i];
                                        $('#additional-image-list').append('<li class="list-group-item">'+ file.resultsThumbnailImg +' ' +  file.title +'<a><i class="pull-right fa fa-minus-circle"></i></a><input type="hidden" name="pifID[]" value="' + file.fID + '" /></li>');
                                    }
                                });


It returns an JSON array filled with selected file data with following structure:

public function getJSONObject()
    {
        $r = new stdClass();
        $fp = new Permissions($this->getFile());
        $r->canCopyFile = $fp->canCopyFile();
        $r->canEditFileProperties = $fp->canEditFileProperties();
        $r->canEditFilePermissions = $fp->canEditFilePermissions();
        $r->canDeleteFile = $fp->canDeleteFile();
        $r->canReplaceFile = $fp->canEditFileContents();
        $r->canEditFileContents = $fp->canEditFileContents();
        $r->canViewFileInFileManager = $fp->canRead();
        $r->canRead = $fp->canRead();
        $r->canViewFile = $this->canView();
        $r->canEditFile = $this->canEdit();
        $r->url = $this->getURL();


So, you can get the file url from the file.url property
linuxoid replied on at Permalink Reply
linuxoid
That looks like reimplementation of the file manager. I've already got it on the form with $al->image(...). This creates an img tag with a path. I just need to get that value - that's all!

The file picker creates this code:
<div class="ccm-file-selector" data-file-selector="picture">
<div class="ccm-file-selector-file-selected">
<input name="pictureID" value="6" type="hidden">
<div class="ccm-file-selector-file-selected-thumbnail">
<img class="ccm-file-manager-list-thumbnail" src="http://localhost/c58/application/files/thumbnails/file_manager_listing/9015/2680/8260/test.jpg" data-at2x="http://localhost/c58/application/files/thumbnails/file_manager_listing_2x/9015/2680/8260/test.jpg"></div>
<div class="ccm-file-selector-file-selected-title">
<div>test.png</div>
</div>

But for some reason $('#pictureID').on('change', function(e) { is not triggered.
brutalnv replied on at Permalink Reply
brutalnv
This img tag contains a thumbnail path, not full image path.
If we take a look at the source code, we'll see that ConcreteFileManager does not return the full path to the image.

ConcreteFileSelector.prototype = {
        chooseTemplate: '<div class="ccm-file-selector-choose-new">' +
            '<input type="hidden" name="<%=options.inputName%>" value="0" /><%=options.chooseText%></div>',
        loadingTemplate: '<div class="ccm-file-selector-loading"><input type="hidden" name="<%=inputName%>" value="<%=fID%>"><img src="' + CCM_IMAGE_PATH + '/throbber_white_16.gif" /></div>',
        fileLoadedTemplate: '<div class="ccm-file-selector-file-selected"><input type="hidden" name="<%=inputName%>" value="<%=file.fID%>" />' +
            '<div class="ccm-file-selector-file-selected-thumbnail"><%=file.resultsThumbnailImg%></div>' +
            '<div class="ccm-file-selector-file-selected-title"><div><%=file.title%></div></div><div class="clearfix"></div>' +
            '</div>',


I'm 100% sure there is an option to override the template used by the CFM
linuxoid replied on at Permalink Reply
linuxoid
Ok. But it returns the pictureID: <input name="pictureID" value="6" type="hidden">

How do I get that ID? If I can get the ID, I can get the path.

The problem is the 'change' event is not triggered for that dynamically created input.

$(document).on('change', '#pictureID', function(e) { - doesn't work either.
linuxoid replied on at Permalink Reply
linuxoid
This doesn't work either:
$('#pictureID').on('change', function() {
        alert('ok');
    }).trigger('change');
linuxoid replied on at Permalink Reply
linuxoid
Just realized that the input doesn't have an id. So something like this should work:
$('input[name=pictureID]').on('change', function() {
        alert('ok');
    }).trigger('change');

although it does NOT. However, this code works on opening the form which shows a '0'. But selecting a file or clearing it doesn't trigger that.

If I add a button to the form, this works fine:
$('#search').on('click', function(){
        alert($('input[name=pictureID]').val());
    });

But I need that value only on selecting the file!
linuxoid replied on at Permalink Reply
linuxoid
Well, I got it partially working. This gets the selected file ID:
$(document).bind('change', 'input[name=pictureID]', function() {
        var fID = $('input[name=pictureID]').val();
        if (fID != 0) {
            alert(fID);
        }
    }).trigger('change');

Now the problem is the fID is a JS variable, while the picture object is retrieved with php. I can paste php into JS but not the other way around. So I'm stuck again. I got the ID but can't figure out how to get its path for the img tag.
brutalnv replied on at Permalink Reply
brutalnv
Try to use ConcreteFileManager.getFileDetails:

ConcreteFileManager.getFileDetails(fID, function(r) {
    for(var i in r.files) {
        var file = r.files[i];
        alert(file.url);
    }
});
linuxoid replied on at Permalink Reply
linuxoid
Thanks, mate! Now we're getting somewhere )))

So this works... 99%:
$(function(){
    $(document).bind('change', 'input[name=pictureID]', function() {
        var fID = $('input[name=pictureID]').val();
        $('#selected_picture').empty();
        if (fID != 0) {
            ConcreteFileManager.getFileDetails(fID, function(r) {
                for (var i in r.files) {
                    var file = r.files[i];
                    $('#selected_picture').append('<img src="' + file.url + '" />');
                }
            });
        }
    }).trigger('change');
});

The picture gets loaded after selection. But it doesn't get cleared when the selected image gets cleared with the file picker. Even though the input value gets set to '0'. So the change event doesn't trigger on clearing the picker.
brutalnv replied on at Permalink Reply
brutalnv
It's because the #selected_picture image is a dynamically created element.
You should use
$("#selected_picture").children().remove();
linuxoid replied on at Permalink Reply
linuxoid
No, that doesn't clear the div because the 'change' is not even triggered on clearing the file picker.

And BTW, the code appends another picture every time I open the form.
brutalnv replied on at Permalink Reply
brutalnv
$(function () {
    $(document).bind('change', 'input[name=pfID]', function() {
        var fID = $('input[name=pfID]').val();
        if (fID != 0) {
            ConcreteFileManager.getFileDetails(fID, function(r) {
                for (var i in r.files) {
                    var file = r.files[i];
                    $('#selected_picture').append('<img src="' + file.url + '" />');
                }
            });
        }
    }).trigger('change');
    Concrete.event.bind("ConcreteMenuShow", function (e, menu) {
        clearAction = $(menu.menuElement).find('a[data-file-manager-action=clear]');
        clearAction.bind("click", function () {


Hope that helps!
linuxoid replied on at Permalink Reply
linuxoid
This worked! Thank you very much.

So if anyone else needs that:
echo $al->image('picture', 'pictureID', t('Select picture'), $pic);
<div id="selected_picture"></div>
<script type="text/javascript" charset="UTF-8">
$(function(){
    $(document).bind('change', 'input[name=pictureID]', function() {
        var fID = $('input[name=pictureID]').val();
        if (fID != 0) {
            ConcreteFileManager.getFileDetails(fID, function(r) {
                jQuery.fn.dialog.hideLoader();
                var file = r.files[0];
                $("#selected_picture").children().remove();
                $('#selected_picture').empty();
                $('#selected_picture').append('<img src="' + file.url + '" />');
            });
        }