Index: advpoll.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/advpoll/advpoll.module,v
retrieving revision 1.44
diff -u -p -r1.44 advpoll.module
--- advpoll.module	28 Nov 2006 06:54:15 -0000	1.44
+++ advpoll.module	28 Nov 2006 16:20:24 -0000
@@ -1020,12 +1020,13 @@ function advpoll_view($node, $teaser = F
         $node, $teaser, $page, $block)
       //. advpoll_view_electoral_list($node, $teaser),
     );
+  // Add javascript for posting voting forms with ajax
+  drupal_add_js(drupal_get_path('module', 'advpoll') .'/jquery.form.js', 'module');
   }
-  else if (_advpoll_can_view_results($node)) {
+  else {
     // Show results only if the user has voted or poll is closed
     $node->content['body'] = array(
       '#value' => advpoll_view_results($node, $teaser, $page, $block)
-        //. advpoll_view_electoral_list($node, $teaser),
     );  
   }
 
@@ -1086,14 +1087,20 @@ function theme_advpoll_results($title, $
     $output .= '<div class="poll">';
     $output .= $results;
     $output .= '<div class="total">'. t('Total votes: %votes', array('%votes' => $votes)) .'</div>';
-    if ($voted && $cancel_vote && user_access('cancel own vote') && !$block) {
-      $output .= drupal_get_form('advpoll_cancel_form', $nid);
-    }
     $output .= '</div>';
   }
   return $output;
 } 
 
