Добавление атрибута accept в поле управляемый файл для указания типов файлов на стороне клиента


У меня есть поле файла в пользовательской форме, как это:

  $form['image_upload'] = array(
    '#type' => 'managed_file',
    '#title' => t('Image upload'),
    '#description' => t('Upload png images'),
    '#upload_location' => 'public://',
    '#process' => array('file_managed_file_process'),
    '#attributes' => array('accept' => '.png'),
  );

Как вы можете видеть, я добавил массив атрибутов #, устанавливающий "принять".

  1. Значение accept не отображается в результирующем HTML-файле. Я удивлен, что он, по крайней мере, не установлен где-нибудь.
  2. Если я изменю ключ массива с accept на class, то он появится в родительском div, а не в элементе ввода, где я его ожидаю.

Итак, похоже, что нужно преодолеть 2 проблемы чтобы получить возможность использовать эту функцию.

Author: greggles, 2015-01-23

4 answers

Все еще не уверен, что это настоящая ошибка; элемент file_managed содержит несколько элементов внутри, поэтому нет реального способа указать, на какой из них вы ориентируетесь с помощью свойства #attributes.

Таким образом, в одном отношении имеет смысл, что они будут проигнорированы из-за двусмысленности. Но это работает для классов, так что в этом меньше смысла. Потребуется еще немного покопаться, чтобы выяснить, почему я подозреваю.

В любом случае, вы можете обойти это, добавив свой собственный обратный вызов процесса в элемент:

$form['image_upload'] = array(
  '#type' => 'managed_file',
  '#title' => t('Image upload'),
  '#description' => t('Upload png images'),
  '#upload_location' => 'public://',
  '#process' => array('file_managed_file_process', 'MYMODULE_file_managed_file_process'),
);

function MYMODULE_file_managed_file_process($element) {
  $element['upload']['#attributes']['accept'] = '.jpg';
  return $element;
}
 4
Author: Clive, 2015-01-23 17:57:08

Для drupal 8 что-то подобное будет работать при использовании в пользовательском модуле:

function my_module_field_widget_form_alter(&$element, FormStateInterface &$form_state, $context) {
  if (isset($element['#field_name']) && $element['#field_name'] === 'my_field_name') {
    $element['#process'][] = 'app_icon_image_file_validate';
    return $element;
  }
}

function app_icon_image_file_validate(&$element, FormStateInterface &$form_state, &$complete_form) {
  $element['upload']['#attributes']['accept'] = '.svg';
  return $element;
}
 2
Author: plocks, 2019-04-02 14:02:31

Для drupal 8:

    $form['audio-file'] = [
        '#type' => 'managed_file',
        '#title' => 'select file:',
        '#upload_location' => 'private://',
        '#upload_validators' => [
            'file_validate_extensions' => array('mp3 m4a wav'),
        ],
        '#accept'   =>  '.wav,.mp3,.m4a',
    ];

Это все...

 0
Author: victor, 2019-10-28 05:49:48

Расширение ответа Клайва.

Вы можете использовать hook_element_info_alter, чтобы всегда вызывать пользовательскую функцию процесса:


/**
 * Implements hook_element_info_alter().
 * 
 * @param $type
 */
function MYMODULE_element_info_alter(&$type) {
  // Custom process managed_file element.
  $type['managed_file']['#process'][] = 'MYMODULE_file_managed_file_process';
}

/**
 * @param $element
 * @param $form_state
 * @param $form
 *
 * @return mixed
 */
function MYMODULE_file_managed_file_process($element, &$form_state, $form){
  if(isset($element['#upload_attributes'])){
    $element['upload']['#attributes'] = $element['#upload_attributes'];
    unset($element['#upload_attributes']);
  }
  return $element;
}

Таким образом, вы можете использовать пользовательский атрибут #upload_attributes для присвоения всех видов атрибутов внутреннему элементу upload

 0
Author: eliosh, 2020-12-18 17:59:57