From ea8d73e1b9cf12888daf93005aa6bce71974a060 Mon Sep 17 00:00:00 2001 From: James Elliott Date: Fri, 8 Jul 2011 14:14:10 -0400 Subject: [PATCH 2/2] Issue #1212930 by james.elliott: Changed Convert the fivestar widget to use the D7 AJAX framework. --- css/fivestar.css | 9 + fivestar.module | 477 +++++++++++++++++-------------------------- includes/fivestar.admin.inc | 10 - includes/fivestar.field.inc | 98 +++------- includes/fivestar.theme.inc | 8 +- js/fivestar.js | 475 ++++++++----------------------------------- 6 files changed, 313 insertions(+), 764 deletions(-) diff --git a/css/fivestar.css b/css/fivestar.css index 0709272..5c7e726 100644 --- a/css/fivestar.css +++ b/css/fivestar.css @@ -94,3 +94,12 @@ div.fivestar-widget div.hover a, div.rating div a:hover { form.fivestar-widget div.description { margin-bottom: 0; } + +/* Fivestar AJAX processing */ +.fivestar-form-item .ajax-progress { + float: none; +} + +.fivestar-form-item.fivestar-processed + .form-submit { + display: none; +} diff --git a/fivestar.module b/fivestar.module index 699e5c9..10a76fe 100644 --- a/fivestar.module +++ b/fivestar.module @@ -93,19 +93,6 @@ function fivestar_menu() { } /** - * Implementation of hook_init(). - * - * These includes do not need to be loaded for cached pages. - */ -function fivestar_init() { - // Add necessary CSS and JS. - // TODO: These shouldn't be loaded on every page, but block caching omits - // CSS and JS files that would be otherwise added. - fivestar_add_js(); - fivestar_add_css(); -} - -/** * Implementation of hook_permission(). * * Exposes permissions for rating content, viewing aggregate ratings, and using PHP @@ -145,7 +132,7 @@ function fivestar_theme() { 'file' => 'includes/fivestar.theme.inc', ), 'fivestar_summary' => array( - 'variables' => array('user_rating' => NULL, 'average_rating' => NULL, 'votes' => 0, 'stars' => 5, 'feedback_enable' => TRUE), + 'variables' => array('user_rating' => NULL, 'average_rating' => NULL, 'votes' => 0, 'stars' => 5), 'file' => 'includes/fivestar.theme.inc', ), 'fivestar_widget' => array( @@ -154,7 +141,7 @@ function fivestar_theme() { ), // fivestar.admin.inc. 'fivestar_preview' => array( - 'variables' => array('style' => NULL, 'text' => NULL, 'stars' => NULL, 'unvote' => NULL, 'title' => NULL, 'feedback_enable' => TRUE, 'labels_enable' => TRUE, 'labels' => array()), + 'variables' => array('style' => NULL, 'text' => NULL, 'stars' => NULL, 'unvote' => NULL, 'title' => NULL, 'labels_enable' => TRUE, 'labels' => array()), 'file' => 'includes/fivestar.theme.inc', ), 'fivestar_preview_widget' => array( @@ -267,7 +254,6 @@ function fivestar_vote($entity_type, $id, $tag, $value) { $suffix = fivestar_get_suffix((!isset($node) ? 'default' : $node->type), $tag); $stars = variable_get('fivestar_stars_' . $suffix, 5); - $feedback_enable = variable_get('fivestar_feedback_' . $suffix, 1); $output .= ''; if (count($result)) { @@ -283,7 +269,6 @@ function fivestar_vote($entity_type, $id, $tag, $value) { 'average_rating' => (isset($summary[$tag]['average'])) ? $summary[$tag]['average'] : 0, 'votes' => (isset($summary[$tag]['count'])) ? $summary[$tag]['count'] : 0, 'stars' => $stars, - 'feedback_enable' => $feedback_enable, ); $skip_map = array( 'average' => array('user_rating', 'votes'), @@ -322,9 +307,9 @@ function _fivestar_cast_vote($entity_type, $id, $value, $tag = NULL, $uid = NULL $tag = empty($tag) ? 'vote' : $tag; $uid = empty($uid) ? $user->uid : $uid; // Bail out if the user's trying to vote on an invalid object. - if (!$skip_validation && !fivestar_validate_target($entity_type, $id, $tag, $uid)) { - return array(); - } +// if (!$skip_validation && !fivestar_validate_target($entity_type, $id, $tag, $uid)) { +// return array(); +// } // Sanity-check the incoming values. if (is_numeric($id) && is_numeric($value)) { if ($value > 100) { @@ -697,7 +682,6 @@ function fivestar_form($form, &$form_state, $entity_type, $id, $tag) { 'tag' => 'vote', 'autosubmit' => TRUE, 'title' => variable_get('fivestar_title_' . $suffix, 1) ? NULL : FALSE, - 'feedback_enable' => variable_get('fivestar_feedback_' . $suffix, 1), 'labels_enable' => variable_get('fivestar_labels_enable_' . $suffix, 1), 'labels' => variable_get('fivestar_labels_' . $suffix, array()), 'tag' => $tag, @@ -801,7 +785,6 @@ function fivestar_static($entity_type, $id, $bundle = NULL, $tag = 'vote') { 'average_rating' => $average_value, 'votes' => $count_value, 'stars'=> $stars, - 'feedback_enable' =>FALSE, )); return theme('fivestar_static_element', array('star_display' => $star_display, 'title' => $title, 'description' => $text_display)); } @@ -834,7 +817,6 @@ function fivestar_static($entity_type, $id, $bundle = NULL, $tag = 'vote') { * showing the widget. Defaults to FALSE. * - required: Whether this field is required before the form can be * submitted. Defaults to FALSE. - * - feedback_enable: Toggles the option to show the "Vote is being saved" * text while a vote is being registered through AJAX. Defaults to TRUE. * - labels_enable: Toggles the option to show the "Give it 2/5 stars" text * while hovering over the stars with the mouse. @@ -844,53 +826,21 @@ function fivestar_static($entity_type, $id, $bundle = NULL, $tag = 'vote') { * to "vote". */ function fivestar_custom_widget($form, &$form_state, $values, $settings) { - $form = array( - '#attributes' => array('class' => array('fivestar-widget')), - '#redirect' => FALSE, - '#theme' => 'fivestar_widget', - ); + $form = array(); $form['#submit'][] = 'fivestar_form_submit'; + $form['#attributes']['class'][] = 'fivestar-custom-widget'; - if (isset($settings['content_type'])) { - $form['content_type'] = array( - '#type' => 'hidden', - '#value' => $settings['content_type'], - ); - } - - if (isset($settings['content_id'])) { - $form['content_id'] = array( - '#type' => 'hidden', - '#value' => $settings['content_id'], - ); - } - - if (isset($settings['tag'])) { - $form['tag'] = array( - '#type' => 'hidden', - '#value' => $settings['tag'], - ); - } + $form_state['settings'] = $settings; + $form_state['destination'] = drupal_get_destination(); + $settings['auto_submit'] = TRUE; + + $values = isset($form_state['votes']) ? $form_state['values'] : $values; + $form['vote'] = array( '#type' => 'fivestar', - '#stars' => $settings['stars'], - '#vote_count' => $values['count'], - '#vote_average' => $values['average'], - '#auto_submit' => isset($settings['autosubmit']) ? $settings['autosubmit'] : TRUE, - '#auto_submit_path' => (!isset($settings['autosubmit']) || $settings['autosubmit']) ? 'fivestar/vote/'. $settings['content_type'] .'/'. $settings['content_id'] .'/' . $settings['tag'] : NULL, - '#allow_clear' => $settings['allow_clear'], - '#content_id' => isset($settings['content_id']) ? $settings['content_id'] : NULL, - '#required' => isset($settings['required']) ? $settings['required'] : FALSE, - '#feedback_enable' => isset($settings['feedback_enable']) ? $settings['feedback_enable'] : TRUE, - '#labels_enable' => isset($settings['labels_enable']) ? $settings['labels_enable'] : TRUE, - '#labels' => isset($settings['labels']) ? $settings['labels'] : NULL, - '#tag' => isset($settings['tag']) ? $settings['tag'] : 'vote', - ); - - $form['destination'] = array( - '#type' => 'hidden', - '#value' => $_GET['q'], + '#values' => $values, + '#settings' => $settings, ); $form['fivestar_submit'] = array( @@ -899,118 +849,6 @@ function fivestar_custom_widget($form, &$form_state, $values, $settings) { '#attributes' => array('class' => array('fivestar-submit')), ); - $form['vote']['#attributes']['class'] = isset($form['vote']['#attributes']['class']) ? $form['vote']['#attributes']['class'] : array(); - $settings['feedback_enable'] = isset($settings['feedback_enable']) ? $settings['feedback_enable'] : TRUE; - switch ($settings['text']) { - case 'user': - $form['vote']['#description'] = theme('fivestar_summary', array( - 'user_rating' => $values['user'], - 'votes' => $settings['style'] == 'dual' ? NULL : $values['count'], - 'stars' => $settings['stars'], - 'feedback_enable' => $settings['feedback_enable'], - )); - $form['vote']['#attributes']['class'][] = 'fivestar-user-text'; - break; - case 'average': - $form['vote']['#description'] = $settings['style'] == 'dual' ? NULL : theme('fivestar_summary', array( - 'average_rating' => $values['average'], - 'votes' => $values['count'], - 'stars' => $settings['stars'], - 'feedback_enable' => $settings['feedback_enable'], - )); - $form['vote']['#attributes']['class'][] = 'fivestar-average-text'; - break; - case 'smart': - $form['vote']['#description'] = ($settings['style'] == 'dual' && !$values['user']) ? NULL : theme('fivestar_summary', array( - 'user_rating' => $values['user'], - 'average_rating' => $values['user'] ? NULL : $values['average'], - 'votes' => $settings['style'] == 'dual' ? NULL : $values['count'], - 'stars' => $settings['stars'], - 'feedback_enable' => $settings['feedback_enable'], - )); - $form['vote']['#attributes']['class'][] = 'fivestar-smart-text'; - $form['vote']['#attributes']['class'][] = $values['user'] ? 'fivestar-user-text' : 'fivestar-average-text'; - break; - case 'dual': - $form['vote']['#description'] = theme('fivestar_summary', array( - 'user_rating' => $values['user'], - 'average_rating' => $settings['style'] == 'dual' ? NULL : $values['average'], - 'votes' => $settings['style'] == 'dual' ? NULL : $values['count'], - 'stars' => $settings['stars'], - 'feedback_enable' => $settings['feedback_enable'], - )); - $form['vote']['#attributes']['class'][] = ' fivestar-combo-text'; - break; - } - - switch ($settings['style']) { - case 'average': - $form['vote']['#title'] = t('Average'); - $form['vote']['#default_value'] = $values['average']; - $form['vote']['#attributes']['class'][] = 'fivestar-average-stars'; - break; - case 'user': - $form['vote']['#title'] = t('Your rating'); - $form['vote']['#default_value'] = $values['user']; - $form['vote']['#attributes']['class'][] = 'fivestar-user-stars'; - break; - case 'smart': - $form['vote']['#title'] = $values['user'] ? t('Your rating') : t('Average'); - $form['vote']['#default_value'] = $values['user'] ? $values['user'] : $values['average']; - $form['vote']['#attributes']['class'][] = 'fivestar-smart-stars '. ($values['user'] ? 'fivestar-user-stars' : 'fivestar-average-stars'); - break; - case 'dual': - $form['vote']['#title'] = t('Your rating'); - $form['vote']['#default_value'] = $values['user']; - $form['vote']['#attributes']['class'][] = 'fivestar-combo-stars'; - $form['#attributes']['class'][] = 'fivestar-combo-stars'; - $static_average = theme('fivestar_static', array( - 'rating' => $values['average'], - 'stars' => $settings['stars'], - 'tag' => $settings['tag'], - )); - if ($settings['text'] == 'none' && !$settings['labels_enable'] && !$settings['feedback_enable']) { - $static_description = NULL; - } - elseif ($settings['text'] != 'none') { - $static_description = theme('fivestar_summary', array( - 'averrage_rating' => $settings['text'] == 'user' ? NULL : (isset($values['average']) ? $values['average'] : 0), - 'votes' => isset($values['count']) ? $values['count'] : 0, - 'stars' => $settings['stars'], - 'feedback_enable' => FALSE - )); - } - else { - $static_description = ' '; - } - $form['average'] = array( - '#type' => 'markup', - '#markup' => theme('fivestar_static_element', array( - 'star_display' => $static_average, - 'title' => $settings['title'] !== FALSE ? t('Average') : NULL, - 'description' => $static_description, - )), - '#weight' => -1, - ); - break; - } - - // Set an over-ridding title if passed in. - // An empty title won't change the default, a string will set a new title, - // and title === FALSE will unset the title entirely. - if (isset($settings['title'])) { - if ($settings['title'] !== FALSE) { - $form['vote']['#title'] = $settings['title']; - } - else { - unset($form['vote']['#title']); - unset($form['average']['#title']); - } - } - elseif ($settings['tag'] && $settings['tag'] != 'vote') { - $form['vote']['#title'] .= ' (' . ucfirst($settings['tag']) . ')'; - } - return $form; } @@ -1018,10 +856,10 @@ function fivestar_custom_widget($form, &$form_state, $values, $settings) { * Submit handler for the above form (non-javascript version). */ function fivestar_form_submit($form, &$form_state) { - if ($form_state['values']['form_id'] == 'fivestar_form_'. $form_state['values']['content_type'] .'_'. $form_state['values']['content_id'] . '_' . $form_state['values']['tag']) { + if ($form_state['settings']['form_id'] == 'fivestar_form_'. $form_state['settings']['content_type'] .'_'. $form_state['settings']['content_id'] . '_' . $form_state['settings']['tag']) { // Cast the vote. - _fivestar_cast_vote($form_state['values']['content_type'], $form_state['values']['content_id'], $form_state['values']['vote'], $form_state['values']['tag']); - votingapi_recalculate_results($form_state['values']['content_type'], $form_state['values']['content_id']); + _fivestar_cast_vote($form_state['settings']['content_type'], $form_state['settings']['content_id'], $form_state['values']['vote'], $form_state['settings']['tag']); + votingapi_recalculate_results($form_state['settings']['content_type'], $form_state['settings']['content_id']); // Set a message that the vote was received. if ($form_state['values']['vote'] === '0') { @@ -1042,62 +880,25 @@ function fivestar_form_submit($form, &$form_state) { */ function fivestar_element_info() { $type['fivestar'] = array( - '#input' => TRUE, - '#stars' => 5, - '#widget' => 'stars', - '#allow_clear' => FALSE, - '#auto_submit' => FALSE, - '#auto_submit_path' => '', - '#labels_enable' => TRUE, - '#feedback_enable' => TRUE, + '#values' => array( + 'user' => 0, + 'count' => 0, + 'average' => 0, + ), + '#settings' => array( + 'stars' => 5, + 'allow_clear' => FALSE, + 'style' => 'average', + 'text' => 'average', + 'auto_submit' => FALSE, + 'widget' => 'stars', + ), '#process' => array('fivestar_expand'), - '#theme_wrappers' => array('form_element'), ); return $type; } /** - * Fetch the necessary CSS files to render the fivestar widget. - */ -function fivestar_add_css($widget_css = NULL) { - // Add fivestar CSS. - drupal_add_css(drupal_get_path('module', 'fivestar') .'/css/fivestar.css'); - - // Add widget specific CSS. - if (!isset($widget_css)) { - $widget_css = variable_get('fivestar_widget', 'default'); - } - - if ($widget_css != 'default') { - drupal_add_css($widget_css); - } -} - -/** - * Add necessary JS files and settings to render the fivestar widget. - */ -function fivestar_add_js() { - static $js_added = FALSE; - - // Add necessary javascript only once per page. - if (!$js_added) { - $settings = array( - 'titleUser' => t('Your rating') .': ', - 'titleAverage' => t('Average') .': ', - 'feedbackSavingVote' => t('Saving your vote...'), - 'feedbackVoteSaved' => t('Your vote has been saved.'), - 'feedbackDeletingVote' => t('Deleting your vote...'), - 'feedbackVoteDeleted' => t('Your vote has been deleted.'), - ); - - drupal_add_js(drupal_get_path('module', 'fivestar') .'/js/fivestar.js'); - drupal_add_js(array('fivestar' => $settings), 'setting'); - $js_added = TRUE; - } -} - - -/** * Add Inline CSS to the page, only used on admin/config/content/fivestar page. */ function fivestar_add_inline_css($widget_key = NULL, $css = NULL, $reset = FALSE) { @@ -1126,95 +927,195 @@ function fivestar_get_inline_css() { * Process callback for fivestar_element -- see fivestar_element() */ function fivestar_expand($element) { - - if (isset($element['#vote_count'])) { - $element['vote_count'] = array( - '#type' => 'hidden', - '#value' => $element['#vote_count'], - ); - } - - if (isset($element['#vote_average'])) { - $element['vote_average'] = array( - '#type' => 'hidden', - '#value' => $element['#vote_average'], - ); - } - - if ($element['#auto_submit'] && !empty($element['#auto_submit_path'])) { - $element['auto_submit_path'] = array( - '#type' => 'hidden', - '#value' => url($element['#auto_submit_path']), - '#attributes' => array('class' => 'fivestar-path'), - ); - $element['auto_submit_token'] = array( - '#type' => 'hidden', - '#value' => fivestar_get_token($element['#auto_submit_path']), - '#attributes' => array('class' => 'fivestar-token'), - ); - } - - if (!isset($element['#default_value'])) { - $element['#default_value'] = 0; - } + $settings = $element['#settings']; + $values = $element['#values']; + + // Add JS and CSS + $path = drupal_get_path('module', 'fivestar'); + $element['#attached']['css'][] = $path . '/css/fivestar.css'; + $element['#attached']['css'][] = variable_get('fivestar_widget', 'default'); + $element['#attached']['js'][] = $path . '/js/fivestar.js'; $options = array('-' => t('Select rating')); - $default_value = $element['#default_value']; - for ($i = 0; $i <= $element['#stars']; $i++) { - $this_value = ceil($i * 100/$element['#stars']); - $next_value = ceil(($i+1) * 100/$element['#stars']); - // Display clear button only if enabled. - if ($element['#allow_clear'] == TRUE && $i == 0) { - $options[$this_value] = isset($element['#labels'][$i]) ? t(filter_xss_admin($element['#labels'][$i])) : t('Cancel rating'); + if ($settings['allow_clear'] == TRUE && $i == 0) { + $options[0] = isset($element['labels'][$i]) ? t(filter_xss_admin($element['labels'][$i])) : t('Cancel rating'); } + + for ($i = 1; $i <= $settings['stars']; $i++) { + $this_value = ceil($i * 100/$settings['stars']); // Display a normal star value. - if ($i > 0) { - if (isset($element['#labels'][$i])) { - $options[$this_value] = $element['#labels'][$i] == '' ? $i : t(filter_xss_admin($element['#labels'][$i]), array('@star' => $i, '@count' => $element['#stars'])); + if (isset($element['labels'][$i])) { + $options[$this_value] = $element['labels'][$i] == '' ? $i : t(filter_xss_admin($element['labels'][$i]), array('@star' => $i, '@count' => $settings['#stars'])); } else { - $options[$this_value] = t('Give it @star/@count', array('@star' => $i, '@count' => $element['#stars'])); + $options[$this_value] = t('Give it @star/@count', array('@star' => $i, '@count' => $settings['stars'])); } } - // Round up the default value to the next exact star value if needed. - if ($this_value < $element['#default_value'] && $next_value > $element['#default_value']) { - $default_value = $next_value; - } - } $element['vote'] = array( '#type' => 'select', '#options' => $options, '#required' => $element['#required'], - '#default_value' => $default_value, '#parents' => $element['#parents'], - '#theme' => 'fivestar_select', '#weight' => $element['#weight'], ); + + + switch ($settings['text']) { + case 'user': + $element['vote']['#description'] = theme('fivestar_summary', array( + 'user_rating' => $values['user'], + 'votes' => $settings['style'] == 'dual' ? NULL : $values['count'], + 'stars' => $settings['stars'], + )); + $element['vote']['#attributes']['class'][] = 'fivestar-user-text'; + break; + case 'average': + $element['vote']['#description'] = $settings['style'] == 'dual' ? NULL : theme('fivestar_summary', array( + 'average_rating' => $values['average'], + 'votes' => $values['count'], + 'stars' => $settings['stars'], + )); + $element['vote']['#attributes']['class'][] = 'fivestar-average-text'; + break; + case 'smart': + $element['vote']['#description'] = ($settings['style'] == 'dual' && !$values['user']) ? NULL : theme('fivestar_summary', array( + 'user_rating' => $values['user'], + 'average_rating' => $values['user'] ? NULL : $values['average'], + 'votes' => $settings['style'] == 'dual' ? NULL : $values['count'], + 'stars' => $settings['stars'], + )); + $element['vote']['#attributes']['class'][] = 'fivestar-smart-text'; + $element['vote']['#attributes']['class'][] = $values['user'] ? 'fivestar-user-text' : 'fivestar-average-text'; + break; + case 'dual': + $element['vote']['#description'] = theme('fivestar_summary', array( + 'user_rating' => $values['user'], + 'average_rating' => $settings['style'] == 'dual' ? NULL : $values['average'], + 'votes' => $settings['style'] == 'dual' ? NULL : $values['count'], + 'stars' => $settings['stars'], + )); + $element['vote']['#attributes']['class'][] = ' fivestar-combo-text'; + break; + } - // If a default value is not exactly on a radio value, round up to the next one - if ($element['#default_value'] > $this_value && $element['#default_value'] <= $next_value) { - $element['vote']['#default_value'] = $next_value; + switch ($settings['style']) { + case 'average': + $element['vote']['#title'] = t('Average'); + $element['vote']['#default_value'] = $values['average']; + $element['vote']['#attributes']['class'][] = 'fivestar-average-stars'; + break; + case 'user': + $element['vote']['#title'] = t('Your rating'); + $element['vote']['#default_value'] = $values['user']; + $element['vote']['#attributes']['class'][] = 'fivestar-user-stars'; + break; + case 'smart': + $element['vote']['#title'] = $values['user'] ? t('Your rating') : t('Average'); + $element['vote']['#default_value'] = $values['user'] ? $values['user'] : $values['average']; + $element['vote']['#attributes']['class'][] = 'fivestar-smart-stars '. ($values['user'] ? 'fivestar-user-stars' : 'fivestar-average-stars'); + break; + case 'dual': + $element['vote']['#title'] = t('Your rating'); + $element['vote']['#default_value'] = $values['user']; + $element['vote']['#attributes']['class'][] = 'fivestar-combo-stars'; + $element['#attributes']['class'][] = 'fivestar-combo-stars'; + $static_average = theme('fivestar_static', array( + 'rating' => $values['average'], + 'stars' => $settings['stars'], + 'tag' => $settings['tag'], + )); + if ($settings['text'] == 'none' && !$settings['labels_enable']) { + $static_description = NULL; + } + elseif ($settings['text'] != 'none') { + $static_description = theme('fivestar_summary', array( + 'averrage_rating' => $settings['text'] == 'user' ? NULL : (isset($values['average']) ? $values['average'] : 0), + 'votes' => isset($values['count']) ? $values['count'] : 0, + 'stars' => $settings['stars'], + )); + } + else { + $static_description = ' '; + } + $element['average'] = array( + '#type' => 'markup', + '#markup' => theme('fivestar_static_element', array( + 'star_display' => $static_average, + 'title' => t('Average'), + 'description' => $static_description, + )), + '#weight' => -1, + ); + break; + } + + // Convert the default value to one that matches one of the options. + $element['vote']['#default_value'] = round($settings['stars'] * $element['vote']['#default_value']/100) * 100/$settings['stars']; + + if ($settings['auto_submit']) { + $element['vote']['#ajax'] = array( + 'callback' => 'fivestar_ajax_submit', + 'wrapper' => 'none', + ); } $class = isset($element['#attributes']['class']) ? $element['#attributes']['class'] : array(); - if ($element['#widget'] == 'stars') { + if ($settings['widget'] == 'stars') { $class[] = 'fivestar-form-item'; } - if ($element['#labels_enable']) { - // Set a class for the display of label text on hover. - $class[] = 'fivestar-labels-hover'; - } $element['#prefix'] = '
$class)) . '>'; $element['#suffix'] = '
'; // Add validation function that considers a 0 value as empty. $element['#element_validate'] = array('fivestar_validate'); + + // Set an over-ridding title if passed in. + // An empty title won't change the default, a string will set a new title, + // and title === FALSE will unset the title entirely. + if (isset($settings['title'])) { + if ($settings['title'] !== FALSE) { + $element['vote']['#title'] = $settings['title']; + } + else { + unset($element['vote']['#title']); + unset($element['average']['#title']); + } + } + elseif ($settings['tag'] && $settings['tag'] != 'vote') { + $element['vote']['#title'] .= ' (' . ucfirst($settings['tag']) . ')'; + } return $element; } +function fivestar_ajax_submit($form, $form_state) { + _fivestar_cast_vote($form_state['settings']['content_type'], $form_state['settings']['content_id'], $form_state['values']['vote'], $form_state['settings']['tag']); + votingapi_recalculate_results($form_state['settings']['content_type'], $form_state['settings']['content_id'], TRUE); + + $votes = fivestar_get_votes($form_state['settings']['content_type'], $form_state['settings']['content_id'], $form_state['settings']['tag']); + + $values = array(); + $values['user'] = isset($votes['user']['value']) ? $votes['user']['value'] : 0; + $values['average'] = isset($votes['average']['value']) ? $votes['average']['value'] : 0; + $values['count'] = isset($votes['count']['value']) ? $votes['count']['value'] : 0; + + $form['vote']['#values'] = $values; + + drupal_process_form($form_state['form_id'], $form, $form_state); + + return array( + '#type' => 'ajax', + '#commands' => array( + array( + 'command' => 'fivestarUpdate', + 'data' => drupal_render($form['vote']), + ), + ), + ); +} + /** * An #element_validate function for "fivestar" elements. */ @@ -1363,7 +1264,6 @@ function fivestar_views_widget_handler($value, $field, $columns, $summary) { 'tag' => $tag, 'autosubmit' => TRUE, 'title' => FALSE, - 'feedback_enable' => $summary ? variable_get('fivestar_feedback_'. $node_type, 1) : FALSE, 'labels_enable' => $summary ? variable_get('fivestar_labels_enable_'. $node_type, 1) : FALSE, 'labels' => $summary ? variable_get('fivestar_labels_'. $node_type, array()) : array(), ); @@ -1421,7 +1321,6 @@ function fivestar_get_settings($node_type, $tag) { 'fivestar' => variable_get('fivestar_' . $suffix, 0), 'stars' => variable_get('fivestar_stars_' . $suffix, 5), 'unvote_enable' => variable_get('fivestar_unvote_' . $suffix, 0), - 'feedback_enable' => variable_get('fivestar_feedback_'. $suffix, 1), 'labels_enable' => variable_get('fivestar_labels_enable_'. $suffix, 1), 'labels' => variable_get('fivestar_labels_'. $suffix, array()), 'star_display' => variable_get('fivestar_style_' . $suffix, 'average'), diff --git a/includes/fivestar.admin.inc b/includes/fivestar.admin.inc index bab3a2a..6b31cf5 100644 --- a/includes/fivestar.admin.inc +++ b/includes/fivestar.admin.inc @@ -163,13 +163,6 @@ function fivestar_node_type_tag_form($form, &$form_state, $node_type, $tag = 'vo '#return_value' => 1, ); - $form['direct']['fivestar_feedback'] = array( - '#type' => 'checkbox', - '#title' => t('Enable feedback during vote saving and deletion'), - '#default_value' => $settings['feedback_enable'], - '#return_value' => 1 - ); - $form['direct']['fivestar_unvote'] = array( '#type' => 'checkbox', '#title' => t('Allow users to undo their votes'), @@ -213,7 +206,6 @@ function fivestar_node_type_tag_form($form, &$form_state, $node_type, $tag = 'vo 'stars' => $form['fivestar_stars']['#default_value'], 'unvote' => $form['direct']['fivestar_unvote']['#default_value'], 'title' => $form['direct']['fivestar_title']['#default_value'] ? NULL : FALSE, - 'feedback_enable' => $form['direct']['fivestar_feedback']['#default_value'], 'labels_enable' => $form['labels']['fivestar_labels_enable']['#default_value'], 'labels' => $settings['labels'], )), @@ -310,7 +302,6 @@ $_POST = array ( $stars = (int)$_POST['stars']; $unvote = (boolean)$_POST['unvote']; $title = (boolean)$_POST['title']; - $feedback_enable = (boolean)$_POST['feedback']; $labels_enable = (boolean)$_POST['labels_enable']; $labels = (array)$_POST['labels']; foreach ($labels as $key => $label) { @@ -323,7 +314,6 @@ $_POST = array ( 'stars' => $stars, 'unvote' => $unvote, 'title' => $title ? NULL : FALSE, - 'feedback' => $feedback_enable, 'labels_enable' => $labels_enable, 'labels' => $labels, )); diff --git a/includes/fivestar.field.inc b/includes/fivestar.field.inc index 5133cd3..ea6c785 100644 --- a/includes/fivestar.field.inc +++ b/includes/fivestar.field.inc @@ -226,67 +226,35 @@ function fivestar_widget_settings_form($field, $instance) { * Implementation of hook_field_widget_form(). */ function fivestar_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) { - if ($instance['widget']['type'] == 'select') { - $element = array('#tree' => TRUE); - $element['rating'] = array( - '#type' => 'fivestar', - '#title' => $instance['label'], - '#default_value' => isset($items[0]['rating']) ? $items[0]['rating'] : NULL, - '#stars' => isset($field['settings']['stars']) ? $field['settings']['stars'] : 5, - // dunno where these two comes from - '#allow_clear' => isset($instance['widget']['settings']['allow_clear']) ? $instance['widget']['settings']['allow_clear'] : 0, - '#description' => isset($instance['widget']['settings']['description']) ? $instance['widget']['settings']['description'] : '', - '#weight' => $instance['widget']['weight'], - '#auto_submit' => FALSE, - '#widget' => $instance['widget']['type'], - '#required' => $instance['required'], - '#labels_enable' => FALSE, - ); - $element['target'] = array( - '#type' => 'value', - // again i have no clue where this comes from. - '#value' => isset($field['settings']['target']) ? $field['settings']['target'] : NULL, - ); - $element['axis'] = array( - '#type' => 'value', - '#value' => $field['settings']['axis'], - ); - - // CCK likes to always have a 2D array for form elements. - $element = array($element); - } - - if ($instance['widget']['type'] == 'stars') { - $element = array('#tree' => TRUE); - $element['rating'] = array( - '#type' => 'fivestar', - '#title' => $instance['label'], - '#default_value' => isset($items[0]['rating']) ? $items[0]['rating'] : NULL, - '#stars' => isset($field['settings']['stars']) ? $field['settings']['stars'] : 5, - // dunno where these two comes from - '#allow_clear' => isset($instance['widget']['settings']['allow_clear']) ? $instance['widget']['settings']['allow_clear'] : 0, - '#description' => isset($instance['widget']['settings']['description']) ? $instance['widget']['settings']['description'] : '', - '#weight' => $instance['widget']['weight'], - '#auto_submit' => FALSE, - '#widget' => $instance['widget']['type'], - '#required' => $instance['required'], - '#labels_enable' => FALSE, - ); - $element['target'] = array( - '#type' => 'value', - // again i have no clue where this comes from. - '#value' => isset($field['settings']['target']) ? $field['settings']['target'] : NULL, - ); - $element['axis'] = array( - '#type' => 'value', - '#value' => $field['settings']['axis'], - ); + $tag = (isset($field['settings']['axis'])) ? $field['settings']['axis'] : 'vote'; + + $widget_settings = isset($form_state['input']['instance']['widget']['settings']) ? $form_state['input']['instance']['widget']['settings'] : $instance['widget']['settings']; + + $settings = array( + 'stars' => $field['settings']['stars'], + 'allow_clear' => $widget_settings['allow_clear'], + 'style' => $widget_settings['style'], + 'text' => $widget_settings['text'], + 'tag' => $tag, + 'auto_submit' => FALSE, + 'widget' => $instance['widget']['type'], + 'title' => isset($instance['label']) ? $instance['label'] : NULL, + ); + + $values = array( + 'count' => 0, + 'average' => 0, + 'user' => 0, + ); - // CCK likes to always have a 2D array for form elements. - $element = array($element); - } + $element = array('#tree' => TRUE); + $element['rating'] = array( + '#type' => 'fivestar', + '#values' => $values, + '#settings' => $settings, + ); - return $element; + return array($element); } /** @@ -313,7 +281,6 @@ function fivestar_field_formatter_info() { 'stars' => 5, 'allow_clear' => FALSE, 'style' => 'average', - 'feedback_enable' => FALSE, 'text' => 'average', ), ), @@ -337,12 +304,6 @@ function fivestar_field_formatter_settings_form($field, $instance, $view_mode, $ '#options' => drupal_map_assoc(range(1, 10)), '#default_value' => $settings['stars'], ); - $element['feedback_enable'] = array( - '#type' => 'checkbox', - '#title' => t('Enable feedback during vote saving and deletion'), - '#default_value' => $settings['feedback_enable'], - '#return_value' => 1 - ); $element['allow_clear'] = array( '#type' => 'checkbox', '#title' => t('Allow users to undo their votes'), @@ -389,8 +350,7 @@ function fivestar_field_formatter_settings_summary($field, $instance, $view_mode $summary = t("Stars: @stars, Feedback: @feedback, Undo: @clear, Stars Display: @style, Text Display: @text", array( '@stars' => $settings['stars'], - '@clear' => ($settings['allow_clear']) ? 'Yes' : 'No', - '@feedback' => ($settings['feedback_enable']) ? 'Yes' : 'No', + '@clear' => ($settings['allow_clear']) ? 'Yes' : 'No', '@style' => $settings['style'], '@text' => $settings['text'])); @@ -425,9 +385,9 @@ function fivestar_field_formatter_view($entity_type, $entity, $field, $instance, 'tag' => $tag, 'autosubmit' => TRUE, 'title' => FALSE, - 'feedback_enable' => $settings['feedback_enable'], 'labels_enable' => FALSE, 'labels' => array(), + 'widget' => 'stars', ); $element[0] = drupal_get_form('fivestar_custom_widget', $values, $settings); diff --git a/includes/fivestar.theme.inc b/includes/fivestar.theme.inc index 9146274..a654052 100644 --- a/includes/fivestar.theme.inc +++ b/includes/fivestar.theme.inc @@ -143,7 +143,6 @@ function theme_fivestar_preview($variables) { 'text' => $text, 'title' => $title, 'autosubmit' => FALSE, - 'feedback_enable' => $feedback_enable, 'labels_enable' => $labels_enable, 'labels' => $labels, 'tag' => 'vote', @@ -213,10 +212,7 @@ function theme_fivestar_formatter_percentage($variables) { function theme_fivestar($variables) { $element = $variables['element']; if (empty($element['#description'])) { - if ($element['#feedback_enable']) { - $element['#description'] = '
 
