Anteprima immagine dopo il caricamento tramite Form API


9

Ho caricato un file di immagine utilizzando il managed_filetipo di API API, ma dopo aver caricato l'immagine non viene visualizzato come anteprima accanto al campo. Ciò che viene reso è il nome del file dell'immagine con un collegamento all'immagine e una piccola icona.

Come faccio a mostrare l'anteprima dell'immagine dopo averla caricata (come l'anteprima dell'immagine dal campo Immagine principale)?

Inoltre, come posso mostrare un'immagine predefinita accanto ad essa (se ha un valore predefinito)?

Questo è il mio codice:

$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),
  )

Risposte:


4

Ho risolto il problema con una semplice correzione. È possibile aggiungere un tema all'elemento del modulo "tbs_thumb_upload" e nel file del tema passare l'elemento come indicato nel codice del file del 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
L'ultima parte del codice if (!empty($form['#file'])) {verrà stampata da `print drupal_render_children ($ form);` scriverà nel .tpl.phpfile? In caso contrario, dove dovrei scrivere questa parte?
Subhajyoti del

9

Definisci il tema nel campo e simula la struttura del codice per visualizzare in anteprima l'immagine appena caricata. La mia soluzione è la seguente,

$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/'
    );

Nel tuo hook_theme (),

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

Nel tuo 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
Sarebbe meglio usare image_style_url('thumbnail', $element['#file']->uri)al posto di file_create_url($element['#file']->uri)- il codice corrente può seriamente interrompere il layout se l'utente carica qualcosa di brutto.
Mołot,

C'è una soluzione molto simile qui: stackoverflow.com/questions/18997423/...
ognockocaten

4

sulla dimensione controlla questa validazione 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

L'hacking dell'HTML per un pulsante di rimozione non funziona per me. La pagina si aggiorna senza rimuovere l'immagine. Invece ho copiato dal theme_image_widgetcallback del campo immagine core trovato 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;
}

Utilizzare questa funzione tema per rendere l'elemento:

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

Definizione dell'elemento del modulo:

$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'),
  ),
);

Questa dovrebbe essere la risposta, finalmente l'ajax funziona, grazie !!!!
DarkteK,

2

Aggiungi un altro elemento del modulo per contenere il markup per l'anteprima dell'immagine. Nel codice seguente, $ v contiene i valori del modulo di interesse. Il tuo caso specifico potrebbe estrarli da un nodo, dallo stato del modulo o da qualche altra parte. È un oggetto file proiettato su un array.

// 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']))
    )
  );
}

Si noti che ho impostato lo stato del file su permanente e ri-salvare. Questo è per le immagini che vengono caricate per essere visualizzate in anteprima correttamente. Gli stili di immagine non possono essere generati per le immagini nella memoria temporanea, quindi è necessario contrassegnarli come perm. A seconda del caso d'uso e del flusso di lavoro, potrebbe essere necessario indirizzare immagini "orfane".

La mia struttura del modulo ($ form ['photos'] ['items'] [$ i]) è per un campo immagine a più voci. Ho un modello di tema che li raccoglie e li inserisce in drupal_add_tabledrag . La struttura della matrice del modulo sarà probabilmente diversa.


grazie Jason ma penso che nel caso in cui avessi un dato e voglio vederlo nel modulo (penso che $ v sia un oggetto che ha uri dell'immagine) Voglio fare un'anteprima dell'immagine come nel campo immagine quando si carica l'immagine utilizzando il pulsante di caricamento accanto al campo, appare accanto al campo
Ahmed il

Questo è quello che sto facendo qui. $ v è il valore dell'elemento del modulo. Durante un aggiornamento AJAX / AHAH il modulo viene rigenerato e il valore verrà utilizzato per mostrare l'immagine di anteprima accanto al file appena caricato. $ form ['photos'] ['items'] è un wrapper per "raggruppare" l'anteprima e il widget di caricamento dei file. $ form ['photos'] ['items'] [x] ['photo'] sarebbe il tuo widget.
Jason Smith,

Non sto usando AHAH (solo Drupal 7 modulo API) ed è upload refresh Tutto il modulo
Ahmed

Non c'è modo di farlo che io sappia che non usa AJAX / AHAH, mi dispiace non poter essere più di aiuto: /
Jason Smith
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.