Добавление атрибута 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'),
);
Как вы можете видеть, я добавил массив атрибутов #, устанавливающий "принять".
- Значение accept не отображается в результирующем HTML-файле. Я удивлен, что он, по крайней мере, не установлен где-нибудь.
- Если я изменю ключ массива с
accept
наclass
, то он появится в родительском div, а не в элементе ввода, где я его ожидаю.
Итак, похоже, что нужно преодолеть 2 проблемы чтобы получить возможность использовать эту функцию.
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;
}
Для 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;
}
Для 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',
];
Это все...
Расширение ответа Клайва.
Вы можете использовать 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