xandeadx.ru Блог музицирующего веб-девелопера

Drupal → Использование виджета AJAX загрузки файлов в своих формах

Опубликовано в

Я как-то упустил из виду, что помимо стандартного способа загрузки файлов в своих формах можно использовать AJAX виджет поля File:

Поле загрузки файлов
Результат загрузки файла

Пример использования:

/**
 * Form builder.
 */
function mymodule_myform($form) {
  $form['file'] = array(
    '#type' => 'managed_file',
    '#title' => 'Картинка',
    '#description' => 'Выберите файл с расширением jpg, jpeg, png или gif',
    '#upload_location' => 'public://',
    '#upload_validators' => array(
      'file_validate_is_image' => array(),
      'file_validate_extensions' => array('png gif jpg jpeg'),
      'file_validate_size' => array(1 * 1024 * 1024),
    ),
    '#default_value' => variable_get('mymodule_myfilefid'),
  );
 
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => 'Отправить',
  );
 
  return $form;
}
 
/**
 * Form submit callback.
 */
function mymodule_myform_submit($form, &$form_state) {
  // Delete old file
  $old_file_fid = variable_get('mymodule_myfilefid');
  if ($old_file_fid && $old_file_fid != $form_state['values']['file']) {
    $old_file = file_load($old_file_fid);
    file_usage_delete($old_file, 'mymodule');
    file_delete($old_file);
  }
 
  // Save new file
  $file = file_load($form_state['values']['file']);
  $file->status = FILE_STATUS_PERMANENT;
  file_save($file);
  file_usage_add($file, 'mymodule', 'mymodule', 0);
  variable_set('mymodule_myfilefid', $file->fid);
 
  drupal_set_message('Картинка загружена');
}

Об удалении файла надо заботиться самостоятельно.

Документация.
Модуль для загрузки картинок и отображения их превьюшек.

Написанное актуально для Drupal 7
Похожие записи

Комментарии RSS

Спасибо за пример!
Скажите как загрузить несколько файлов? т.е. при выборе одного файла появлялось форма для загрузки еще одного и т.д.

Спасибо за пример!
Не совсем понял для чего нужна функция mymodule_myform_submit? Файл и без нее загружается на сервер или файл при такой загрузке в друпале имеет состояние "временного" и ему нужно присвоить статус "постоянного".

А можно в этом виджете указать диалоговому окну маску разрешенных расширения для открытия или такое не предусмотрено?

Если файл уже был когда-то загружен, как передать виджету что файл уже есть и надо просто вывести имя файла и кнопку Remove (т.е. привести к состоянию как на 2-м скриншоте)?

заполнить #default_value

Павел, FILE_STATUS_PERMANENT вам ни о чем не говорит?

А не подскажите как сделать, если мне необходимо загрузить больше одного изображения?

создайте больше одного элемента формы ;)

нее, мне необходима что-то вроде массовой загрузки файлов. Например если мне нужно загрузить 100 изображений - эт не вариант делать 100 элементов форм.

из коробки способов нет

а зачем писать свою кнопку, если она по умолчанию при использовании managed_file уже существует ? Или тогда mymodule_myform_submit не сработает ? я так понимаю ?

потому что это кнопка виджета загрузки файлов, а не формы

а не подскажите что не так делаю. Вообщем есть форма из модуля, которая загружает изображения. Всё-бы хорошо, только вот статус на хранение на сохранение изображения ни как не могу поменять, т.е. у меня не обрабатывается сабмит вот код в модуле:

<?php
function example_admin_settings(){
  $form['file'] = array(
	  '#type' => 'managed_file',
	  '#title' => 'Загрузите изображение',
	  '#description' => 'Выберите изображение в формате jpg, png, gif',
	  '#upload_location' => 'public://example',
	  '#default_value' => variable_get('file', ''),
  );
 
  return system_settings_form($form);
}
 
