From 15161da7755a8d74853ccae0966afa22d9830b07 Mon Sep 17 00:00:00 2001 From: "Christophe.Boulain" <> Date: Sat, 8 Nov 2008 17:41:48 +0000 Subject: Issue#36: Refactored TRatingList/TActiveRatingList, and added some docs. --- framework/Web/UI/WebControls/TRatingList.php | 347 ++++++++++++++++++--------- 1 file changed, 238 insertions(+), 109 deletions(-) (limited to 'framework/Web/UI/WebControls') diff --git a/framework/Web/UI/WebControls/TRatingList.php b/framework/Web/UI/WebControls/TRatingList.php index 85e7f66c..aba44fb0 100644 --- a/framework/Web/UI/WebControls/TRatingList.php +++ b/framework/Web/UI/WebControls/TRatingList.php @@ -4,7 +4,7 @@ * * @author Wei Zhuo * @link http://www.pradosoft.com/ - * @copyright Copyright © 2005-2008 PradoSoft + * @copyright Copyright © 2005-2008 PradoSoft * @license http://www.pradosoft.com/license/ * @version $Id$ * @package System.Web.UI.WebControls @@ -21,191 +21,320 @@ Prado::using('System.Web.UI.WebControls.TRadioButtonList'); * This class is EXPERIMENTAL. * * @author Wei Zhuo + * @author Bradley Booms * @version $Id$ * @package System.Web.UI.WebControls * @since 3.0 */ class TRatingList extends TRadioButtonList { + /** + * Script path relative to the TClientScriptManager::SCRIPT_PATH + */ const SCRIPT_PATH='prado/ratings'; + /** + * @var array list of published rating images. + */ private $_ratingImages = array(); + /** + * Sets the default repeat direction to horizontal. + */ public function __construct() { parent::__construct(); - $this->getRepeatInfo()->setRepeatDirection('Horizontal'); + $this->setRepeatDirection(TRepeatDirection::Horizontal); } + /** + * @return boolean whether the items in the column can be edited. Defaults to false. + */ + public function getReadOnly() + { + return $this->getViewState('ReadOnly',false); + } + + /** + * @param boolean whether the items in the column can be edited + */ + public function setReadOnly($value) + { + $this->setViewState('ReadOnly',TPropertyValue::ensureBoolean($value),false); + } + + /** + * Wrapper for {@link setReadOnly ReadOnly} property. + * @return boolean whether the rating list can be edited. Defaults to true. + */ public function getAllowInput() { - return $this->getViewState('AllowInput', true); + return !$this->getReadOnly(); } + /** + * Wrapper for {@link setReadOnly ReadOnly} property. + * @param boolean whether the rating list can be edited + */ public function setAllowInput($value) { - $this->setViewState('AllowInput', TPropertyValue::ensureBoolean($value), true); + $this->setReadOnly(!TPropertyValue::ensureBoolean($value)); } - public function getRating() + /** + * Wrapper for {@link setReadOnly ReadOnly} property. + * @param boolean whether the rating list can be edited + */ + public function setEnabled($value) { - if($this->getAllowInput()) - return $this->getSelectedIndex(); - else - return $this->getViewState('Rating',0); + $this->setReadOnly(!TPropertyValue::ensureBoolean($value)); } - public function setRating($value) + /** + * The repeat layout must be Table. + * @param string repeat layout type + * @throws TInvaliddataValueException when repeat layout is not Table. + */ + public function setRepeatLayout($value) { - if($this->getAllowInput()) - $this->setSelectedIndex($value); + if($value!==TRepeatLayout::Table) + throw new TInvalidDataValueException('ratinglist_table_layout_only'); else - $this->setViewState('Rating', TPropertyValue::ensureFloat($value),0); + parent::setRepeatLayout($value); } /** - * @param string set the rating style + * @return float rating value. */ - public function setRatingStyle($value) + public function getRating() { - $this->setViewState('RatingStyle', $value, 'default'); + $rating = $this->getViewState('Rating', null); + if ($rating === null) + return $this->getSelectedIndex()+1; + else + return $rating; } /** - * @return TRatingListStyle current rating style + * @param float rating value, also sets the selected Index */ - public function getRatingStyle() + public function setRating($value) { - return $this->getViewState('RatingStyle', 'default'); + $value = TPropertyValue::ensureFloat($value); + $this->setViewState('Rating', $value, null); + $index = $this->getRatingIndex($value); + parent::setSelectedIndex($index); + } + + public function setSelectedIndex($value) + { + $this->setRating($value+1); + parent::setSelectedIndex($value); } /** - * @return string caption text. Default is "Rate It:". + * @param float rating value + * @return int rating as integer */ - public function getCaption() + protected function getRatingIndex($rating) { - return $this->getViewState('Caption', 'Rate It:'); + $interval = $this->getHalfRatingInterval(); + $base = intval($rating)-1; + $remainder = $rating-$base-1; + return $remainder > $interval[1] ? $base+1 : $base; } /** - * @param string caption text + * @param int change the rating selection index */ - public function setCaption($value) + public function onSelectedIndexChanged($param) { - $this->setViewState('Caption', $value, 'Rate It:'); + $value = $this->getRating(); + $value = TPropertyValue::ensureInteger($value); + $this->setRating($value); + parent::onSelectedIndexChanged($param); } + /** + * @return string control or html element ID for displaying a caption. + */ + public function getCaptionID() + { + return $this->getViewState('CaptionID', ''); + } - public function setHalfRatingLimit($value) + /** + * @param string control or html element ID for displaying a caption. + */ + public function setCaptionID($value) { - $this->setViewState('HalfRating', - TPropertyValue::ensureArray($value), array(0.3, 0.7)); + $this->setViewState('CaptionID', $value, ''); } - public function getHalfRatingLimit() + protected function getCaptionControl() { - return $this->getViewState('HalfRating', array(0.3, 0.7)); + if(($id=$this->getCaptionID())!=='') + { + if($control=$this->getParent()->findControl($id)) + return $control; + } + throw new TInvalidDataValueException( + 'ratinglist_invalid_caption_id',$id,$this->getID()); } /** - * @param string asset file in the self::SCRIPT_PATH directory. - * @return string asset file url. + * @return string caption text. Default is "Rate It:". */ - protected function getAssetUrl($file='') + public function getCaption() { - $base = $this->getPage()->getClientScript()->getPradoScriptAssetUrl(); - return $base.'/'.self::SCRIPT_PATH.'/'.$file; + return $this->getCaptionControl()->getText(); } - public function getRatingClientOptions() - { - $options['cssClass'] = 'TRatingList_'.$this->getRatingStyle(); - $options['ID'] = $this->getClientID(); - $options['caption'] = $this->getCaption(); - $options['field'] = $this->getUniqueID(); - $options['selectedIndex'] = $this->getSelectedIndex(); + /** + * @return TRatingListStyle current rating style + */ + public function setCaption($value) + { + $this->getCaptionControl()->setText($value); + } + + /** + * @param string set the rating style, default is "default" + */ + public function setRatingStyle($value) + { + $this->setViewState('RatingStyle', $value, 'default'); + } + + /** + * @return TRatingListStyle current rating style + */ + public function getRatingStyle() + { + return $this->getViewState('RatingStyle', 'default'); + } + + /** + * @return string rating style css class name. + */ + protected function getRatingStyleCssClass() + { + return 'TRatingList_'.$this->getRatingStyle(); + } + + /** + * Sets the interval such that those rating values within the interval + * will be considered as a half star rating. + * @param array rating display half value interval, default is array(0.3, 0.7); + */ + public function setHalfRatingInterval($value) + { + $this->setViewState('HalfRating', + TPropertyValue::ensureArray($value), array(0.3, 0.7)); + } + + /** + * @return array rating display half value interval, default is array(0.3, 0.7); + */ + public function getHalfRatingInterval() + { + return $this->getViewState('HalfRating', array(0.3, 0.7)); + } + + /** + * @return array list of post back options. + */ + protected function getPostBackOptions() + { + $options = parent::getPostBackOptions(); + $options['AutoPostBack'] = $this->getAutoPostBack(); + $options['ReadOnly'] = $this->getReadOnly(); + $options['Style'] = $this->getRatingStyleCssClass(); + $options['CaptionID'] = $this->getCaptionControlID(); + $options['SelectedIndex'] = $this->getSelectedIndex(); + $options['Rating'] = $this->getRating(); + $options['HalfRating'] = $this->getHalfRatingInterval(); return $options; - } + } - protected function publishRatingListStyle($style) - { + /** + * @return string find the client ID of the caption control. + */ + protected function getCaptionControlID() + { + if(($id=$this->getCaptionID())!=='') + { + if($control=$this->getParent()->findControl($id)) + { + if($control->getVisible(true)) + return $control->getClientID(); + } + else + return $id; + } + return ''; + } + + /** + * Publish the the rating style css file and rating image files. + */ + public function onPreRender($param) + { + parent::onPreRender($param); + $this->publishStyle($this->getRatingStyle()); + $this->_ratingImages = $this->publishImages($this->getRatingStyle()); + } + + /** + * @param string rating style name + * @return string URL of the css style file + */ + protected function publishStyle($style) + { $cs = $this->getPage()->getClientScript(); $url = $this->getAssetUrl($style.'.css'); if(!$cs->isStyleSheetFileRegistered($url)) $cs->registerStyleSheetFile($url, $url); return $url; - } + } - protected function publishRatingListImages($style, $fileExt='.gif') - { - $images = array('blank', 'hover', 'selected', 'half'); + /** + * @param string rating style name + * @param string rating image file extension, default is '.gif' + * @return array URL of publish the rating images + */ + protected function publishImages($style, $fileExt='.gif') + { + $types = array('blank', 'selected', 'half', 'combined'); $files = array(); - foreach($images as $type) + foreach($types as $type) $files[$type] = $this->getAssetUrl("{$style}_{$type}{$fileExt}"); return $files; - } + } /** - * @param THtmlWriter writer + * @param string asset file in the self::SCRIPT_PATH directory. + * @return string asset file url. */ - public function onPreRender($param) - { - parent::onPreRender($param); - - $this->publishRatingListStyle($this->getRatingStyle()); - $this->_ratingImages = $this->publishRatingListImages($this->getRatingStyle()); - - if($this->getAllowInput()) - $this->registerRatingListClientScript(); - else - { - $this->getRepeatInfo()->setCaption($this->getCaption()); - $this->setAttribute('title', $this->getRating()); - } - } - - protected function registerRatingListClientScript() - { - $id = $this->getClientID(); - $scripts = $this->getPage()->getClientScript(); - $scripts->registerPradoScript('prado'); - $options = TJavaScript::encode($this->getRatingClientOptions()); - $code = "new Prado.WebUI.TRatingList($options);"; - $scripts->registerEndScript("prado:$id", $code); - } - - public function renderItem($writer,$repeatInfo,$itemType,$index) - { - if($this->getAllowInput()) - parent::renderItem($writer, $repeatInfo, $itemType, $index); - else - $this->renderRatingListItem($writer, $repeatInfo, $itemType, $index); - } - - protected function renderRatingListItem($writer, $repeatInfo, $itemType, $index) - { - $image = new TImage; - $image->setImageUrl($this->_ratingImages[$this->getRatingImageType($index)]); - $image->setAlternateText($this->getRating()); - $image->render($writer); - } - - protected function getRatingImageType($index) - { - $rating = floatval($this->getRating()); - $int = intval($rating); - $limit = $this->getHalfRatingLimit(); - if($index < $int || ($rating < $index + 1 && $rating > $index +$limit[1])) - return 'selected'; - if($rating >= $index+$limit[0] && $rating <= $index+$limit[1]) - return 'half'; - return 'blank'; - } + protected function getAssetUrl($file='') + { + $base = $this->getPage()->getClientScript()->getPradoScriptAssetUrl(); + return $base.'/'.self::SCRIPT_PATH.'/'.$file; + } - public function generateItemStyle($itemType,$index) - { - return new TStyle; - } + /** + * Add rating style class name to the class attribute + * when {@link setReadOnly ReadOnly} property is true and when the + * {@link setCssClass CssClass} property is empty. + * @param THtmlWriter renderer + */ + public function render($writer) + { + $writer->addAttribute('id',$this->getClientID()); + $this->getPage()->getClientScript()->registerPostBackControl( + $this->getClientClassName(), $this->getPostBackOptions()); + parent::render($writer); + } /** * Gets the name of the javascript class responsible for performing postback for this control. -- cgit v1.2.3