View source  
  <?php
function ajax_preprocess_page(&$variables) {
  $p = drupal_get_path('module', 'ajax');
  drupal_add_js($p . '/jquery/jquery.a_form.packed.js', 'module');
  drupal_add_js($p . '/ajax.js', 'module');
  $scripts = drupal_add_js();
  $variables['scripts'] = drupal_get_js('header', $scripts);
  return TRUE;
}
function ajax_form_alter(&$form, $form_state, $form_id) {
  ajax_form_configure($form, $form_state, $form_id);
  if (ajax_is_enabled($form) && !$form['#programmed']) {
    $found = array(
      'submitter' => FALSE,
    );
    ajax_invoke_alter($form, $form_state, $form_id);
    ajax_validator_set($form);
    ajax_submitter_find($form, $found);
    ajax_submitter_set($form, $found);
  }
  return TRUE;
}
function ajax_form_configure(&$form, $form_state, $form_id) {
  if ($form_id === 'node_configure') {
    $form['node_preview']['#description'] .= " " . "<span style='color:#F00;'>" . t('Setting this option to "Required" will conflict with Ajax ' . 'form submissions. ') . "</span>";
  }
  return TRUE;
}
function ajax_is_enabled($form) {
  return array_key_exists('#ajax', $form) && is_array($form['#ajax']) && array_key_exists('enabled', $form['#ajax']) && $form['#ajax']['enabled'] === TRUE;
}
function ajax_drupal_path($val) {
  $b = base_path();
  $bs = sizeof($b);
  if (substr($val, 0, $bs) === $b) {
    return substr($val, $bs);
  }
  else {
    return $val;
  }
}
function ajax_path_info($val) {
  $out = array(
    'path' => NULL,
    'query' => array(),
    'fragment' => NULL,
  );
  $u = parse_url($val);
  if (array_key_exists('query', $u)) {
    parse_str($u, $out['query']);
  }
  if (array_key_exists('path', $u)) {
    $out['path'] = $u['path'];
  }
  if (array_key_exists('fragment', $u)) {
    $out['fragment'] = $u['fragment'];
  }
  return $out;
}
function ajax_validator_set(&$form) {
  $form['#validate'][] = 'ajax_validator';
  if (empty($form['#attributes']['class'])) {
    $form['#attributes']['class'] = 'ajax-form';
  }
  else {
    $form['#attributes']['class'] .= ' ajax-form';
  }
  return TRUE;
}
function ajax_submitter_set(&$form, $found) {
  if (!isset($_POST['drupal_ajax'])) {
    return;
  }
  if (!$found['submitter']) {
    $form['#submit'][] = 'ajax_submitter';
    if (empty($form['#attributes']['class'])) {
      $form['#attributes']['class'] = 'ajax-form';
    }
    else {
      $form['#attributes']['class'] .= ' ajax-form';
    }
  }
  return TRUE;
}
function ajax_submitter_find(&$form, &$found) {
  foreach ($form as $form_key => $form_val) {
    if (is_array($form[$form_key])) {
      
      if (ajax_is_submitter($form, $form_key)) {
        $form[$form_key]['#attributes']['class'] = 'ajax-trigger';
        if (array_key_exists('#submit', $form[$form_key]) && !empty($form[$form_key]['#submit'])) {
          $form[$form_key]['#submit'][] = 'ajax_submitter';
          $found['submitter'] = TRUE;
        }
      }
      else {
        ajax_submitter_find($form[$form_key], $found);
      }
    }
  }
  return TRUE;
}
function ajax_is_submitter($form, $form_key) {
  $is = FALSE;
  if (array_key_exists('#type', $form[$form_key])) {
    if ($form[$form_key]['#type'] === 'submit' || $form[$form_key]['#type'] === 'button') {
      if ($form_key === 'submit' || $form_key === 'preview') {
        $is = TRUE;
      }
      elseif (array_key_exists('#ajax', $form[$form_key])) {
        if (array_key_exists('submitter', $form[$form_key]['#ajax'])) {
          if ($form[$form_key]['#ajax']['submitter'] === TRUE) {
            $is = TRUE;
          }
        }
      }
    }
  }
  return $is;
}
function ajax_get_redirect($redirect) {
  
  
  $args = array();
  $args['absolute'] = TRUE;
  if (is_array($redirect)) {
    if ($redirect[1] !== NULL) {
      $args['query'] = $redirect[1];
    }
    if ($redirect[2] !== NULL) {
      $args['fragment'] = $redirect[2];
    }
    $path = $redirect[0];
  }
  else {
    $path = $redirect;
  }
  $n = url($path, $args);
  $u = ajax_get_url($n);
  $u['query'][mt_rand()] = 1;
  $u['fragment'] = NULL;
  $out = ajax_build_url($u);
  return $out;
}
function ajax_build_url($u) {
  $out = '';
  if (!empty($u['scheme'])) {
    $out .= $u['scheme'];
  }
  else {
    $out .= 'http';
  }
  $out .= '://';
  if (!empty($u['user'])) {
    $out .= $u['user'];
    if (!empty($u['pass'])) {
      $out .= ':';
      $out .= $u['pass'];
    }
    $out .= '@';
  }
  $out .= $u['host'];
  if (!empty($u['port'])) {
    $out .= ':' . $u['port'];
  }
  $out .= $u['path'];
  if (!empty($u['query'])) {
    $out .= '?';
    $out .= drupal_query_string_encode($u['query']);
  }
  if (!empty($u['fragment'])) {
    $out .= '#';
    $out .= $u['fragment'];
  }
  return $out;
}
function ajax_get_url($url) {
  $p = parse_url($url);
  if (!empty($p['query'])) {
    parse_str($p['query'], $q);
    $p['query'] = $q;
  }
  else {
    $p['query'] = array();
  }
  return $p;
}
function ajax_submitter(&$form, &$form_state) {
  $messages = drupal_get_messages(NULL, TRUE);
  $data = array(
    'form_id' => $form_state['values']['form_id'],
    'options' => $form['#ajax'],
  );
  
  if (array_key_exists('node_preview', $form_state) && !empty($form_state['node_preview'])) {
    $data['preview'] = $form_state['node_preview'];
  }
  
  if (array_key_exists('redirect', $form_state) && !empty($form_state['redirect'])) {
    $data['redirect'] = $form_state['redirect'];
  }
  
  if (array_key_exists('redirect', $form) && !empty($form_state['redirect'])) {
    $data['redirect'] = $form['redirect'];
  }
  
  if (array_key_exists('status', $messages)) {
    $data['messages_status'] = $messages['status'];
  }
  
  if (array_key_exists('warning', $messages)) {
    $data['messages_warning'] = $messages['warning'];
  }
  $out = ajax_build($data);
  ajax_out($out);
  return TRUE;
}
function ajax_invoke_validate_pass(&$form, &$form_state, &$data, &$pass) {
  $hook = 'ajax_validate_pass';
  foreach (module_implements($hook) as $name) {
    $function = $name . '_' . $hook;
    $result = $function($form, $form_state, $data, $pass);
  }
  return TRUE;
}
function ajax_invoke_validate_fail(&$form, &$form_state, &$data) {
  $hook = 'ajax_validate_fail';
  foreach (module_implements($hook) as $name) {
    $function = $name . '_' . $hook;
    $result = $function($form, $form_state, $data);
  }
  return TRUE;
}
function ajax_invoke_alter(&$form, &$form_state, $form_id) {
  $hook = 'ajax_alter';
  foreach (module_implements($hook) as $name) {
    $function = $name . '_' . $hook;
    $result = $function($form, $form_state, $form_id);
  }
  return TRUE;
}
function ajax_validator(&$form, &$form_state) {
  if (array_key_exists('drupal_ajax', $_REQUEST)) {
    drupal_get_messages(NULL, TRUE);
    $data = ajax_build(array(
      'messages_error' => form_get_errors(),
      'form_id' => $form_state['values']['form_id'],
      'options' => $form['#ajax'],
    ));
    
    if (!$data['status']) {
      ajax_invoke_validate_fail($form, $form_state, $data);
      ajax_out($data);
    }
    else {
      $pass = TRUE;
      ajax_invoke_validate_pass($form, $form_state, $data, $pass);
      if (!$pass) {
        ajax_out($data);
      }
    }
  }
  return TRUE;
}
function ajax_out($data) {
  $buffer_len = ob_get_length();
  if ($buffer_len !== FALSE && $buffer_len > 0) {
    ob_clean();
  }
  header('HTTP/1.1 200 OK', TRUE);
  if (!array_key_exists('HTTP_X_REQUESTED_WITH', $_SERVER) && $_SERVER['HTTP_X_REQUESTED_WITH'] !== 'XMLHttpRequest') {
    drupal_set_header('Content-Type: text/html; Charset=UTF-8');
    print "<textarea>";
    print drupal_to_js($data);
    print "</textarea>\n";
  }
  else {
    drupal_set_header('Content-Type: text/javascript; Charset=UTF-8');
    print drupal_to_js($data);
  }
  exit;
}
function ajax_clean_id($field_id) {
  return str_replace(array(
    '][',
    '_',
    ' ',
  ), '-', $field_id);
}
function ajax_build($data) {
  $out = array(
    'status' => true,
    'updaters' => array(),
    'debug' => array(),
    'messages_error' => array(),
    'messages_status' => array(),
    'messages_warning' => array(),
    'redirect' => NULL,
    'preview' => NULL,
    'form_id' => NULL,
    'options' => array(),
  );
  
  if (array_key_exists('messages_error', $data) && $data['messages_error'] !== NULL) {
    $out['status'] = FALSE;
    foreach ($data['messages_error'] as $k => $v) {
      $out['messages_error'][] = array(
        'id' => ajax_clean_id("edit-" . $k),
        'value' => $v,
      );
    }
  }
  
  if (array_key_exists('messages_status', $data) && $data['messages_status'] !== NULL) {
    foreach ($data['messages_status'] as $k => $v) {
      $out['messages_status'][] = array(
        'id' => (int) $k,
        'value' => $v,
      );
    }
  }
  
  if (array_key_exists('messages_warning', $data) && $data['messages_warning'] !== null) {
    foreach ($data['messages_warning'] as $k => $v) {
      $out['messages_warning'][] = array(
        'id' => (int) $k,
        'value' => $v,
      );
    }
  }
  
  if (array_key_exists('destination', $_GET)) {
    $out['redirect'] = ajax_get_redirect($_GET['destination']);
  }
  elseif (array_key_exists('redirect', $data) && $data['redirect'] !== NULL) {
    $out['redirect'] = ajax_get_redirect($data['redirect']);
  }
  
  if (array_key_exists('preview', $data) && $data['preview'] !== NULL) {
    $out['preview'] = rawurlencode($data['preview']);
  }
  
  if (array_key_exists('debug', $data) && $data['debug'] !== NULL) {
    $out['debug'] = $data['debug'];
  }
  
  if (array_key_exists('form_id', $data) && $data['form_id'] !== NULL) {
    $out['form_id'] = $data['form_id'];
  }
  
  if (array_key_exists('options', $data) && $data['options'] !== NULL) {
    $out['options'] = $data['options'];
  }
  return $out;
}