my requirement is to upload files to specific folders. How can I achieve this by using form api. How can I modify below code such that upload_location should be dynamic. Uploaded file should save into the Folder name provided by the user.
I tried below code but not worked.

#submit element is not calling custom_document_submit function.

 $form['folder_name'] = array(
      '#type' => 'textfield',
      '#title' => t('Folder Name'),
  $form['document'] = array(
    '#type' => 'managed_file',
    '#upload_validators' => array('file_validate_extensions' => array('xml')),
    '#upload_location' => 'public://',
    '#submit' => array('custom_document_submit'),
function custom_document_submit($form, &$form_state){
  $destination = $form_state['values']['folder_name'];
  $validators = array();
  $file = file_save_upload('document', $validators, 'public://'.$destination);
  • managed_file does not support #submit
    – Jimmy Ko
    Jul 28, 2016 at 9:14
  • Ohh thank you. May I know how can I achieve that. #upload_location should be dynamic one.
    – Suraj
    Jul 28, 2016 at 9:51
  • How about using Form Ajax to rebuild the form with the updated #upload_location on managed_file?
    – Jimmy Ko
    Jul 28, 2016 at 9:53
  • If its succeed that will be great.. May I know how can I use form ajax in my case?
    – Suraj
    Jul 28, 2016 at 9:55
  • I will answer you, wait.
    – Jimmy Ko
    Jul 28, 2016 at 9:56

1 Answer 1


I would suggest using ajax to update the #upload_location on demand.

However, ajax on managed_file element is quite tricky. Because managed_file has its own ajax handling for uploading file. It only rebuilds the file element itself and returns lack of data from other fields during during file upload ajax. So it need to be fixed in some hacky way

Example code:

function mymodule_custom_form($form, &$form_state) {
  $input = &$form_state['input'];
  $values = &$form_state['values'];

  $form['folder_name'] = array(
    '#type' => 'textfield',
    '#title' => t('Folder Name'),
    '#submit' => array('mymodule_custom_form_folder_name_submit'),
    '#ajax' => array(
      'callback' => 'mymodule_custom_form_folder_name_ajax',
      'wrapper' => 'edit-file-ajax-wrapper',
      'event' => 'keyup',

  // HACK: manually construct the folder_name value.
  // $form_state['values'] is empty for other field in file upload ajax
  // because it only rebuild the element rather then the whole form.
  if (!isset($values['folder_name']) && !empty($input['folder_name'])) {
    $values['folder_name'] = form_type_textfield_value($form['folder_name'], $input['folder_name']);

  $form['file'] = array(
    '#type' => 'managed_file',
    '#title' => 'File',
    '#disabled' => empty($values['folder_name']) && empty($input['folder_name']),
    '#upload_validators' => array('file_validate_extensions' => array('jpg')),
    '#upload_location' => !empty($values['folder_name']) ? 'public://' . $values['folder_name'] : 'public://',

function mymodule_custom_form_folder_name_submit(&$form, &$form_state) {
  $form_state['rebuild'] = TRUE;

function mymodule_custom_form_folder_name_ajax(&$form, &$form_state) {
  return $form['file'];
  • Hi, I am getting disabled file upload on the page. One more thing is I am doing this thing on admin page. So form function I cant use I guess. I have written ur form elements inside mymodule_admin() function.
    – Suraj
    Jul 28, 2016 at 12:37
  • @Suraj Yes, I make it disabled by default. You can remove the #disabled code if you don't want this feature. And, if you are using form API to construct form in admin page. It should work.
    – Jimmy Ko
    Jul 28, 2016 at 13:01
  • Thanks for your information. I am bit new to this thing. How can i use form api in admin page. I know only hting is to display in admin page we have to use mymodule_admin function. Whatever i will write inside this function that will display on admin page. So where can i use form api here.
    – Suraj
    Jul 28, 2016 at 13:19
  • @Suraj You can read Creating a module configuration (settings) page first.
    – Jimmy Ko
    Jul 28, 2016 at 13:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.