How to pass dynamic file location in Form API?
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'];
}