Obtener una vista previa de la imagen después de cargarla utilizando el formulario API


9

Cargué un archivo de imagen usando el managed_filetipo de API de formulario, pero después de cargar la imagen, no aparece como una miniatura al lado del campo. Lo que se representa es el nombre de archivo de la imagen con un enlace a la imagen y un pequeño icono.

¿Cómo muestro la miniatura de la imagen después de cargarla (como la vista previa de la imagen desde el campo Imagen principal)?

Además, ¿cómo puedo mostrar una imagen predeterminada al lado (si tiene un valor predeterminado)?

Este es mi código:

$form['logo'] = array(
      '#title' => t('Logo'),
      '#type' => 'managed_file',
      '#required' => TRUE,
      '#default_value' => variable_get('logo', ''),
      '#upload_location' => 'public://',
      '#upload_validators' => array(
            'file_validate_extensions' => array('gif png jpg jpeg'),
            'file_validate_size' => array(0.3*1024*1024),
  )

Respuestas:


4

He resuelto el problema con una solución simple. Puede agregar un tema al elemento de formulario "tbs_thumb_upload" y, en la mano del archivo de tema, el elemento como se menciona en el código del archivo de tema.

 // THIS IS THE FILE FIELD  
 $form['logo'] = array(
  '#type' => 'managed_file',
  '#title' => t('Logo'),
  '#description' => t('Allowed extensions: gif png jpg jpeg'),
  '#upload_validators' => array(
    'file_validate_extensions' => array('gif png jpg jpeg'),
    // Pass the maximum file size in bytes
    'file_validate_size' => array(1 * 1024 * 1024),
  ),
  '#theme' => 'tbs_thumb_upload',
  '#upload_location' => 'public://society/',
  '#attributes' => array('default_image_path' => TBS_IMAGE_DEFAULT_SOCIETY)
  );

 // THIS IS THE THEME FILE : THEME : tbs_thumb_upload : Theme file code
 if (!empty($form['#file'])) {
   $uri = $form['#file']->uri;
   $desc = FALSE;
 }else {
   $uri = $form['#attributes']['default_image_path'];
   $desc = TRUE;
 }

 // Render form element
 print drupal_render_children($form);

1
¿La última parte del código de if (!empty($form['#file'])) {`print drupal_render_children ($ form);` escribirá en el .tpl.phparchivo? Si no es así, ¿dónde debo escribir esta parte?
Subhajyoti De

9

Defina el tema en el campo y simule la estructura del código para obtener una vista previa de la imagen que acaba de cargar. Mi solución es la siguiente,

$form['abc_field']['abc_filename'] = array(
        '#type' => 'managed_file',
        '#title' => t('abc image'),
        '#upload_validators' => array(
            'file_validate_extensions' => array('gif png jpg jpeg'),
            'file_validate_size' => array(1 * 1024 * 1024),
        ),
        '#theme' => 'abc_thumb_upload',
        '#upload_location' => 'public://abc/'
    );

En su hook_theme (),

return array(
    'abc_thumb_upload' => array(
        'render element' => 'element',
        'file'           => 'abc.module',
));

En su theme_abc_thumb_upload (),

function theme_abc_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="' . file_create_url($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 . '">';

        return $output;
    }
}

3
Sería mejor usarlo image_style_url('thumbnail', $element['#file']->uri)en lugar de file_create_url($element['#file']->uri): el código actual puede romper seriamente el diseño si el usuario carga algo malo.
Mołot 01 de

Aquí hay una solución muy similar: stackoverflow.com/questions/18997423/…
ognockocaten

4

acerca de la dimensión, compruebe esta validación file_validate_image_resolution :

$form['logo'] = array(
      '#title' => t('Logo'),
      '#type' => 'managed_file',
      '#required' => TRUE,
      '#default_value' => variable_get('logo', ''),
      '#upload_location' => 'public://',
      '#upload_validators' => array(
            'file_validate_extensions' => array('gif png jpg jpeg'),
            'file_validate_size' => array(0.3*1024*1024),
            'file_validate_image_resolution'=>array('100x100'),
  )

3

Hackear el HTML para un botón de eliminar no me funciona. La página se actualiza sin eliminar la imagen. En su lugar, copié de la theme_image_widgetdevolución de llamada del campo de imagen central que se encuentra en 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 esta función de tema para representar el elemento:

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

Definición del elemento de forma:

$form['upload_image'] = array(
  '#type' => 'managed_file',
  '#default_value' => $value,
  '#title' => t('Image'),
  '#description' => t('Upload an image'),
  '#upload_location' => 'public://',
  '#theme' => 'mymodule_thumb_upload',
  '#upload_validators' => array(
    'file_validate_is_image' => array(),
    'file_validate_extensions' => array('jpg jpeg gif png'),
    'file_validate_image_resolution' => array('600x400','300x200'),
  ),
);

Esta debería ser la respuesta, finalmente el ajax funciona, ¡gracias!
DarkteK

2

Agregue otro elemento de formulario para contener el marcado para la vista previa de su imagen. En el siguiente código, $ v contiene los valores de forma de interés. Su caso específico puede extraerlos de un nodo, del estado del formulario o de otro lugar. Es un objeto de archivo convertido a una matriz.

// If there is a file id saved
if (!empty($v['fid'])) {
  // If there is no file path, a new file is uploaded
  // save it and try to fetch an image preview
  if (empty($v['uri'])) {
    $file = file_load($v['fid']);
    // Change status to permanent so the image remains on the filesystem. 
    $file->status = FILE_STATUS_PERMANENT;
    $file->title  = $v['title'];
    // Save.
    file_save($file);
    global $user;
    file_usage_add($file, 'node', 'node', $user->uid);
    $v = (array)$file;
  }
  $form['photos']['items'][$i]['preview']['#markup'] = theme(
    'image_style',
    array(
      'style_name' => 'form_image_preview',
      'path' => file_build_uri(file_uri_target($v['uri']))
    )
  );
}

Tenga en cuenta que configuro el estado del archivo como permanente y lo vuelvo a guardar. Esto es para que las imágenes que se cargan se previsualicen correctamente. Los estilos de imagen no se pueden generar para las imágenes en el almacenamiento temporal, por lo que debe marcarlas como permanentes. Dependiendo de su caso de uso y flujo de trabajo, es posible que deba abordar imágenes "huérfanas".

Mi estructura de formulario ($ form ['fotos'] ['artículos'] [$ i]) es para un campo de imagen de entrada múltiple. Tengo una plantilla de tema que los reúne y los coloca en drupal_add_tabledrag . Su estructura de matriz de formulario probablemente diferirá.


gracias Jason pero creo que esto en caso de que tenga datos y quiera verlos en el formulario (creo que $ v es un objeto que tiene uri de la imagen) Quiero hacer una vista previa de la imagen como en el campo de imagen al cargar la imagen usando el botón de carga al lado del campo, aparece al lado del campo
Ahmed

Eso es lo que estoy haciendo aquí. $ v es el valor del elemento del formulario. Durante una actualización AJAX / AHAH, el formulario se regenera y el valor se usará para mostrar la imagen de vista previa al lado del archivo recién cargado. $ form ['photos'] ['items'] es un contenedor para "agrupar" su widget de vista previa y carga de archivos. $ form ['fotos'] ['elementos'] [x] ['foto'] sería su widget.
Jason Smith

No estoy usando AHAH (solo Drupal 7 formulario api) y estoy cargando actualizar todo el formulario
Ahmed

No hay forma de hacer esto que sepa que no usa AJAX / AHAH, lo siento, no podría ser más ayuda: /
Jason Smith
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.