'; - } - elseif ($element['#labels_enable']) { + if ($element['#labels_enable']) { $element['#description'] = '
 
'; } } @@ -358,7 +354,7 @@ function theme_fivestar_summary($variables) { $output = ''. t('No votes yet') .''; } - $output = '
'. $output .'
'; + $output = '
'. $output .'
'; return $output; } diff --git a/js/fivestar.js b/js/fivestar.js index df7f770..1c10d46 100644 --- a/js/fivestar.js +++ b/js/fivestar.js @@ -1,395 +1,90 @@ -/** - * Modified Star Rating - jQuery plugin - * - * Copyright (c) 2006 Wil Stuckey - * - * Original source available: http://sandbox.wilstuckey.com/jquery-ratings/ - * Extensively modified by Lullabot: http://www.lullabot.com - * - * Dual licensed under the MIT and GPL licenses: - * http://www.opensource.org/licenses/mit-license.php - * http://www.gnu.org/licenses/gpl.html - */ - -/** - * Create a degradeable star rating interface out of a simple form structure. - * Returns a modified jQuery object containing the new interface. - * - * @example jQuery('form.rating').fivestar(); - * @cat plugin - * @type jQuery - * - */ -(function($){ // Create local scope. - /** - * Takes the form element, builds the rating interface and attaches the proper events. - * @param {Object} $obj - */ - var buildRating = function($obj){ - var $widget = buildInterface($obj), - $stars = $('.star', $widget), - $cancel = $('.cancel', $widget), - $summary = $('.fivestar-summary', $obj), - feedbackTimerId = 0, - summaryText = $summary.html(), - summaryHover = $obj.is('.fivestar-labels-hover'), - currentValue = $("select", $obj).val(), - cancelTitle = $('label', $obj).html(), - voteTitle = cancelTitle != Drupal.settings.fivestar.titleAverage ? cancelTitle : Drupal.settings.fivestar.titleUser, - voteChanged = false; - - // Record star display. - if ($obj.is('.fivestar-user-stars')) { - var starDisplay = 'user'; - } - else if ($obj.is('.fivestar-average-stars')) { - var starDisplay = 'average'; - currentValue = $("input[name=vote_average]", $obj).val(); - } - else if ($obj.is('.fivestar-combo-stars')) { - var starDisplay = 'combo'; - } - else { - var starDisplay = 'none'; - } - - // Smart is intentionally separate, so the average will be set if necessary. - if ($obj.is('.fivestar-smart-stars')) { - var starDisplay = 'smart'; - } - - // Record text display. - if ($summary.size()) { - var textDisplay = $summary.attr('class').replace(/.*?fivestar-summary-([^ ]+).*/, '$1').replace(/-/g, '_'); - } - else { - var textDisplay = 'none'; - } - - // Add hover and focus events. - $stars - .mouseover(function(){ - event.drain(); - event.fill(this); - }) - .mouseout(function(){ - event.drain(); - event.reset(); - }); - $stars.children() - .focus(function(){ - event.drain(); - event.fill(this.parentNode) - }) - .blur(function(){ - event.drain(); - event.reset(); - }).end(); - - // Cancel button events. - $cancel - .mouseover(function(){ - event.drain(); - $(this).addClass('on') - }) - .mouseout(function(){ - event.reset(); - $(this).removeClass('on') - }); - $cancel.children() - .focus(function(){ - event.drain(); - $(this.parentNode).addClass('on') - }) - .blur(function(){ - event.reset(); - $(this.parentNode).removeClass('on') - }).end(); - - // Click events. - $cancel.click(function(){ - currentValue = 0; - event.reset(); - voteChanged = false; - // Inform a user that his vote is being processed - if ($("input.fivestar-path", $obj).size() && $summary.is('.fivestar-feedback-enabled')) { - setFeedbackText(Drupal.settings.fivestar.feedbackDeletingVote); - } - // Save the currentValue in a hidden field. - $("select", $obj).val(0); - // Update the title. - cancelTitle = starDisplay != 'smart' ? cancelTitle : Drupal.settings.fivestar.titleAverage; - $('label', $obj).html(cancelTitle); - // Update the smart classes on the widget if needed. - if ($obj.is('.fivestar-smart-text')) { - $obj.removeClass('fivestar-user-text').addClass('fivestar-average-text'); - $summary[0].className = $summary[0].className.replace(/-user/, '-average'); - textDisplay = $summary.attr('class').replace(/.*?fivestar-summary-([^ ]+).*/, '$1').replace(/-/g, '_'); - } - if ($obj.is('.fivestar-smart-stars')) { - $obj.removeClass('fivestar-user-stars').addClass('fivestar-average-stars'); - } - // Submit the form if needed. - $("input.fivestar-path", $obj).each(function() { - var token = $("input.fivestar-token", $obj).val(); - $.ajax({ - type: 'GET', - data: { token: token }, - dataType: 'xml', - url: this.value + '/' + 0, - success: voteHook - }); - }); - return false; - }); - $stars.click(function(){ - currentValue = $('select option', $obj).get($stars.index(this) + $cancel.size() + 1).value; - // Save the currentValue to the hidden select field. - $("select", $obj).val(currentValue); - // Update the display of the stars. - voteChanged = true; - event.reset(); - // Inform a user that his vote is being processed. - if ($("input.fivestar-path", $obj).size() && $summary.is('.fivestar-feedback-enabled')) { - setFeedbackText(Drupal.settings.fivestar.feedbackSavingVote); - } - // Update the smart classes on the widget if needed. - if ($obj.is('.fivestar-smart-text')) { - $obj.removeClass('fivestar-average-text').addClass('fivestar-user-text'); - $summary[0].className = $summary[0].className.replace(/-average/, '-user'); - textDisplay = $summary.attr('class').replace(/.*?fivestar-summary-([^ ]+).*/, '$1').replace(/-/g, '_'); - } - if ($obj.is('.fivestar-smart-stars')) { - $obj.removeClass('fivestar-average-stars').addClass('fivestar-user-stars'); - } - // Submit the form if needed. - $("input.fivestar-path", $obj).each(function () { - var token = $("input.fivestar-token", $obj).val(); - $.ajax({ - type: 'GET', - data: { token: token }, - dataType: 'xml', - url: this.value + '/' + currentValue, - success: voteHook - }); - }); - return false; - }); - - var event = { - fill: function(el){ - // Fill to the current mouse position. - var index = $stars.index(el) + 1; - $stars - .children('a').css('width', '100%').end() - .filter(':lt(' + index + ')').addClass('hover').end(); - // Update the description text and label. - if (summaryHover && !feedbackTimerId) { - var summary = $("select option", $obj)[index + $cancel.size()].text; - var value = $("select option", $obj)[index + $cancel.size()].value; - $summary.html(summary != index + 1 ? summary : ' '); - $('label', $obj).html(voteTitle); - } - }, - drain: function() { - // Drain all the stars. - $stars - .filter('.on').removeClass('on').end() - .filter('.hover').removeClass('hover').end(); - // Update the description text. - if (summaryHover && !feedbackTimerId) { - var cancelText = $("select option", $obj)[1].text; - $summary.html(($cancel.size() && cancelText != 0) ? cancelText : ' '); - if (!voteChanged) { - $('label', $obj).html(cancelTitle); - } - } - }, - reset: function(){ - // Reset the stars to the default index. - var starValue = currentValue/100 * $stars.size(); - var percent = (starValue - Math.floor(starValue)) * 100; - $stars.filter(':lt(' + Math.floor(starValue) + ')').addClass('on').end(); - if (percent > 0) { - $stars.eq(Math.floor(starValue)).addClass('on').children('a').css('width', percent + "%").end().end(); - } - // Restore the summary text and original title. - if (summaryHover && !feedbackTimerId) { - $summary.html(summaryText ? summaryText : ' '); - } - if (voteChanged) { - $('label', $obj).html(voteTitle); - } - else { - $('label', $obj).html(cancelTitle); - } - } - }; - - var setFeedbackText = function(text) { - // Kill previous timer if it isn't finished yet so that the text we - // are about to set will not get cleared too early. - feedbackTimerId = 1; - $summary.html(text); - }; - - /** - * Checks for the presence of a javascript hook 'fivestarResult' to be - * called upon completion of a AJAX vote request. - */ - var voteHook = function(data) { - var returnObj = { - result: { - count: $("result > count", data).text(), - average: $("result > average", data).text(), - summary: { - average: $("summary average", data).text(), - average_count: $("summary average_count", data).text(), - user: $("summary user", data).text(), - user_count: $("summary user_count", data).text(), - combo: $("summary combo", data).text(), - count: $("summary count", data).text() - } - }, - vote: { - id: $("vote id", data).text(), - tag: $("vote tag", data).text(), - type: $("vote type", data).text(), - value: $("vote value", data).text() - }, - display: { - stars: starDisplay, - text: textDisplay - } - }; - // Check for a custom callback. - if (window.fivestarResult) { - fivestarResult(returnObj); - } - // Use the default. - else { - fivestarDefaultResult(returnObj); - } - // Update the summary text. - summaryText = returnObj.result.summary[returnObj.display.text]; - if ($(returnObj.result.summary.average).is('.fivestar-feedback-enabled')) { - // Inform user that his/her vote has been processed. - if (returnObj.vote.value != 0) { // check if vote has been saved or deleted - setFeedbackText(Drupal.settings.fivestar.feedbackVoteSaved); - } - else { - setFeedbackText(Drupal.settings.fivestar.feedbackVoteDeleted); - } - // Setup a timer to clear the feedback text after 3 seconds. - feedbackTimerId = setTimeout(function() { clearTimeout(feedbackTimerId); feedbackTimerId = 0; $summary.html(returnObj.result.summary[returnObj.display.text]); }, 2000); - } - // Update the current star currentValue to the previous average. - if (returnObj.vote.value == 0 && (starDisplay == 'average' || starDisplay == 'smart')) { - currentValue = returnObj.result.average; - event.reset(); - } - }; - - event.reset(); - return $widget; - }; - - /** - * Accepts jQuery object containing a single fivestar widget. - * Returns the proper div structure for the star interface. - * - * @return jQuery - * @param {Object} $widget - * - */ - var buildInterface = function($widget){ - var $container = $('
'); - var $options = $("select option", $widget); - var size = $('option', $widget).size() - 1; - var cancel = 1; - for (var i = 1, option; option = $options[i]; i++){ - if (option.value == "0") { - cancel = 0; - $div = $(''); - } - else { - var zebra = (i + cancel - 1) % 2 == 0 ? 'even' : 'odd'; - var count = i + cancel - 1; - var first = count == 1 ? ' star-first' : ''; - var last = count == size + cancel - 1 ? ' star-last' : ''; - $div = $(''); - } - $container.append($div[0]); - } - $container.addClass('fivestar-widget-' + (size + cancel - 1)); - // Attach the new widget and hide the existing widget. - $('select', $widget).after($container).css('display', 'none'); - return $container; - }; - - /** - * Standard handler to update the average rating when a user changes their - * vote. This behavior can be overridden by implementing a fivestarResult - * function in your own module or theme. - * @param object voteResult - * Object containing the following properties from the vote result: - * voteResult.result.count The current number of votes for this item. - * voteResult.result.average The current average of all votes for this item. - * voteResult.result.summary.average The textual description of the average. - * voteResult.result.summary.user The textual description of the user's current vote. - * voteResult.vote.id The id of the item the vote was placed on (such as the nid) - * voteResult.vote.type The type of the item the vote was placed on (such as 'node') - * voteResult.vote.tag The multi-axis tag the vote was placed on (such as 'vote') - * voteResult.vote.average The average of the new vote saved - * voteResult.display.stars The type of star display we're using. Either 'average', 'user', or 'combo'. - * voteResult.display.text The type of text display we're using. Either 'average', 'user', or 'combo'. - */ - function fivestarDefaultResult(voteResult) { - // Update the summary text. - $('div.fivestar-summary-'+voteResult.vote.tag+'-'+voteResult.vote.id).html(voteResult.result.summary[voteResult.display.text]); - // If this is a combo display, update the average star display. - if (voteResult.display.stars == 'combo') { - $('div.fivestar-form-'+voteResult.vote.id).each(function() { - // Update stars. - var $stars = $('.fivestar-widget-static .star span', this); - var average = voteResult.result.average/100 * $stars.size(); - var index = Math.floor(average); - $stars.removeClass('on').addClass('off').css('width', 'auto'); - $stars.filter(':lt(' + (index + 1) + ')').removeClass('off').addClass('on'); - $stars.eq(index).css('width', ((average - index) * 100) + "%"); - // Update summary. - var $summary = $('.fivestar-static-form-item .fivestar-summary', this); - if ($summary.size()) { - var textDisplay = $summary.attr('class').replace(/.*?fivestar-summary-([^ ]+).*/, '$1').replace(/-/g, '_'); - $summary.html(voteResult.result.summary[textDisplay]); - } - }); +(function($){ + +Drupal.behaviors.fivestar = { + attach: function(context, settings) { + $('div.fivestar-form-item', context).once('fivestar', function() { + var $this = $(this); + var $container = $('
'); + var $select = $('select', $this); + + // Setup the cancel button + var $cancel = $('option[value="0"]', $this); + if ($cancel.length) { + $('') + .appendTo($container); } - }; - - /** - * Set up the plugin - */ - $.fn.fivestar = function() { - var stack = []; - this.each(function() { - var ret = buildRating($(this)); - stack.push(ret); + + // Setup the rating buttons + var $options = $('option', $this).not('[value="-"], [value="0"]'); + $options.each(function(i, element) { + var classes = 'star-' + (i+1); + classes += (i + 1) % 2 == 0 ? ' even' : ' odd'; + classes += i == 0 ? ' star-first' : ''; + classes += i + 1 == $options.length ? ' star-last' : ''; + $('') + .addClass(classes) + .appendTo($container); }); - return stack; - }; - - // Fix ie6 background flicker problem. - if ($.browser.msie == true) { - try { - document.execCommand('BackgroundImageCache', false, true); - } catch(err) {} - } - - Drupal.behaviors.fivestar = { - attach: function(context) { - $('div.fivestar-form-item:not(.fivestar-processed)', context).addClass('fivestar-processed').fivestar(); - $('input.fivestar-submit', context).css('display', 'none'); + + Drupal.behaviors.fivestar.updateDisplay($('a[href=#' + $select.val() + ']', $container), $container); + + $container.addClass('fivestar-widget-' + ($options.length)); + $container.find('a') + .bind('click', this, Drupal.behaviors.fivestar.rate) + .bind('mouseover', $this, Drupal.behaviors.fivestar.hover); + + $container.bind('mouseover mouseout', $this, Drupal.behaviors.fivestar.hover); + + // Attach the new widget and hide the existing widget. + $select.after($container).css('display', 'none'); + }); + }, + rate: function(event) { + var $this = $(this); + var $widget = event.data; + var value = this.hash.replace('#', ''); + $('select', $widget).val(value).change(); + + Drupal.behaviors.fivestar.updateDisplay($this, $widget); + }, + hover: function(event) { + var $this = $(this); + var $widget = event.data; + var $target = $(event.target); + var $stars = $('.star', $this); + + if (event.type == 'mouseover') { + var index = $stars.index($target.parent()); + $stars.each(function(i, element) { + if (i <= index) { + $(element).addClass('hover'); + } else { + $(element).removeClass('hover'); + } + }); + } else { + $stars.removeClass('hover'); } + }, + updateDisplay: function($star, $widget) { + var $links = $('a', $widget).not('a.cancel'); + var index = $links.index($star); + $links.each(function (i, element) { + if (i <= index) { + $(this).parent().addClass('on'); + } else { + $(this).parent().removeClass('on'); + } + }); } +}; + +if (typeof Drupal.ajax != 'undefined') { + Drupal.ajax.prototype.commands.fivestarUpdate = function (ajax, response, status) { + response.selector = $('.fivestar-form-item', ajax.form); + response.method = 'replaceWith'; + ajax.commands.insert(ajax, response, status); + }; +} + })(jQuery); -- 1.7.4.msysgit.0