3

I have managed_file for uploading an image in my form and I would like to display the image(thumbnail) right away when the user uploads it so he won' have to submit the form to see it(I am rendering it in the form if the image exists).

I think there might be an issue with the ajax wrapper/structure so I am not sure how exactly it should be achieved without too much customization/coding.

2

This is my solution:

<?php

namespace Drupal\foo\Element;

use Drupal\Core\Form\FormStateInterface;
use Drupal\file\Element\ManagedFile;

/**
 * @FormElement("managed_image")
 */
class ManagedImage extends ManagedFile {

  /**
   * {@inheritdoc}
   */
  public function getInfo() {
    $info = parent::getInfo();
    // @see \Drupal\image\Plugin\Field\FieldWidget\ImageWidget::formElement()
    $info['#accept'] = 'image/*';
    $info['#image_style'] = 'thumbnail';

    return $info;
  }

  /**
   * {@inheritdoc}
   */
  public static function processManagedFile(&$element, FormStateInterface $form_state, &$complete_form) {
    /** @var \Drupal\Core\Image\ImageFactory $image_factory */
    $image_factory = \Drupal::service('image.factory');
    $element['#upload_validators'] += [
      'file_validate_is_image' => [],
      'file_validate_extensions' => [implode(' ', $image_factory->getSupportedExtensions())]
    ];

    $element['#description'] = [
      '#theme' => 'file_upload_help',
      '#description' => isset($element['#description']) ? $element['#description'] : NULL,
      '#upload_validators' => $element['#upload_validators']
    ];

    return parent::processManagedFile($element, $form_state, $complete_form);
  }

  /**
   * {@inheritdoc}
   */
  public static function preRenderManagedFile($element) {
    $element = parent::preRenderManagedFile($element);

    if (!empty($element['#files'])) {
      foreach ($element['#files'] AS $delta => $file) {
        /** @var \Drupal\file\Entity\File $file */
        $element['file_' . $delta] = [
          'preview' => [
            '#type' => 'container',
            '#weight' => -10,
            '#attributes' => [
              'class' => [
                'image-preview'
              ]
            ],
            'image' => [
              '#theme' => 'image_style',
              '#style_name' => $element['#image_style'],
              '#uri' => $file->getFileUri()
            ]
          ]
        ] + $element['file_' . $delta];
      }
    }

    return $element;
  }

}
  • Great solution, thank you for providing it. Please consider that while implementing this, also in Form Field definition should be changed to: '#type' => 'managed_image', . – Francis Apr 12 '18 at 9:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy