diff options
author | Dries Buytaert <dries@buytaert.net> | 2007-10-17 12:34:16 +0000 |
---|---|---|
committer | Dries Buytaert <dries@buytaert.net> | 2007-10-17 12:34:16 +0000 |
commit | a745b0f68ba165de3bc94e16f29724776224a9dc (patch) | |
tree | d862d5bbea472a7864c46ea7b891ae5fb0322c82 | |
parent | 6f731d920ac2f6564c44043bffac147aeb3d3bed (diff) | |
download | brdo-a745b0f68ba165de3bc94e16f29724776224a9dc.tar.gz brdo-a745b0f68ba165de3bc94e16f29724776224a9dc.tar.bz2 |
- Patch #155870 by quicksketch et al: AHAH-ification of the poll module.
-rw-r--r-- | CHANGELOG.txt | 1 | ||||
-rw-r--r-- | includes/path.inc | 2 | ||||
-rw-r--r-- | modules/book/book.admin.inc | 2 | ||||
-rw-r--r-- | modules/book/book.pages.inc | 4 | ||||
-rw-r--r-- | modules/openid/openid.module | 2 | ||||
-rw-r--r-- | modules/poll/poll.css | 5 | ||||
-rw-r--r-- | modules/poll/poll.module | 219 |
7 files changed, 184 insertions, 51 deletions
diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 0809f6e97..8bfc125fd 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -48,6 +48,7 @@ Drupal 6.0, xxxx-xx-xx (development version) * Can now specify the minimum PHP version required for a module within the .info file. * Dynamically check password strength and confirmation. + * Refactored poll administration. - Theme system: * Added .info files to themes and made it easier to specify regions and features. diff --git a/includes/path.inc b/includes/path.inc index d9774f93e..aa6ae9d47 100644 --- a/includes/path.inc +++ b/includes/path.inc @@ -234,7 +234,7 @@ function drupal_is_front_page() { */ function drupal_match_path($path, $patterns) { static $regexps; - + if (!isset($regexps[$patterns])) { $regexps[$patterns] = '/^('. preg_replace(array('/(\r\n?|\n)/', '/\\\\\*/', '/(^|\|)\\\\<front\\\\>($|\|)/'), array('|', '.*', '\1'. preg_quote(variable_get('site_frontpage', 'node'), '/') .'\2'), preg_quote($patterns, '/')) .')$/'; } diff --git a/modules/book/book.admin.inc b/modules/book/book.admin.inc index 4fd1e6815..039940206 100644 --- a/modules/book/book.admin.inc +++ b/modules/book/book.admin.inc @@ -75,7 +75,7 @@ function book_admin_edit($form_state, $node) { '#prefix' => '<div id="book-admin-edit-wrapper">', '#suffix' => '</div>', ); - + $form['#node'] = $node; $form['table'] = _book_admin_table($node); $form['save'] = array( diff --git a/modules/book/book.pages.inc b/modules/book/book.pages.inc index 15dd553a3..bcfd71dda 100644 --- a/modules/book/book.pages.inc +++ b/modules/book/book.pages.inc @@ -281,11 +281,11 @@ function book_form_update() { drupal_json(array('status' => TRUE, 'data' => $output)); } else { - drupal_json(array('status' => FALSE, 'data' => '')); + drupal_json(array('status' => FALSE, 'data' => '')); } } else { - drupal_json(array('status' => FALSE, 'data' => '')); + drupal_json(array('status' => FALSE, 'data' => '')); } exit(); } diff --git a/modules/openid/openid.module b/modules/openid/openid.module index d5727954a..97a75294c 100644 --- a/modules/openid/openid.module +++ b/modules/openid/openid.module @@ -168,7 +168,7 @@ function openid_begin($claimed_id, $return_to = '', $form_values = array()) { else { $identity = $claimed_id; } - + if (isset($services[0]['types']) && is_array($services[0]['types']) && in_array(OPENID_NS_2_0 .'/server', $services[0]['types'])) { $identity = 'http://openid.net/identifier_select/2.0'; } diff --git a/modules/poll/poll.css b/modules/poll/poll.css index 67695b054..b63161179 100644 --- a/modules/poll/poll.css +++ b/modules/poll/poll.css @@ -30,7 +30,6 @@ .poll .vote-form .choices .title { font-weight: bold; } - -.node-form .poll-form fieldset { - display: block; +.node-form #edit-poll-more { + margin: 0; } diff --git a/modules/poll/poll.module b/modules/poll/poll.module index 3f4f28bac..af700af48 100644 --- a/modules/poll/poll.module +++ b/modules/poll/poll.module @@ -36,6 +36,9 @@ function poll_theme() { 'template' => 'poll-vote', 'arguments' => array('form' => NULL), ), + 'poll_choices' => array( + 'arguments' => array('form' => NULL), + ), 'poll_results' => array( 'template' => 'poll-results', 'arguments' => array('raw_title' => NULL, 'results' => NULL, 'votes' => NULL, 'raw_links' => NULL, 'block' => NULL, 'nid' => NULL, 'vote' => NULL), @@ -96,6 +99,14 @@ function poll_menu() { '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,70 +179,80 @@ function poll_node_info() { 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) ? 2 : count($node->choice)); } - $form['choices'] = array( - '#type' => 'hidden', - '#value' => $choices, + // Add a wrapper for the choices and more button. + $form['choice_wrapper'] = array( + '#tree' => FALSE, + '#weight' => -5, + '#prefix' => '<div class="clear-block" id="poll-choice-wrapper">', + '#suffix' => '</div>', ); - // Poll choices - $form['choice'] = array( - '#type' => 'fieldset', - '#title' => t('Choices'), - '#prefix' => '<div class="poll-form">', + // Container for just the poll choices. + $form['choice_wrapper']['choice'] = array( + '#prefix' => '<div id="poll-choices">', '#suffix' => '</div>', - '#tree' => TRUE + '#theme' => 'poll_choices', ); - // 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."), + // 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'] : 0; + + $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('More choices'), + '#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' => 'replace', + 'effect' => 'fade', + ), ); - 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 - ); - } - } + // If we're using the javascript version (99% use-case), change the button + // title to 'Add another choice' to reflect the javascript behavior. + drupal_add_js("if (Drupal.jsEnabled) { $(document).ready(function() { $('#edit-poll-more').val('". t('Add another choice') ."'); }); }", 'inline'); // 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')); if ($admin) { - $form['settings'] = array('#type' => 'fieldset', '#title' => t('Settings')); + $form['settings'] = array( + '#type' => 'fieldset', + '#collapsible' => TRUE, + '#title' => t('Poll settings'), + '#weight' => -4, + ); $form['settings']['active'] = array( '#type' => 'radios', @@ -253,16 +274,93 @@ function poll_form(&$node, $form_state) { } /** + * 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 the form to rebuild and run submit handlers. + node_form_submit_build_node($form, $form_state); + + // Make the changes we want to the form state. + if ($form_state['values']['poll_more']) { + $form_state['choice_count'] = count($form_state['values']['choice']) + 5; + } +} + +function _poll_choice_form($delta, $value = '', $votes = 0) { + $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' => $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, + '#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. + $cache = cache_get('form_'. $_POST['form_build_id'], 'cache_form'); + $cache->data['choice_wrapper']['choice'][$delta] = $form_element; + cache_set('form_'. $_POST['form_build_id'], $cache->data, 'cache_form', $cache->expire); + + // Build the new form. + $form_state = array('submitted' => FALSE); + $form = $cache->data; + $form += array( + '#post' => $_POST, + '#programmed' => FALSE, + ); + $form = form_builder('poll_node_form', $form, $form_state); + + // Render the new output. + $choice_form = $form['choice_wrapper']['choice']; + unset($choice_form['#prefix'], $choice_form['#suffix']); // Prevent duplicate wrappers. + $choice_form[$delta]['#attributes']['class'] = empty($choice_form[$delta]['#attributes']['class']) ? 'ahah-new-content' : $choice_form[$delta]['#attributes']['class'] .' ahah-new-content'; + $choice_form[$delta]['chvotes']['#value'] = 0; + $output = theme('status_messages') . drupal_render($choice_form); + + 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; - } } /** @@ -530,6 +628,41 @@ function poll_view_results(&$node, $teaser, $page, $block) { return theme('poll_results', $node->title, $poll_results, $total_votes, isset($node->links) ? $node->links : array(), $block, $node->nid, isset($node->vote) ? $node->vote : NULL); } + +/** + * Theme the admin poll form for choices. + */ +function theme_poll_choices($form) { + $rows = array(); + $headers = array( + t('Choice'), + t('Vote count'), + ); + + foreach (element_children($form) as $key) { + // No need to print the field title every time. + unset($form[$key]['chtext']['#title'], $form[$key]['chvotes']['#title']); + + // Build the table row. + $row = array( + 'data' => array( + array('data' => drupal_render($form[$key]['chtext']), 'class' => 'poll-chtext'), + array('data' => drupal_render($form[$key]['chvotes']), 'class' => 'poll-chvotes'), + ), + ); + + // Add additional attributes to the row, such as a class for this row. + if (isset($form[$key]['#attributes'])) { + $row = array_merge($row, $form[$key]['#attributes']); + } + $rows[] = $row; + } + + $output = theme('table', $headers, $rows); + $output .= drupal_render($form); + return $output; +} + /** * Preprocess the poll_results theme hook. * |