Vorschau des Bildes nach dem Hochladen mit der Formular-API

9

Ich habe eine Bilddatei mit dem managed_fileFormular-API-Typ hochgeladen , aber nach dem Hochladen des Bildes wird es nicht als Miniaturansicht neben dem Feld angezeigt. Was gerendert wird, ist der Dateiname des Bildes mit einem Link zum Bild und einem kleinen Symbol.

Wie zeige ich die Miniaturansicht des Bildes nach dem Hochladen an (wie die Bildvorschau aus dem Kernbildfeld)?

Wie kann ich auch ein Standardbild daneben anzeigen (wenn es einen Standardwert hat)?

Das ist mein 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
quelle

Antworten:

4

Ich habe das Problem mit einer einfachen Lösung behoben. Sie können dem Formularelement "tbs_thumb_upload" ein Thema hinzufügen und in der Themendatei das Element übergeben, wie im Code der Themendatei angegeben.

 // 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
quelle
1
Wird der letzte Teil des Codes von if (!empty($form['#file'])) {"drupal_render_children ($ form) drucken" in die .tpl.phpDatei schreiben ? Wenn nicht, wo soll ich dann diesen Teil schreiben?
Subhajyoti De
9

Definieren Sie das Thema im Feld und simulieren Sie die Codestruktur, um eine Vorschau des gerade hochgeladenen Bildes anzuzeigen. Meine Lösung lautet wie folgt:

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

In Ihrem hook_theme (),

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

In Ihrem 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
quelle
3
Wäre besser image_style_url('thumbnail', $element['#file']->uri)anstelle von file_create_url($element['#file']->uri)- aktueller Code kann das Layout ernsthaft beschädigen, wenn der Benutzer etwas Schlechtes hochlädt.
Mołot
Es gibt hier eine sehr ähnliche Lösung: stackoverflow.com/questions/18997423/…
ognockocaten
4

Informationen zur Dimension Überprüfen Sie diese Validierungsdatei_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
quelle
3

Das Hacken des HTML-Codes für eine Schaltfläche zum Entfernen funktioniert bei mir nicht. Die Seite wird aktualisiert, ohne das Bild zu entfernen. Stattdessen habe ich den theme_image_widgetRückruf des Kernbildfelds in kopiert 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;
}

Verwenden Sie diese Designfunktion, um das Element zu rendern:

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

Formularelementdefinition:

$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
quelle
Dieser sollte die Antwort sein, endlich funktioniert der Ajax, danke u !!!!
DarkteK
2

Fügen Sie ein weiteres Formularelement hinzu, das das Markup für Ihre Bildvorschau enthält. Im folgenden Code enthält $ v die interessierenden Formularwerte. Ihr spezieller Fall kann sie von einem Knoten, aus dem Formularstatus oder an einem anderen Ort abrufen. Es ist ein Dateiobjekt, das in ein Array umgewandelt wird.

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

Beachten Sie, dass ich den Dateistatus auf permanent gesetzt und erneut gespeichert habe. Hiermit werden die hochgeladenen Bilder korrekt in der Vorschau angezeigt. Bildstile können nicht für Bilder im temporären Speicher generiert werden, daher müssen Sie sie als Dauerwelle kennzeichnen. Abhängig von Ihrem Anwendungsfall und Workflow müssen Sie möglicherweise "verwaiste" Bilder adressieren.

Meine Formularstruktur ($ form ['photos'] ['items'] [$ i]) ist für ein Bildfeld mit mehreren Einträgen vorgesehen. Ich habe eine Themenvorlage, die sie sammelt und in drupal_add_tabledrag einfügt . Ihre Formulararray-Struktur wird sich wahrscheinlich unterscheiden.

Jason Smith
quelle
danke jason, aber ich denke dies für den Fall, dass ich Daten habe und sie in der Form anzeigen möchte (ich denke, $ v ist ein Objekt, das uri des Bildes hat), ich möchte eine Vorschau des Bildes wie im Bildfeld machen Wenn Sie das Bild mit der Upload-Schaltfläche neben dem Feld hochladen, wird es neben dem Feld
Ahmed
Das mache ich hier. $ v ist der Wert des Formularelements. Während einer AJAX / AHAH-Aktualisierung wird das Formular neu generiert und der Wert wird verwendet, um das Vorschaubild neben der neu hochgeladenen Datei anzuzeigen. $ form ['photos'] ['items'] ist ein Wrapper zum "Gruppieren" Ihres Widgets für Vorschau und Datei-Upload. $ form ['photos'] ['items'] [x] ['photo'] wäre dein Widget.
Jason Smith
Ich benutze nicht AHAH (nur Drupal 7 Form API) und ist Upload aktualisieren Alle Formulare
Ahmed
Es gibt keine Möglichkeit, dies zu tun, von der ich weiß, dass AJAX / AHAH nicht verwendet wird. Tut mir leid, ich könnte nicht mehr helfen: /
Jason Smith