3

Here is my form field for users to upload their company logo:

$form['company_logo'] = array(
  '#type' => 'managed_file',
  '#title' => t('Company Logo'),
  '#description' => t('Allowed extensions: gif png jpg jpeg'),
  '#upload_location' => 'public://uploads/',
  '#default_value' => $row['companyLogo'],
  '#upload_validators' => array(
    'file_validate_extensions' => array('gif png jpg jpeg'),
    // Pass the maximum file size in bytes
    'file_validate_size' => array(1024*1024*1024),
  ),

What I would like to do is have their logo displayed after they click "upload".

I'm surprised this isn't a simple option built in to the form API...how can one go about doing this?

valen
  • 807
  • 1
  • 16
  • 43

2 Answers2

5

Declare a theme function

/**
 * Implements mymodule_thumb_upload theme callback.
 */
function theme_mymodule_thumb_upload($variables) {

    $element = $variables['element'];

    if (isset($element['#file']->uri)) {
        $output = '<div id="edit-logo-ajax-wrapper"><div class="form-item form-type-managed-file form-item-logo"><span class="file">';
        $output .= '<img height="50px" src="' . image_style_url('thumbnail', $element['#file']->uri) . '" />';
        $output .= '</span><input type="submit" id="edit-' . $element['#name'] . '-remove-button" name="' . $element['#name'] . '_remove_button" value="Remove" class="form-submit ajax-processed">';
        $output .= '<input type="hidden" name="' . $element['#name'] . '[fid]" value="' . $element['#file']->fid . '"></div></div>';
        return $output;
    }
}

Tell drupal that this theme function could be used to render an element.

/**
 * Implements hook_theme().
 */
function mymodule_theme() {
  return array(
    'mymodule_thumb_upload' => array(
      'render element' => 'element',
    )
  );
}

Use '#theme' => 'mymodule_thumb_upload', to make managed file call a custom theme function for the element.

<?php
$form['company_logo'] = array(
  '#type' => 'managed_file',
  '#title' => t('Company Logo'),
  '#description' => t('Allowed extensions: gif png jpg jpeg'),
  '#upload_location' => 'public://uploads/',
  '#default_value' => $row['companyLogo'],
  '#theme' => 'mymodule_thumb_upload',
  '#upload_validators' => array(
    'file_validate_extensions' => array('gif png jpg jpeg'),
    // Pass the maximum file size in bytes
    'file_validate_size' => array(1024*1024*1024),
  ),
D34dman
  • 1,241
  • 9
  • 12
  • 1
    This soloution works, but you should fix closing div tags in theme $output. They are not closed. – tomas.teicher Dec 06 '13 at 07:28
  • I have a problem also with removing image according this solution. After clicking on Remove button, image is not removed and whole page is refreshed with the same image. Can anybody help, how to edit this solution, or where can be problem? (I hava no js errors in javascript console) – tomas.teicher Dec 06 '13 at 07:36
  • @tomas.teicher, thanks for the input, have edited the theme function to include the div tags. The removing image should work out of the box though. – D34dman Dec 10 '13 at 17:41
  • doesnt work when I tried it. Any related links about displaying an uploaded image.? –  Feb 02 '15 at 05:55
  • @D34dman, the remove button works as it should but it refreshed the page. Is there some work-around to stop the page from getting refreshed ? – AkiShankar May 20 '15 at 10:01
  • It doesn't work for me. After using this code I have file button and when I click it to choose file... I have no ajax call at all (previously there was ajax call that returns default link to file). – PolGraphic Jan 01 '17 at 19:52
  • @PolGraphic are there javascript errors on page? Also above solution is for D7. – D34dman Jan 03 '17 at 11:17
0

The previous answer's remove button did not work for me either. The page refreshed without removing the image. Instead I copied from the core image field's theme_image_widget callback found in docroot/modules/image/image.field.inc.

/**
* Implements theme_mymodule_thumb_upload theme callback.
*/
function theme_mymodule_thumb_upload($variables) {
  $element = $variables['element'];
  $output = '';
  $output .= '<div class="image-widget form-managed-file clearfix">';

  // My uploaded element didn't have a preview array item, so this didn't work
  //if (isset($element['preview'])) {
  //  $output .= '<div class="image-preview">';
  //  $output .= drupal_render($element['preview']);
  //  $output .= '</div>';
  //}

  // If image is uploaded show its thumbnail to the output HTML
  if ($element['fid']['#value'] != 0) {
    $output .= '<div class="image-preview">';

    // Even though I was uploading to public:// the $element uri was pointing to temporary://system, so the path to the preview image was a 404
    //$output .= theme('image_style', array('style_name' => 'thumbnail', 'path' => file_load($element['fid']['#value'])->uri, 'getsize' => FALSE));

    $output .= theme('image_style', array('style_name' => 'thumbnail', 'path' => 'public://'.$element['#file']->filename, 'getsize' => FALSE));
    $output .= '</div>';
  }

  $output .= '<div class="image-widget-data">';

  if ($element['fid']['#value'] != 0) {
    $element['filename']['#markup'] .= ' <span class="file-size">(' . format_size($element['#file']->filesize) . ')</span> ';
  }

  // The remove button is already taken care of by rendering the rest of the form. No need to hack up some HTML!
  $output .= drupal_render_children($element);

  $output .= '</div>';
  $output .= '</div>';

  return $output;
}

Use this theme function to render the element:

/**
* Implements hook_theme().
*/
function mymodule_theme() {
  return array(
    'mymodule_thumb_upload' => array(
      'render element' => 'element',
    )
  );
}

Form element definition:

$form['image_upload'] = array(
  '#type' => 'managed_file',
  '#default_value' => $value,
  '#title' => t('Thumbnail Image'),
  '#description' => t('Upload a thumbnail'),
  '#upload_location' => 'public://',
  '#theme' => 'mymodule_thumb_upload',
  '#progress_indicator' => 'throbber',
  '#progress_message' => 'Uploading ...',
  '#upload_validators' => array(
    'file_validate_is_image' => array(),
    'file_validate_extensions' => array('jpg jpeg gif png'),
    'file_validate_image_resolution' => array('600x400','300x200'),
  ),
);
Wesley Musgrove
  • 574
  • 5
  • 8
  • It doesn't work for me. After using this code I have file button and when I click it to choose file... I have no ajax call at all (previously there was ajax call that returns default link to file). The logs shows "Notice: Undefined index: fid in ..._thumb_upload() " in my .theme file. – PolGraphic Jan 01 '17 at 19:54