Index: modules/poll/poll.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/poll/poll.module,v
retrieving revision 1.234
diff -u -r1.234 poll.module
--- modules/poll/poll.module 1 Jul 2007 17:41:16 -0000 1.234
+++ modules/poll/poll.module 9 Jul 2007 17:02:30 -0000
@@ -101,12 +101,9 @@
*/
function poll_node_form_submit(&$form, &$form_state) {
// Renumber fields
- $form_state['values']['choice'] = array_values($form_state['values']['choice']);
+ $form_state['values']['choices'] = array_values($form_state['values']['choices']);
$form_state['values']['teaser'] = poll_teaser((object)$form_state['values']);
$form_state['choices'] = $form_state['values']['choices'];
- if ($form_state['values']['morechoices']) {
- $form_state['choices'] *= 2;
- }
}
/**
@@ -117,18 +114,18 @@
// Check for at least two options and validate amount of votes:
$realchoices = 0;
// Renumber fields
- $node->choice = array_values($node->choice);
- foreach ($node->choice as $i => $choice) {
+ $node->choices = array_values($node->choices);
+ foreach ($node->choices as $i => $choice) {
if ($choice['chtext'] != '') {
$realchoices++;
}
if ($choice['chvotes'] < 0) {
- form_set_error("choice][$i][chvotes", t('Negative values are not allowed.'));
+ form_set_error("choices][$i][chvotes", t('Negative values are not allowed.'));
}
}
if ($realchoices < 2) {
- form_set_error("choice][$realchoices][chtext", t('You must fill in at least two choices.'));
+ form_set_error("choices][$realchoices][chtext", t('You must fill in at least two choices.'));
}
}
}
@@ -139,6 +136,11 @@
function poll_form(&$node, $form_state) {
$admin = user_access('administer nodes');
$type = node_get_types('type', $node);
+
+ $form = array(
+ '#cache' => TRUE,
+ );
+
$form['title'] = array(
'#type' => 'textfield',
'#title' => check_plain($type->title_label),
@@ -147,56 +149,48 @@
'#weight' => -1
);
- if (isset($form_state['choices'])) {
- $choices = $form_state['choices'];
+ if (isset($form_state['choice_count'])) {
+ $choice_count = $form_state['choice_count'];
}
else {
- $choices = max(2, empty($node->choice) ? 5 : count($node->choice));
+ $choice_count = max(2, empty($node->choices) ? 5 : count($node->choices));
}
- $form['choices'] = array(
- '#type' => 'hidden',
- '#value' => $choices,
- );
-
- // Poll choices
- $form['choice'] = array(
+ // Add a wrapper for the choices and more button.
+ $form['choice_wrapper'] = array(
'#type' => 'fieldset',
'#title' => t('Choices'),
- '#prefix' => '
',
- '#suffix' => '
',
- '#tree' => TRUE
+ '#tree' => FALSE,
);
- // We'll manually set the #parents property of this checkbox so that
- // it appears in the fieldset visually, but its value won't pollute
- // the $form_state['values']['choice'] array.
- $form['choice']['morechoices'] = array(
- '#type' => 'checkbox',
- '#parents' => array('morechoices'),
- '#title' => t('Need more choices'),
- '#default_value' => 0,
- '#description' => t("If the amount of boxes above isn't enough, check this box and click the Preview button below to add some more."),
- '#weight' => 1,
+ // Container for just the poll choices.
+ $form['choice_wrapper']['choices'] = array(
+ '#prefix' => '',
+ '#suffix' => '
',
);
- for ($a = 0; $a < $choices; $a++) {
- $form['choice'][$a]['chtext'] = array(
- '#type' => 'textfield',
- '#title' => t('Choice @n', array('@n' => ($a + 1))),
- '#default_value' => isset($node->choice[$a]) ? $node->choice[$a]['chtext'] : '',
- );
-
- if ($admin) {
- $form['choice'][$a]['chvotes'] = array(
- '#type' => 'textfield',
- '#title' => t('Votes for choice @n', array('@n' => ($a + 1))),
- '#default_value' => isset($node->choice[$a]) ? (int)$node->choice[$a]['chvotes'] : 0,
- '#size' => 5, '#maxlength' => 7
- );
- }
+ // Add the current choices to the form.
+ for ($delta = 0; $delta < $choice_count; $delta++) {
+ $text = isset($node->choices[$delta]['chtext']) ? $node->choices[$delta]['chtext'] : '';
+ $votes = isset($node->choices[$delta]['chvotes']) ? $node->choices[$delta]['chvotes'] : '';
+
+ $form['choice_wrapper']['choices'][$delta] = _poll_choice_form($delta, $text, $votes);
}
+ // We name our button 'poll_more' to avoid conflicts with other modules with
+ // buttons with the id 'more'.
+ $form['choice_wrapper']['poll_more'] = array(
+ '#type' => 'submit',
+ '#value' => t('Add another choice'),
+ '#description' => t("If the amount of boxes above isn't enough, click here to add more choices."),
+ '#weight' => 1,
+ '#submit' => array('poll_more_choices_submit'), // If no javascript action.
+ '#ahah_path' => 'poll/js',
+ '#ahah_wrapper' => 'poll-choices',
+ '#ahah_method' => 'append',
+ '#ahah_effect' => 'slide',
+ );
+
// Poll attributes
$_duration = array(0 => t('Unlimited')) + drupal_map_assoc(array(86400, 172800, 345600, 604800, 1209600, 2419200, 4838400, 9676800, 31536000), "format_interval");
$_active = array(0 => t('Closed'), 1 => t('Active'));
@@ -223,18 +217,95 @@
return $form;
}
+/**
+ * Submit handler to add more choices to a poll form. This handler is used when
+ * javascript is not available. It makes changes to the form state and the
+ * entire form is rebuilt during the page reload.
+ */
+function poll_more_choices_submit($form, &$form_state) {
+ // Set rebuild to true to make Drupal re-render the form with our changes.
+ $form_state['rebuild'] = TRUE;
+
+ // Make the changes we want to the form state.
+ $form_state['node'] = $form_state['values'];
+ if ($form_state['values']['poll_more']) {
+ $form_state['choice_count'] = count($form_state['values']['choices']) + 5;
+ }
+}
+
+function _poll_choice_form($delta, $value = NULL, $votes = NULL) {
+ $admin = user_access('administer nodes');
+
+ $form = array(
+ '#tree' => TRUE,
+ );
+
+ // We'll manually set the #parents property of these fields so that
+ // their values appear in the $form_state['values']['choices'] array.
+ $form['chtext'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Choice @n', array('@n' => ($delta + 1))),
+ '#default_value' => isset($value) ? $value : '',
+ '#parents' => array('choices', $delta,'chtext'),
+ );
+
+ if ($admin) {
+ $form['chvotes'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Votes for choice @n', array('@n' => ($delta + 1))),
+ '#default_value' => $votes ? $votes : 0,
+ '#size' => 5,
+ '#maxlength' => 7,
+ '#parents' => array('choices', $delta, 'chvotes'),
+ );
+ }
+
+ return $form;
+}
+
+/**
+ * Menu callback for AHAH additions.
+ */
+function poll_choice_js() {
+ $delta = count($_POST['choices']);
+
+ // Build our new form element.
+ $form_element = _poll_choice_form($delta);
+ drupal_alter('form', $form_element, array(), 'poll_choice_js');
+
+ // Add the new element to the stored form state. Without adding the element
+ // to the form, Drupal is not aware of this new elements existence and will
+ // not process it. We retreive the cached form, add the element, and resave.
+ $form = cache_get('form_'. $_POST['form_build_id'], 'cache_form');
+ $form->data['choice_wrapper']['choices'][$delta] = $form_element;
+ cache_set('form_'. $_POST['form_build_id'], $form->data, 'cache_form');
+
+ // Render the new output.
+ $form_state = array('submitted' => FALSE);
+ $form_element += array(
+ '#post' => $_POST,
+ '#programmed' => FALSE,
+ );
+ $form_element = form_builder('poll_choice_js', $form_element, $form_state);
+ $output = theme('status_messages') . drupal_render($form_element);
+
+ // Return the new output.
+ print drupal_to_js(array('status' => TRUE, 'data' => $output));
+ exit;
+}
+
function poll_insert($node) {
if (!user_access('administer nodes')) {
// Make sure all votes are 0 initially
- foreach ($node->choice as $i => $choice) {
- $node->choice[$i]['chvotes'] = 0;
+ foreach ($node->choices as $i => $choice) {
+ $node->choices[$i]['chvotes'] = 0;
}
$node->active = 1;
}
db_query("INSERT INTO {poll} (nid, runtime, active) VALUES (%d, %d, %d)", $node->nid, $node->runtime, $node->active);
- foreach ($node->choice as $choice) {
+ foreach ($node->choices as $choice) {
if ($choice['chtext'] != '') {
db_query("INSERT INTO {poll_choices} (nid, chtext, chvotes, chorder) VALUES (%d, '%s', %d, %d)", $node->nid, $choice['chtext'], $choice['chvotes'], $i++);
}
@@ -256,6 +327,13 @@
'type' => MENU_SUGGESTED_ITEM,
);
+ $items['poll/js'] = array(
+ 'title' => 'Javascript Choice Form',
+ 'page callback' => 'poll_choice_js',
+ 'access arguments' => array('access content'),
+ 'type' => MENU_CALLBACK,
+ );
+
$items['poll/cancel/%node'] = array(
'title' => 'Cancel',
'page callback' => 'poll_cancel',
@@ -297,7 +375,7 @@
$result = db_query("SELECT chtext, chvotes, chorder FROM {poll_choices} WHERE nid = %d ORDER BY chorder", $node->nid);
while ($choice = db_fetch_array($result)) {
- $poll->choice[$choice['chorder']] = $choice;
+ $poll->choices[$choice['chorder']] = $choice;
}
// Determine whether or not this user is allowed to vote
@@ -361,8 +439,8 @@
*/
function poll_teaser($node) {
$teaser = NULL;
- if (is_array($node->choice)) {
- foreach ($node->choice as $k => $choice) {
+ if (is_array($node->choices)) {
+ foreach ($node->choices as $k => $choice) {
$teaser .= '* '. $choice['chtext'] .'\n';
}
}
@@ -372,10 +450,10 @@
/**
* Generates the voting form for a poll.
*/
-function poll_view_voting($node, $block) {
- if ($node->choice) {
+function poll_view_voting($form_state, $node, $block) {
+ if ($node->choices) {
$list = array();
- foreach ($node->choice as $i => $choice) {
+ foreach ($node->choices as $i => $choice) {
$list[$i] = check_plain($choice['chtext']);
}
$form['choice'] = array(
@@ -395,6 +473,7 @@
* Themes the voting form for a poll.
*/
function theme_poll_view_voting($form) {
+ $output = '';
$output .= '