function example_admin_settings_submit($form, &$form_state){
	$file = file_load($form_state['values']['file']);
	$file->status = FILE_STATUS_PERMANENT;
	file_save($file);
	drupal_set_message('Hello World');
}

Подскажите пожалуйста-как привязать валидейшн к тому что написано - ну для того что бы проверить был ли загружен файл или нет. дело в том что я прикрепил валидейшн функцию к новой кнопке в форме и должен проверить загружен ли файл или нет только принажатии этой кнопки. Нижеприведенный код выдает ошибку вот такую ошибку ajax:

An AJAX HTTP request terminated abnormally.
Debugging information follows.
Path: <a href="https://en.myhost/file/ajax/field_cv/und/0/form-p4NjUVngT4sgFkVxTikjeWxnDrq5U47BM37XNBO0IH0<br />
StatusText:" title="https://en.myhost/file/ajax/field_cv/und/0/form-p4NjUVngT4sgFkVxTikjeWxnDrq5U47BM37XNBO0IH0<br />
StatusText:" rel="nofollow">https://en.myhost/file/ajax/field_cv/und/0/form-p4NjUVngT4sgFkVxTikjeWxn...</a> n/a
ResponseText: 
Error  
The website encountered an unexpected error. Please try again later.    
 
ReadyState: undefined

Проверил права на запись в этой папке: стоят как положено: drwxrwxr-x www-data www-data
А вот функция валидейшн:
function applicationform_submit_validate($form, &$form_state) {
  $field_cv = file_save_upload('field_cv', $validators, 'private://cv', FILE_EXISTS_RENAME);
  if($field_cv !== NULL){
    if ($field_cv) {
      // upload file to private://cv
      $form_state['values']['field_cv'] = $field_cv;
    }
    else {
      form_set_error('field_cv', t('File could not be uploaded.'));
    }
  } else {
      form_set_error('field_cv', t('No CV was uploaded.'));
  }
}

Спасибо

Прошу прощения, но в этой строчке пропущена точка с запятой
variable_set('mymodule_myfilefid', $file->fid)
variable_set('mymodule_myfilefid', $file->fid);

Есть великолепный модуль (https://www.drupal.org/project/plupload) для загрузки файлов.
На D.org отлично описано как добавить поле в свою форму https://www.drupal.org/node/1647890

$form['my_element'] = array(
 '#type' => 'plupload',
 '#title' => t('Upload files'),
 '#description' => t('This multi-upload widget uses Plupload library.'),
 '#upload_validators' => array(
 'file_validate_extensions' => array('jpg jpeg gif png txt doc xls pdf ppt pps odt ods odp'),
 'my_custom_file_validator' => array('some validation criteria'),
  ),
 '#plupload_settings' => array(
 'runtimes' => 'html5',
 'chunk_size' => '1mb',
  ),
);

Но не одного примера дальнейшей обработки файлов (фото).
Может подскажите правильный способ обработки этого поля в форме чтобы фото загруженные отображались как картинки, а виджет был готов для повторной загрузки.
По умолчанию никаких перезагрузок формы не происходит, а файлы списком в виджете.

Исправь ошибку здесь

$old_file = file_load($form_state['values']['file']);

должно быть
$old_file = file_load($old_file_fid);

ведь мы все таки удаляем старый файл

Оставить комментарий

Содержимое этого поля является приватным и не будет отображаться публично. Если у вас есть аккаунт в Gravatar, привязанный к этому e-mail адресу, то он будет использован для отображения аватара.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Доступные HTML теги: <a> <i> <b> <strong> <code> <ul> <ol> <li> <blockquote> <em> <s>
  • Строки и параграфы переносятся автоматически.
  • Подсветка кода осуществляется с помощью тегов: <code>, <css>, <html>, <ini>, <javascript>, <sql>, <php>. Поддерживаемые стили выделения кода: <foo>, [foo].

Подробнее о форматировании