3 * TRatingList class file.
5 * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
6 * @link https://github.com/pradosoft/prado
7 * @copyright Copyright © 2005-2016 The PRADO Group
8 * @license https://github.com/pradosoft/prado/blob/master/COPYRIGHT
9 * @package System.Web.UI.WebControls
13 * Includes TRadioButtonList class
15 Prado::using('System.Web.UI.WebControls.TRadioButtonList');
20 * This class is EXPERIMENTAL.
22 * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
23 * @author Bradley Booms <bradley[dot]booms[at]gmail[dot]com>
24 * @package System.Web.UI.WebControls
27 class TRatingList extends TRadioButtonList
30 * Script path relative to the TClientScriptManager::SCRIPT_PATH
32 const SCRIPT_PATH='prado/ratings';
35 * @var array list of published rating images.
37 private $_ratingImages = array();
40 * Sets the default repeat direction to horizontal.
42 public function __construct()
44 parent::__construct();
45 $this->setRepeatDirection(TRepeatDirection::Horizontal);
49 * @return boolean whether the items in the column can be edited. Defaults to false.
51 public function getReadOnly()
53 return $this->getViewState('ReadOnly',false);
57 * @param boolean whether the items in the column can be edited
59 public function setReadOnly($value)
61 $this->setViewState('ReadOnly',TPropertyValue::ensureBoolean($value),false);
65 * Wrapper for {@link setReadOnly ReadOnly} property.
66 * @return boolean whether the rating list can be edited. Defaults to true.
68 public function getAllowInput()
70 return !$this->getReadOnly();
74 * Wrapper for {@link setReadOnly ReadOnly} property.
75 * @param boolean whether the rating list can be edited
77 public function setAllowInput($value)
79 $this->setReadOnly(!TPropertyValue::ensureBoolean($value));
83 * Wrapper for {@link setReadOnly ReadOnly} property.
84 * @param boolean whether the rating list can be edited
86 public function setEnabled($value)
88 $this->setReadOnly(!TPropertyValue::ensureBoolean($value));
92 * The repeat layout must be Table.
93 * @param string repeat layout type
94 * @throws TInvaliddataValueException when repeat layout is not Table.
96 public function setRepeatLayout($value)
98 if($value!==TRepeatLayout::Table)
99 throw new TInvalidDataValueException('ratinglist_table_layout_only');
101 parent::setRepeatLayout($value);
105 * @return float rating value.
107 public function getRating()
109 $rating = $this->getViewState('Rating', null);
110 if ($rating === null)
111 return $this->getSelectedIndex()+1;
117 * @param float rating value, also sets the selected Index
119 public function setRating($value)
121 $value = TPropertyValue::ensureFloat($value);
122 $this->setViewState('Rating', $value, null);
123 $index = $this->getRatingIndex($value);
124 parent::setSelectedIndex($index);
127 public function setSelectedIndex($value)
129 $this->setRating($value+1);
130 parent::setSelectedIndex($value);
134 * @param float rating value
135 * @return int rating as integer
137 protected function getRatingIndex($rating)
139 $interval = $this->getHalfRatingInterval();
140 $base = intval($rating)-1;
141 $remainder = $rating-$base-1;
142 return $remainder > $interval[1] ? $base+1 : $base;
146 * @param int change the rating selection index
148 public function onSelectedIndexChanged($param)
150 $value = $this->getRating();
151 $value = TPropertyValue::ensureInteger($value);
152 $this->setRating($value);
153 parent::onSelectedIndexChanged($param);
157 * @return string control or html element ID for displaying a caption.
159 public function getCaptionID()
161 return $this->getViewState('CaptionID', '');
165 * @param string control or html element ID for displaying a caption.
167 public function setCaptionID($value)
169 $this->setViewState('CaptionID', $value, '');
172 protected function getCaptionControl()
174 if(($id=$this->getCaptionID())!=='')
176 if($control=$this->getPage()->findControl($id))
178 if($control=$this->getNamingContainer()->findControl($id))
181 throw new TInvalidDataValueException(
182 'ratinglist_invalid_caption_id',$id,$this->getID());
186 * @return string caption text. Default is "Rate It:".
188 public function getCaption()
190 return $this->getCaptionControl()->getText();
194 * @return TRatingListStyle current rating style
196 public function setCaption($value)
198 $this->getCaptionControl()->setText($value);
202 * @param string set the rating style, default is "default"
204 public function setRatingStyle($value)
206 $this->setViewState('RatingStyle', $value, 'default');
210 * @return TRatingListStyle current rating style
212 public function getRatingStyle()
214 return $this->getViewState('RatingStyle', 'default');
218 * @return string rating style css class name.
220 protected function getRatingStyleCssClass()
222 return 'TRatingList_'.$this->getRatingStyle();
226 * Sets the interval such that those rating values within the interval
227 * will be considered as a half star rating.
228 * @param array rating display half value interval, default is array(0.3, 0.7);
230 public function setHalfRatingInterval($value)
232 $this->setViewState('HalfRating',
233 TPropertyValue::ensureArray($value), array(0.3, 0.7));
237 * @return array rating display half value interval, default is array(0.3, 0.7);
239 public function getHalfRatingInterval()
241 return $this->getViewState('HalfRating', array(0.3, 0.7));
245 * @return array list of post back options.
247 protected function getPostBackOptions()
249 $options = parent::getPostBackOptions();
250 $options['AutoPostBack'] = $this->getAutoPostBack();
251 $options['ReadOnly'] = $this->getReadOnly();
252 $options['Style'] = $this->getRatingStyleCssClass();
253 $options['CaptionID'] = $this->getCaptionControlID();
254 $options['SelectedIndex'] = $this->getSelectedIndex();
255 $options['Rating'] = $this->getRating();
256 $options['HalfRating'] = $this->getHalfRatingInterval();
261 * @return string find the client ID of the caption control.
263 protected function getCaptionControlID()
265 if(($id=$this->getCaptionID())!=='')
267 if($control=$this->getParent()->findControl($id))
269 if($control->getVisible(true))
270 return $control->getClientID();
279 * Publish the the rating style css file and rating image files.
281 public function onPreRender($param)
283 parent::onPreRender($param);
284 $this->publishStyle($this->getRatingStyle());
285 $this->_ratingImages = $this->publishImages($this->getRatingStyle());
286 $this->registerClientScript();
290 * @param string rating style name
291 * @return string URL of the css style file
293 protected function publishStyle($style)
295 $cs = $this->getPage()->getClientScript();
296 $url = $this->getAssetUrl($style.'.css');
297 if(!$cs->isStyleSheetFileRegistered($url))
298 $cs->registerStyleSheetFile($url, $url);
303 * @param string rating style name
304 * @param string rating image file extension, default is '.gif'
305 * @return array URL of publish the rating images
307 protected function publishImages($style, $fileExt='.gif')
309 $types = array('blank', 'selected', 'half', 'combined');
311 foreach($types as $type)
312 $files[$type] = $this->getAssetUrl("{$style}_{$type}{$fileExt}");
317 * Registers the relevant JavaScript.
319 protected function registerClientScript()
321 $cs=$this->getPage()->getClientScript();
322 $cs->registerPradoScript('ratings');
326 * @param string asset file in the self::SCRIPT_PATH directory.
327 * @return string asset file url.
329 protected function getAssetUrl($file='')
331 $base = $this->getPage()->getClientScript()->getPradoScriptAssetUrl();
332 return $base.'/'.self::SCRIPT_PATH.'/'.$file;
336 * Add rating style class name to the class attribute
337 * when {@link setReadOnly ReadOnly} property is true and when the
338 * {@link setCssClass CssClass} property is empty.
339 * @param THtmlWriter renderer
341 public function render($writer)
343 $writer->addAttribute('id',$this->getClientID());
344 $this->getPage()->getClientScript()->registerPostBackControl(
345 $this->getClientClassName(), $this->getPostBackOptions());
346 parent::render($writer);
350 * Gets the name of the javascript class responsible for performing postback for this control.
351 * This method overrides the parent implementation.
352 * @return string the javascript class name
354 protected function getClientClassName()
356 return 'Prado.WebUI.TRatingList';