The main problem is that you're not loading the form in Drupal way in the AJAX requests. When you use the normal jQuery ajax to load the form, then the necessary actions(Generating new scripts and re-attaching the behaviors) won't happen.
So you should follow the below process to achieve it.
- Create a page with ajax Link/button - clicking on it should load the form(This
may change based on your need)
- Create form generation callback
- Create a ajax callback which will returns the form
Below is the complete example module which loads the form with the managed file field using ajax.
<?php
/**
* @file
* Provides File module pages for testing purposes.
*/
/**
* Implements hook_menu().
*/
function test_menu() {
$items = array();
$items['file/test'] = array(
'title' => 'Managed file test',
'page callback' => 'drupal_get_form',
'page arguments' => array('test_form'),
'access arguments' => array('access content'),
);
$items['ajax/test'] = array(
'title' => 'Managed file test',
'page callback' => 'file_ajax_page',
'access arguments' => array('access content'),
);
$items['ajax/form'] = array(
'title' => 'Managed file test',
'page callback' => 'file_ajax_form',
'access arguments' => array('access content'),
);
return $items;
}
/**
* Generates the Test page.
*/
function file_ajax_page() {
// Make sure Drupal Ajax framework javascript is around.
drupal_add_library('system', 'drupal.ajax');
$output = '';
// Generate a Ajax Link to load the form.
$output .= l(t('Delete'), 'ajax/form', array('attributes' => array('class' => 'use-ajax')));
// Specify the container for the form.
$output .= '<div class="form-container"></div>';
return $output;
}
/**
* Returns the processed file form.
*/
function file_ajax_form() {
$commands = array();
// Treat them in Drupal way to load the form in AJAX, so that all the necessary scripts will be loaded.
$commands[] = ajax_command_html('.form-container', drupal_render(drupal_get_form('test_form')));
ajax_deliver( array(
'#type' => 'ajax',
'#commands' => $commands,
));
}
/**
* Form constructor for testing a 'managed_file' element.
*
* @see file_module_test_form_submit()
* @ingroup forms
*/
function test_form($form, &$form_state, $tree = TRUE, $extended = FALSE, $default_fid = NULL) {
$form['#tree'] = (bool) $tree;
$form['nested']['file'] = array(
'#type' => 'managed_file',
'#title' => t('Managed file'),
'#upload_location' => 'public://test',
'#progress_message' => t('Please wait...'),
'#extended' => (bool) $extended,
'#size' => 13,
);
if ($default_fid) {
$form['nested']['file']['#default_value'] = $extended ? array('fid' => $default_fid) : $default_fid;
}
$form['textfield'] = array(
'#type' => 'textfield',
'#title' => t('Type a value and ensure it stays'),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
);
return $form;
}
/**
* Form submission handler for file_module_test_form().
*/
function test_form_submit($form, &$form_state) {
if ($form['#tree']) {
$fid = $form['nested']['file']['#extended'] ? $form_state['values']['nested']['file']['fid'] : $form_state['values']['nested']['file'];
}
else {
$fid = $form['nested']['file']['#extended'] ? $form_state['values']['file']['fid'] : $form_state['values']['file'];
}
drupal_set_message(t('The file id is %fid.', array('%fid' => $fid)));
}
This way Drupal will do all the works for you if you specify what/how do you want:)
I took File Test module in the core as the base for this example.