It seems, I found some solution, may be not fully drupal-way.
Firstly, we need to load JS libraries, needed for working of ajax submit. This code helps us:
drupal_add_library('system', 'drupal.ajax');
drupal_add_library('system', 'drupal.form');
drupal_add_library('system', 'jquery.form');
drupal_add_library('system', 'druapl.progress');
drupal_add_library('system', 'drupal.textarea');
Nextly, we need to fill JS class Drupal.settings.ajax with data about page elements, which provides ajax behavior. I have not an universal solution, I only stops JS code on breakpoint in misc/ajax.js when running it on page with correct working ajax form. You can see correct values in this part of code:
Drupal.behaviors.AJAX = {
attach: function (context, settings) {
// Load all Ajax behaviors specified in the settings.
for (var base in settings.ajax) {
if (!$('#' + base + '.ajax-processed').length) {
var element_settings = settings.ajax[base];
if (typeof element_settings.selector == 'undefined') {
element_settings.selector = '#' + base;
}
$(element_settings.selector).each(function () {
element_settings.element = this;
Drupal.ajax[base] = new Drupal.ajax(base, this, element_settings);
});
$('#' + base).addClass('ajax-processed');
}
}
So, in my case resulting JS code, needed to be added into startup javascript, looks like this:
if(Drupal.settings.ajax == undefined){
Drupal.settings.ajax = {
'edit-submit': {
callback: "faqform_ajaxsubmit",
event: "mousedown",
keypress: true,
prevent: 'key',
submit: {
_triggering_element_name: "op",
_triggering_element_value: "Send"
},
url: 'system/ajax',
wrapper:'submit-message'
}
};
}
If all done correctly, you form, loaded by ajax, will have correct ajax behavior, in my case - ajax submit.
May be there are more graceful solutions, may be diving deeper into code will help you to find them.
So, here is much more graceful solution!
After some analyses of steps, maked above, I decided, that only thing we need to make ajax form, loaded by ajax, to work is fill javascript Drupal.settings array with correct data, describing forb behavior.
In the above example we made it by hands, with hardcode, whitch is not true. Obviously, somewhere in drupal code it work does automatically.
I found this place. It is function ajax_pre_render_element in the ajax.inc. It gives array of any form element with ajax property and appends to it additional parameters, which will be converted to JS code and added to Drupal.settings array later. Exactly thing, that we need.
Here is my code now:
function anyform_block_info()
{
//standart form for displaying to user
$blocks['any_form'] = array(
'info' => t('Any form'),
'status' => true,
'region' => 'content',
'weight' => 99,
'visibility' => 1
);
//hidden 'form' needed to generate and load ajax behavior settings before form loading
$blocks['faq_form_hidden'] = array(
'info' => t('Any fake form'),
'status' => true,
'region' => 'footer', //I thing, it will be better place it in footer^ in my case content is ajaxed
'weight' => 99,
'visibility' => 1
);
return $blocks;
}
function anyform_block_view($delta)
{
switch ($delta) {
case 'faq_form':
$block['content'] = drupal_get_form('anyform'); //standart form
return $block;
case 'faq_form_hidden':
$block['content'] = anyform_get_hidden_form(); //fake form
return $block;
break;
}
}
function anyform_get_hidden_form()
{
$form = drupal_get_form('faqform'); //give our original form
$form = ajax_pre_render_element($form['submit']); //create settings for element with #ajax property (don't pass whole form as argument - not works)
//makes fake form with hidden element in footer, but with correct array with settings for ajax behavior
$fakeform['fakeform'] = array(
'#type'=>'markup',
'#markup'=>'<div style="display: none;"></div>',
'#attached'=>$form['#attached'], //our magical array
);
return $fakeform;
}
So, I hope, it will solve most of your problems with drupal ajax-loaded forms. For me this solution works without any problems, and I going sleep being happy =^_^=
Good luck!