+function _advpoll_show_cancel_form($node, $block) {
+  $output = '';
+  if ($node->voted && $node->cancel_vote && user_access('cancel own vote')
+    && !$block) {
+    $output .= drupal_get_form('advpoll_cancel_form', $node->nid);
+  }
+  return $output;
+}
+
 function theme_advpoll_bar($title, $percentage, $votes, $block) {
   if ($block) {
     $output  = '<div class="text">'. $title .'</div>';
@@ -1121,6 +1128,25 @@ function advpoll_results() {
     drupal_not_found();
   }
 }
+
+function _advpoll_register_vote($node, $form_values) {
+  $msg = t('Your vote was registered.');
+  $node->voted = true;
+  $node->cancel_vote = true;
+  // Ajax response
+  if ($form_values['ajax']) {
+    $ajax_output = '<div class="messages status">'. $msg .'</div>';
+    $ajax_output .= advpoll_view_results($node, NULL, NULL, NULL);
+    $ajax_output = str_replace("\n", '', $ajax_output);
+    print drupal_to_js(array('response' => $ajax_output));
+    exit();
+  }
+  // Usual response
+  else {
+    drupal_set_message($msg);
+  }
+}
+
 /**
  * Show results of the vote
  *
@@ -1130,13 +1156,17 @@ function advpoll_results() {
  */
 function advpoll_view_results(&$node, $teaser, $page, $block) {
   $mode = _advpoll_get_mode($node);
-  if (function_exists("advpoll_view_results_$mode")) {
-    $output =  call_user_func("advpoll_view_results_$mode", $node,
-      $teaser, $page, $block);
-    return theme('advpoll_results', check_plain($node->title),
-      $output['results'], $output['votes'], $node->links, $block, $node->nid,
-      $node->voted, $node->cancel_vote);
+  if (_advpoll_can_view_results($node)) {
+    if (function_exists("advpoll_view_results_$mode")) {
+      $results = call_user_func("advpoll_view_results_$mode", $node,
+        $teaser, $page, $block);
+      $output .= theme('advpoll_results', check_plain($node->title),
+        $results['results'], $results['votes'], $node->links, $block,
+        $node->nid, $node->voted, $node->cancel_vote);
+    }
   }
+  $output .= _advpoll_show_cancel_form($node, $block);
+  return $output;
 }
 
 /**
Index: modes/binary.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/advpoll/modes/binary.inc,v
retrieving revision 1.12
diff -u -p -r1.12 binary.inc
--- modes/binary.inc	16 Nov 2006 21:22:21 -0000	1.12
+++ modes/binary.inc	28 Nov 2006 16:20:24 -0000
@@ -17,6 +17,8 @@ function advpoll_algorithms_binary() {
  * This creates a list of choices to allow the user to vote on choices.
  */
 function advpoll_voting_binary_form(&$node, $teaser, $page, $block) {
+  $form['#attributes'] = array('class' => 'advpoll-vote');
+  
   if ($node->choice) {
     $list = array();
     foreach ($node->choice as $i => $choice) {
@@ -138,7 +140,7 @@ function advpoll_voting_binary_form_subm
   }
 
   votingapi_set_vote('advpoll', $form_values['nid'], $vote);
-  drupal_set_message(t('Your vote was registered.'));
+  _advpoll_register_vote($node, $_POST);
 }
 
 /**
@@ -149,10 +151,17 @@ function advpoll_voting_binary_form_subm
 function advpoll_voting_binary_form_validate($form_id, $form_values) {
   $ok = true;
   $node = node_load($form_values['nid']);
+  $ajax = $_POST['ajax'];
   if ($node->maxchoices == 1) {
     // plurality voting
     if (!($ok = array_key_exists($form_values['choice'], $node->choice))) {
-      form_set_error('choice[', 'At least one choice must be selected.');
+      $msg = t('At least one choice must be selected.');
+      if ($ajax) {
+        $errors[] = $msg;
+      }
+      else {
+        form_set_error('choice[', $msg);
+      }
       $ok = false;
     }
   }
@@ -170,19 +179,38 @@ function advpoll_voting_binary_form_vali
   
     // too many choices ranked
     if ($node->maxchoices != 0 && $numchoices > $node->maxchoices) {
-      form_set_error('choice[',
-        t('%num choices were selected but only %max are allowed.',
-          array('%num' => $numchoices, '%max' => $node->maxchoices)));
+      $msg = t('%num choices were selected but only %max are allowed.',
+        array('%num' => $numchoices, '%max' => $node->maxchoices));
+      if ($ajax) {
+        $errors[] = $msg;
+      }
+      else {
+        form_set_error('choice[', $msg);
+      }
       $ok = false;
     }
 
     // not enough choices ranked
     $minchoices = 1;
     if ($numchoices < $minchoices) {
-      form_set_error('choice[', t('At least one choice must be selected.'));
+      $msg = t('At least one choice must be selected.');
+      if ($ajax) {
+        $errors[] = $msg;
+      }
+      else {
+        form_set_error('choice[', $msg);
+      }
       $ok = false;
     }
   }
-  return $ok;
+  // If the form was posted with AJAX and has errors, print the error message.
+  if ($ajax && !$ok) {
+    print drupal_to_js(array('response' => '<div class="messages error">'. implode('<br />', $errors) .'</div>', 'error' => TRUE));
+    exit;
+  }
+  // Do as usual.
+  else {
+    return $ok;
+  }
 }
 
Index: modes/ranking.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/advpoll/modes/ranking.inc,v
retrieving revision 1.13
diff -u -p -r1.13 ranking.inc
--- modes/ranking.inc	14 Nov 2006 07:00:58 -0000	1.13
+++ modes/ranking.inc	28 Nov 2006 16:20:25 -0000
@@ -16,10 +16,11 @@ function advpoll_algorithms_ranking() {
 }
 
 function advpoll_voting_ranking_form(&$node, $teaser, $page, $block) {
-
   $weight = 0;
   $form = array();
 
+  $form['#attributes'] = array('class' => 'advpoll-vote');
+
   if ($node->choice) {
     $list = array();
 
@@ -565,6 +566,8 @@ function advpoll_voting_ranking_form_sub
   }
 
   votingapi_set_vote('advpoll', $form_values['nid'], $vote);
+  $node = node_load($form_values['nid']);
+  _advpoll_register_vote($node, $_POST);
 }
 
 /**
@@ -577,6 +580,7 @@ function advpoll_voting_ranking_form_sub
  */
 function advpoll_voting_ranking_form_validate($form_id, $form_values) {
   $node = node_load($form_values['nid']);
+  $ajax = $_POST['ajax'];
 
   $ok = TRUE;
   // array used to check which values are set
@@ -595,36 +599,65 @@ function advpoll_voting_ranking_form_val
     // check range
     if ($intvalue > count($node->choice) || $intvalue < 0) {
       // TODO: clean up this error message
-      form_set_error('choice][' . $key,
-        "Illegal rank for choice $key: $intvalue (min: 1, max: "
-        . count($node->choice) . ')');
+      $msg = "Illegal rank for choice $key: $intvalue (min: 1, max: "
+        . count($node->choice) . ')';
+      if ($ajax) {
+        $errors[] = $msg;
+      }
+      else {
+        form_set_error('choice][' . $key, $msg);
+      }
       $ok = FALSE;
     }
   }
   
   // too many choices ranked
   if ($node->maxchoices != 0 && $numchoices > $node->maxchoices) {
-    form_set_error('choice',
-      t('%num choices were selected but only %max are allowed.',
-        array('%num' => $numchoices, '%max' => $node->maxchoices)));
+    $msg = t('%num choices were selected but only %max are allowed.',
+        array('%num' => $numchoices, '%max' => $node->maxchoices));
+    if ($ajax) {
+      $errors[] = $msg;
+    }
+    else {
+      form_set_error('choice', $msg);
+    }
     $ok = false;
   }
 
   // not enough choices ranked
   $minchoices = 1;
   if ($numchoices < $minchoices) {
-    form_set_error('choice', t('At least one choice must be selected.'));
+    $msg = t('At least one choice must be selected.');
+    if ($ajax) {
+      $errors[] = $msg;
+    }
+    else {
+      form_set_error('choice', $msg);
+    }
     $ok = false;
   }
 
   // Check that multiple choices are not set to the same value
   foreach ($setvalues as $val => $count) {
     if ($val != 0 && $count > 1) {
-      form_set_error('choice',
-        t('Multiple choices given the rank of %val.', array('%val' => $val)));
+      $msg = t('Multiple choices given the rank of %val.', array('%val' => $val));
+      if ($ajax) {
+        $errors[] = $msg;
+      }
+      else {
+        form_set_error('choice', $msg);
+      }
+    
       $ok = false;
     }
   }
-
-  return $ok;
+  // If the form was posted with AJAX and has errors, print the error message.
+  if ($ajax && !$ok) {
+    print drupal_to_js(array('response' => '<div class="messages error">'. implode('<br />', $errors) .'</div>', 'error' => TRUE));
+    exit;
+  }
+  // Do as usual.
+  else {
+    return $ok;
+  }
 }
