Index: modules/poll/poll.css
===================================================================
RCS file: /cvs/drupal/drupal/modules/poll/poll.css,v
retrieving revision 1.4
diff -u -r1.4 poll.css
--- modules/poll/poll.css 2 Aug 2007 10:46:53 -0000 1.4
+++ modules/poll/poll.css 5 Oct 2007 16:55:06 -0000
@@ -31,6 +31,6 @@
font-weight: bold;
}
-.node-form .poll-form fieldset {
- display: block;
+.node-form .poll-form .form-item {
+ margin-top: 0;
}
Index: modules/poll/poll.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/poll/poll.module,v
retrieving revision 1.242
diff -u -r1.242 poll.module
--- modules/poll/poll.module 6 Sep 2007 12:18:01 -0000 1.242
+++ modules/poll/poll.module 5 Oct 2007 16:55:06 -0000
@@ -96,6 +96,14 @@
'type' => MENU_LOCAL_TASK,
'file' => 'poll.pages.inc',
);
+
+ $items['poll/js'] = array(
+ 'title' => 'Javascript Choice Form',
+ 'page callback' => 'poll_choice_js',
+ 'access arguments' => array('access content'),
+ 'type' => MENU_CALLBACK,
+ );
+
return $items;
}
@@ -168,64 +176,65 @@
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),
'#required' => TRUE,
'#default_value' => $node->title,
- '#weight' => -1
+ '#weight' => -5,
);
- 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->choice) ? 5 : count($node->choice));
}
- $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,
+ '#attributes' => array('class' => 'clear-block'),
+ '#weight' => -5,
);
- // 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']['choice'] = 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'] : '',
- );
+ // Add the current choices to the form.
+ for ($delta = 0; $delta < $choice_count; $delta++) {
+ $text = isset($node->choice[$delta]['chtext']) ? $node->choice[$delta]['chtext'] : '';
+ $votes = isset($node->choice[$delta]['chvotes']) ? $node->choice[$delta]['chvotes'] : '';
- 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
- );
- }
+ $form['choice_wrapper']['choice'][$delta] = _poll_choice_form($delta, $text, $votes);
}
+ // We name our button 'poll_more' to avoid conflicts with other modules using
+ // AHAH-enabled 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' => array(
+ 'path' => 'poll/js',
+ 'wrapper' => 'poll-choices',
+ 'method' => 'append',
+ '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'));
@@ -253,16 +262,88 @@
}
/**
+ * 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']['choice']) + 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']['choice'] array.
+ $form['chtext'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Choice @n', array('@n' => ($delta + 1))),
+ '#default_value' => isset($value) ? $value : '',
+ '#parents' => array('choice', $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('choice', $delta, 'chvotes'),
+ );
+ }
+
+ return $form;
+}
+
+/**
+ * Menu callback for AHAH additions.
+ */
+function poll_choice_js() {
+ $delta = count($_POST['choice']);
+
+ // 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']['choice'][$delta] = $form_element;
+ cache_set('form_'. $_POST['form_build_id'], $form->data, 'cache_form', $form->expire);
+
+ // 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.
+ drupal_json(array('status' => TRUE, 'data' => $output));
+}
+
+/**
* Implementation of hook_submit().
*/
function poll_node_form_submit(&$form, &$form_state) {
// Renumber fields
$form_state['values']['choice'] = array_values($form_state['values']['choice']);
$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;
- }
}
/**
Index: misc/ahah.js
===================================================================
RCS file: /cvs/drupal/drupal/misc/ahah.js,v
retrieving revision 1.3
diff -u -r1.3 ahah.js
--- misc/ahah.js 5 Oct 2007 09:35:08 -0000 1.3
+++ misc/ahah.js 5 Oct 2007 16:55:06 -0000
@@ -128,11 +128,6 @@
progress_element.remove();
$(this.element).removeClass('progess-disabled').attr('disabled', false);
- // Hide the new content before adding to page.
- if (this.showEffect != 'show') {
- new_content.hide();
- }
-
// Add the new content to the page.
Drupal.freezeHeight();
if (this.method == 'replace') {
@@ -142,10 +137,18 @@
wrapper[this.method](new_content);
}
+ // Immediately hide the new content if we're using any effects.
+ if (this.showEffect != 'show') {
+ new_content.hide();
+ }
+
// Determine what effect use and what content will receive the effect, then
// show the new content. For browser compatibility, Safari is excluded from
// using effects on table rows.
- if ($('.ahah-new-content', new_content).size() > 0 && !($.browser.safari && $("tr.ahah-new-content", new_content).size() > 0)) {
+ if (($.browser.safari && $("tr.ahah-new-content", new_content).size() > 0)) {
+ new_content.show();
+ }
+ else if ($('.ahah-new-content', new_content).size() > 0) {
$('.ahah-new-content', new_content).hide();
new_content.show();
$(".ahah-new-content", new_content)[this.showEffect](this.showSpeed);