I'm trying to add ajax submit to dynamically loaded form in Drupal 7.
I know how to add AJAX functionality to form, loaded with page. But dynamically loaded form have not AJAX functionality. The form loads after clicking on link to separate div. When I click to "save" button, the form works, but page reloads instead of ajax action. What I am doing wrong?
PHP:
function fae_menu() {
$items['fae_edit'] = array(
'title' => t('FAE Edit'),
'page callback' => 'fae_get_node_form',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
return $items;
}
function fae_get_node_form($nid = 0, $field_name = '') {
if (!$nid) {
$nid = $_GET['nid'];
}
if (!$field_name) {
$field_name = $_GET['field_name'];
}
module_load_include('inc', 'node', 'node.pages');
$ret = '';
$node = node_load($nid);
$node->this_field_only = $field_name;
$node->hidesubmit = false;
$form = drupal_get_form($node->type . '_node_form', $node);
$ret.=render($form);
print $ret;
// return $ret; // if I view this form as a separate page AJAX works normally
}
function fae_form_alter(&$form, &$form_state, $form_id) {
module_load_include('inc', 'node', 'node.pages');
if (isset($form['#node']) && $form_id == $form['#node']->type . '_node_form') {
if (!isset($form_state['build_info']['files'])) {
$form_state['build_info']['files'] = array("menu" => "modules/node/node.pages.inc");
}
if (isset($form['#node']->this_field_only) && $form['#node']->this_field_only) {
$excludes = array();
$excludes[] = $form['#node']->this_field_only;
$types_exclude = array('value', 'hidden', 'actions', 'token');
foreach ($form as $key => $val) {
if (strpos($key, '#') !== 0) {
$tounset = true;
foreach ($excludes as $exclude) {
if ($key == $exclude) {
$tounset = false;
}
}
foreach ($types_exclude as $type) {
if ($form[$key]['#type'] == $type) {
$tounset = false;
}
}
if ($tounset) {
// unset($form[$key]);
$form[$key] = array('#language' => NULL); //I use this instead unset to prevent notices from Locale module
}
}
}
$form['#submit'][] = 'fae_node_form_edit_submit';
$form['actions']['submit']['#ajax'] = array(
'callback' => 'fae_ajax_callback',
'effect' => 'fade',
'wrapper' => 'task-node-form',
'event' => 'click',
'progress' => array('message' => '', 'type' => 'throbber'),
);
if (isset($form['#node']->hidesubmit) && $form['#node']->hidesubmit) {
$form['actions']['#attributes']['class'][] = 'element-invisible';
}
}
}
}
function fae_node_form_edit_submit($form, &$form_state) {
$form_state['rebuild'] = TRUE;
// $form_state['redirect'] = FALSE; // I don't know if I need to enable this
}
function fae_ajax_callback($form, $form_state) {
return 'test callback';
}
Javascript:
(function ($) {
Drupal.behaviors.fae = {
attach: function (context, settings) {
$('.fae-editable-original').click(function () {
var nid = $(this).parent().data('nid');
var field = $(this).parent().data('field');
var thisedit = $(this).parent().find('.fae-editable-edit');
$.get('/fae_edit', {
nid: nid,
field_name: field
}).success(function (data) {
//$(thisedit).html(data);
var newform = $(data).appendTo(thisedit);
Drupal.attachBehaviors();
});
});
}
};
})(jQuery);
I figured out a cause of the problem. If we load form via AJAX, we have no ajax and jquery form included on page. So we need to include ajax.js and jquery.form.js to our page if we suppose to have AJAX forms loaded dynamically.
drupal_add_js('misc/ajax.js');
drupal_add_js('misc/jquery.form.js');
Also we need to attach behaviours to new form and process it via jquery.form
Drupal.attachBehaviors('#our-form-id');
$('#our-form-id').ajaxForm();
After this changes our dynamically loaded form works good with AJAX submitting.