How to pass dynamic file location in Form API? 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' =&gt; 'textfield',
      '#title' =&gt; t('Folder Name'),
  );
  $form['document'] = array(
    '#type' =&gt; 'managed_file',
    '#upload_validators' =&gt; array('file_validate_extensions' =&gt; array('xml')),
    '#upload_location' =&gt; 'public://',
    '#submit' =&gt; array('custom_document_submit'),
    );
function custom_document_submit($form, &amp;$form_state){
  $destination = $form_state['values']['folder_name'];
  $validators = array();
  $file = file_save_upload('document', $validators, 'public://'.$destination);
}
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, &amp;$form_state) {
  $input = &amp;$form_state['input'];
  $values = &amp;$form_state['values'];

  $form['folder_name'] = array(
    '#type' =&gt; 'textfield',
    '#title' =&gt; t('Folder Name'),
    '#submit' =&gt; array('mymodule_custom_form_folder_name_submit'),
    '#ajax' =&gt; array(
      'callback' =&gt; 'mymodule_custom_form_folder_name_ajax',
      'wrapper' =&gt; 'edit-file-ajax-wrapper',
      'event' =&gt; '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']) &amp;&amp; !empty($input['folder_name'])) {
    $values['folder_name'] = form_type_textfield_value($form['folder_name'], $input['folder_name']);
  }

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

function mymodule_custom_form_folder_name_submit(&amp;$form, &amp;$form_state) {
  unset($form['file']['#disabled']);
  $form_state['rebuild'] = TRUE;
}

function mymodule_custom_form_folder_name_ajax(&amp;$form, &amp;$form_state) {
  return $form['file'];
}