web-dev-qa-db-ja.com

フォームAPI画像プレビュー

私は'managed_file'を使用したfapiでの画像プレビューに関する多くの議論を読みましたが、D8でこれを適切に行う方法に関する決定的な答えを見つけることができません。

明白な解決策はDrupal\image\Plugin\Field\FieldWidget\ImageWidgetを再利用することですが、これを達成する方法がわかりません。

だから私の質問は、D8のフォームに画像プレビューのある画像アップロードフィールドをどのように持つことができ、buildForm関数の連想配列はどのようになるのでしょうか。

6
maartend

しばらく検索した後、ここでこれに対する何らかの回避策の解決策を見つけました: https://stackoverflow.com/a/38268567/2267244

私はそれをテストし、それが動作しました、これは私が使用したビット修正バージョンです。

また、stackoverflow.comで解決策を見つけたので、この質問をd​​pulicateとしてマークする必要があるかどうかもわかりません。

とにかく、フォームフィールドは次のようになります。

$form['image_with_preview'] = [
  '#type' => 'managed_file',
  '#title' => t('Image with preview'),
  '#upload_validators' => [
    'file_validate_extensions' => ['gif png jpg jpeg'],
    'file_validate_size' => [25600000],
  ],
  '#theme' => 'image_widget',
  '#preview_image_style' => 'medium',
  '#upload_location' => 'public://',
  '#required' => FALSE,
];

また、次のようにモジュールにhook_preprocess_HOOKを実装する必要があります。

function YOUR_MODULE_preprocess_image_widget(&$variables) {
    $element = $variables['element'];

    $variables['attributes'] = array('class' => array('image-widget', 'js-form-managed-file', 'form-managed-file', 'clearfix'));

    if (!empty($element['fids']['#value'])) {
      $file = reset($element['#files']);
      $element['file_' . $file->id()]['filename']['#suffix'] = ' <span class="file-size">(' . format_size($file->getSize()) . ')</span> ';
      $file_variables = array(
        'style_name' => $element['#preview_image_style'],
        'uri' => $file->getFileUri(),
      );

      // Determine image dimensions.
      if (isset($element['#value']['width']) && isset($element['#value']['height'])) {
        $file_variables['width'] = $element['#value']['width'];
        $file_variables['height'] = $element['#value']['height'];
      } else {
        $image = \Drupal::service('image.factory')->get($file->getFileUri());
        if ($image->isValid()) {
          $file_variables['width'] = $image->getWidth();
          $file_variables['height'] = $image->getHeight();
        }
        else {
          $file_variables['width'] = $file_variables['height'] = NULL;
        }
      }

      $element['preview'] = array(
        '#weight' => -10,
        '#theme' => 'image_style',
        '#width' => $file_variables['width'],
        '#height' => $file_variables['height'],
        '#style_name' => $file_variables['style_name'],
        '#uri' => $file_variables['uri'],
      );

      // Store the dimensions in the form so the file doesn't have to be
      // accessed again. This is important for remote files.
      $element['width'] = array(
        '#type' => 'hidden',
        '#value' => $file_variables['width'],
      );
      $element['height'] = array(
        '#type' => 'hidden',
        '#value' => $file_variables['height'],
      );
    }

    $variables['data'] = array();
    foreach (\Drupal\Core\Render\Element::children($element) as $child) {
      $variables['data'][$child] = $element[$child];
    }
}

私はそれを私のローカルDrupalインスタンスでテストしました、そしてそれはうまくいきます、AJAXアップロードが完了した後に画像プレビューが表示されました.

8
otarza