Aperçu de l'image après le téléchargement à l'aide de l'API Form

9

J'ai téléchargé un fichier image à l'aide du managed_filetype API de formulaire, mais après avoir téléchargé l'image, il n'apparaît pas sous forme de miniature à côté du champ. Ce qui est rendu est le nom de fichier de l'image avec un lien vers l'image et une petite icône.

Comment afficher la vignette de l'image après l'avoir téléchargée (comme l'aperçu de l'image à partir du champ Image principal)?

Comment puis-je également afficher une image par défaut à côté (si elle a une valeur par défaut)?

Voici mon code:

$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),
  )
Ahmed
la source

Réponses:

4

J'ai résolu le problème avec une solution simple. Vous pouvez ajouter un thème à l'élément de formulaire "tbs_thumb_upload" et, dans le fichier de thème, remettre l'élément comme indiqué dans le code du fichier de thème.

 // 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);
Mubashar Khokhar
la source
1
Est-ce que la dernière partie du code de if (!empty($form['#file'])) {`print drupal_render_children ($ form);` écrit dans le .tpl.phpfichier? Sinon, où dois-je écrire cette partie?
Subhajyoti De
9

Définissez le thème dans le champ et simulez la structure du code pour prévisualiser l'image que vous venez de télécharger. Ma solution est la suivante,

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

Dans votre hook_theme (),

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

Dans votre 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;
    }
}
Jason
la source
3
Il serait préférable d'utiliser image_style_url('thumbnail', $element['#file']->uri)à la place de file_create_url($element['#file']->uri)- le code actuel peut sérieusement casser la mise en page si l'utilisateur télécharge quelque chose de mauvais.
Mołot
Il existe une solution très similaire ici: stackoverflow.com/questions/18997423/…
ognockocaten
4

à propos de la dimension, vérifiez cette validation 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'),
  )
lmeurs
la source
3

Hacker le code HTML d'un bouton de suppression ne fonctionne pas pour moi. La page est actualisée sans supprimer l'image. Au lieu de cela, j'ai copié à partir du theme_image_widgetrappel du champ d'image principale trouvé dans 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;
}

Utilisez cette fonction de thème pour rendre l'élément:

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

Définition de l'élément de formulaire:

$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'),
  ),
);
Wesley Musgrove
la source
Celui-ci devrait être la réponse, enfin l'ajax fonctionne, thx u !!!!
DarkteK
2

Ajoutez un autre élément de formulaire pour contenir le balisage de votre aperçu d'image. Dans le code ci-dessous, $ v contient les valeurs de formulaire qui vous intéressent. Votre cas spécifique peut les extraire d'un nœud, d'un état de formulaire ou ailleurs. Il s'agit d'un objet fichier converti en tableau.

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

Notez que j'ai défini le statut du fichier sur permanent et réenregistré. C'est pour que les images qui sont téléchargées soient prévisualisées correctement. Les styles d'image ne peuvent pas être générés pour les images dans le stockage temporaire, vous devez donc les marquer comme permanentes. En fonction de votre cas d'utilisation et de votre flux de travail, vous devrez peut-être traiter des images «orphelines».

Ma structure de formulaire ($ form ['photos'] ['items'] [$ i]) est pour un champ d'image à entrées multiples. J'ai un modèle de thème qui les rassemble et les met dans drupal_add_tabledrag . La structure de votre tableau de formulaires sera probablement différente.

Jason Smith
la source
merci jason mais je pense que si j'ai des données et je veux les voir sous la forme (je pense que $ v est un objet qui a uri de l'image) je veux faire un aperçu de l'image comme dans le champ image lors du téléchargement de l'image en utilisant le bouton de téléchargement à côté du champ, il apparaît à côté du champ
Ahmed
Voilà ce que je fais ici. $ v est la valeur de l'élément de formulaire. Lors d'une actualisation AJAX / AHAH, le formulaire est régénéré et la valeur sera utilisée pour afficher l'image d'aperçu à côté du fichier nouvellement téléchargé. $ form ['photos'] ['items'] est un wrapper pour "grouper" votre widget de prévisualisation et de téléchargement de fichiers. $ form ['photos'] ['items'] [x] ['photo'] serait votre widget.
Jason Smith
Je n'utilise pas AHAH (juste l'api du formulaire Drupal 7) et est en train d'actualiser tout le formulaire
Ahmed
Il n'y a aucun moyen de faire cela que je sache qui n'utilise pas AJAX / AHAH, désolé je ne pourrais pas être plus d'aide: /
Jason Smith