YiiWheels
  • Package
  • Class
  • Tree

Packages

  • yiiwheels
    • behaviors
    • widgets
    • widgets
      • ace
      • box
      • datepicker
      • daterangepicker
      • datetimepicker
      • detail
      • editable
      • fileupload
      • fileuploader
      • formhelpers
      • gallery
      • google
      • grid
        • behaviors
        • operations
      • highcharts
      • maskInput
      • maskmoney
      • modal
      • multiselect
      • rangeslider
      • redactor
      • select2
      • sparklines
      • switch
      • timeago
      • timepicker
      • toggle
      • typeahead

Classes

  • WhRangeSlider
  1 <?php
  2 /**
  3  * WhDateRangePicker widget class
  4  * Implementation of jQRangeSlider. A powerful slider for selecting value ranges, supporting dates and more.
  5  * @see http://ghusse.github.io/jQRangeSlider
  6  *
  7  * @author Antonio Ramirez <amigo.cobos@gmail.com>
  8  * @copyright Copyright &copy; 2amigos.us 2013-
  9  * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
 10  * @package YiiWheels.widgets.rangeslider
 11  * @uses YiiStrap.helpers.TbArray
 12  */
 13 Yii::import('bootstrap.helpers.TbArray');
 14 
 15 class WhRangeSlider extends CInputWidget
 16 {
 17 
 18     /**
 19      * @var string lets you specify what type of jQRangeSlider you wish to display. Defaults to "range". Possible values
 20      * are:
 21      * - 'range'
 22      * - 'editRange'
 23      * - 'dateRange'
 24      */
 25     public $type = 'range';
 26 
 27     /**
 28      * @var bool lets you remove scrolling arrows on both sides of the slider. Defaults to true.
 29      */
 30     public $arrows = true;
 31 
 32     /**
 33      * @var mixed lets you specify the min bound value of the range. This value Defaults to 0.
 34      * <strong>Note</strong> when using 'dateRange' type, this value can be string representing a javascript date. For
 35      * example: `'minValue'=>'js:new Date( 2012, 0, 1)`'
 36      */
 37     public $minValue = 0;
 38 
 39     /**
 40      * @var mixed lets you specify the max bound value of the range. This value Defaults to 100.
 41      * <strong>Note</strong> when using 'dateRange' type, this value can be a string representing a javascript date. For
 42      * example: `'maxValue'=>'js:new Date( 2012, 0, 1)`'
 43      */
 44     public $maxValue = 100;
 45 
 46     /**
 47      * @var mixed lets you specify min value by default on construction of the widget. Defaults to 0.
 48      * <strong>Note</strong> when  using 'dateRange' type, this value can be a string representing a javascript date. For
 49      * example: `'minDefaultValue'=>'js:new Date( 2012, 0, 1)`'
 50      */
 51     public $minDefaultValue = 0;
 52 
 53     /**
 54      * @var mixed lets you specify max valuee by default on construction of the widget. Defaults to 100.
 55      * <strong>Note</strong> when  using 'dateRange' type, this value can be a string representing a javascript date. For
 56      * example: `'minDefaultValue'=>'js:new Date( 2012, 0, 1)`'
 57      */
 58     public $maxDefaultValue = 100;
 59 
 60     /**
 61      * @var int lets you specify the duration labels are shown after the user changed its values. Defaults to null.
 62      * <strong>Note</strong>: This option can only be used in conjunction with `'valueLabels'=>'change'`
 63      */
 64     public $delayOut;
 65 
 66     /**
 67      * @var int lets you specify the animation length when displaying value labels. Similarly,`durationOut` allows to
 68      * customize the animation duration when hiding those labels. Defaults to null.
 69      * <strong>Note</strong>: This option can only be used in conjunction with `'valueLabels'=>'change'`
 70      */
 71     public $durationIn;
 72 
 73     /**
 74      * @var int lets you specify the animation length when hiding value labels. Similarly,`durationIn` allows to
 75      * customize the animation duration when displaying those labels. Defaults to null.
 76      * <strong>Note</strong>: This option can only be used in conjunction with `'valueLabels'=>'change'`
 77      */
 78     public $durationOut;
 79 
 80     /**
 81      * @var string a javascript function that lets you customize displayed label text.
 82      * Example:
 83      * ```
 84      *   'formater'=>'js:function(val){
 85     var value = Math.round(val * 5) / 5,
 86      *      decimal = value - Math.round(val);
 87      *      return decimal == 0 ? value.toString() + ".0" : value.toString();
 88      *   }'
 89      */
 90     public $formatter;
 91 
 92     /**
 93      * @var int lets you specify minimum range length. It works in conjunction with `maxRange`.
 94      * For instance, let's consider you want the user to choose a range of dates during 2012. You can constraint people
 95      * to choose at least 1 week during this period. Similarly, you also can constraint the user to choose 90 days at
 96      * maximum.
 97      * When this option is activated, the slider constraints the user input. When minimum or maximum value is reached,
 98      * the user cannot move an extremity further to shrink/enlarge the selected range.
 99      */
100     public $minRange = 0;
101 
102     /**
103      * @var int see `minRange` documentation above.
104      */
105     public $maxRange = 100;
106 
107     /**
108      * @var int allows to customize values rounding, and graphically render this rounding. Considering you configured a
109      * slider with a step value of 10: it'll only allow your user to choose a value corresponding to minBound + 10n.
110      * <strong>Warning</strong> For the date slider there is a small variation, the following is an example with days:
111      *
112      * ```
113      *  \\...
114      *  'step'=>array('days'=>2)
115      *  \\...
116      */
117     public $step;
118 
119     /**
120      * @var string allows to specify input types in edit slider. Possible values are 'text' (default) and 'number'.
121      * <strong>Note</strong>: This option is only available on `editRange` `type`.
122      */
123     public $inputType = 'text';
124 
125     /**
126      * @var string lets you specify a display mode for value labels: `hidden`, `shown`, or only shown when moving.
127      * Possible values are: show, hide and change.
128      */
129     public $valueLabels = 'shown';
130 
131     /**
132      * @var string allows to use the mouse wheel to `scroll` (translate) or `zoom` (enlarge/shrink) the selected area in
133      * jQRangeSlider. Defaults to null.
134      * <strong>Note</strong>: This option requires the plugin `jquery mousehwheel to be loaded`
135      */
136     public $wheelMode;
137 
138     /**
139      * @var int lets you customize the speed of mouse wheel interactions. This parameter requires the `wheelMode` to be set.
140      */
141     public $wheelSpeed;
142 
143     /**
144      * @var array The option scales lets you add a ruler with multiple scales to the slider background.
145      *
146      *
147      * ```
148      * 'scales' => array(
149      *      // primary scale
150      *      array(
151      *          'first'=>'js:function(val){return val;},
152      *          'next'=>'js:function(val){return val+10;}',
153      *          'stop'=>'js:function(val){return false;}',
154      *          'label'=>'js:function(val){return val;}',
155      *          'format'=> 'js:function(tickContainer, tickStart, tickEnd){
156      *              tickContainer.addClass("myCustomClass");
157      *          }'
158      *      ),
159      *      // secondary scale
160      *      array(
161      *          'first'=>'js:function(val){return val;},
162      *          'next'=>'js:function(val){ if(val%10 === 9){return val+2;} return val + 1;}',
163      *          'stop'=>'js:function(val){return false;}',
164      *          'label'=>'js:function(val){return null;}',
165      *      ),
166      *  )
167      * ```
168      */
169     public $scales;
170 
171     /**
172      * @var array string[] the events to monitor.
173      *
174      * Possible events:
175      * - valuesChanging
176      * - valuesChanged
177      * - userValuesChanged
178      *
179      * ### valuesChanging
180      * Use the event valuesChanging if you want to intercept events while the user is moving an element in the slider.
181      * Warning: Use this event wisely, because it is fired very frequently. It can have impact on performance. When
182      * possible, prefer the `valuesChanged` event.
183      *
184      * ```
185      * 'events' => array(
186      *      "valuesChanging"=>'js:function(e, data){ console.log("Something moved. min: " + data.values.min +
187      *      " max: " + data.values.max);})'
188      *  )
189      * ```
190      *
191      * ### valuesChanged
192      * Use the event `valuesChanged` when you want to intercept events once values are chosen.
193      * This event is only triggered once after a move.
194      *
195      * ```
196      * 'events' => array(
197      *       "valuesChanged", 'js:function(e, data){
198      *          console.log("Values just changed. min: " + data.values.min + " max: " + data.values.max);
199      *      }'
200      * )
201      * ````
202      *
203      * ### userValuesChanged
204      * Like the `valuesChanged` event, the `userValuesChanged` is fired after values finished changing. But, unlike the
205      * previous one, `userValuesChanged` is only fired after the user interacted with the slider. <strong>Not when you changed
206      * values programmatically</strong>.
207      *
208      * ```
209      *   'events' => array(
210      *       "userValuesChanged", 'js:function(e, data){
211      *          console.log("This changes when user interacts with slider");
212      *      }'
213      * )
214      * ```
215      */
216     public $events;
217 
218     /**
219      * @var string the theme to use with the slider. Supported values are "iThing" and "classic"
220      */
221     public $theme = 'iThing';
222 
223     /**
224      * @var array the options to pass to the jQSlider
225      */
226     protected $options;
227 
228     /**
229      * Widget's initialization
230      */
231     public function init()
232     {
233 
234         $this->checkOptionAttribute($this->type, array('range', 'editRange', 'dateRange'), 'type');
235 
236         $this->checkOptionAttribute($this->inputType, array('text', 'number'), 'inputType');
237 
238         $this->checkOptionAttribute($this->valueLabels, array('shown', 'hidden'), 'valueLabels');
239 
240         $this->checkOptionAttribute($this->theme, array('iThing', 'classic'), 'theme');
241 
242         if($this->wheelMode)
243         {
244             $this->checkOptionAttribute($this->wheelMode, array('zoom', 'scroll'), 'wheelMode');
245         }
246         $this->attachBehavior('ywplugin', array('class' => 'yiiwheels.behaviors.WhPlugin'));
247         $this->buildOptions();
248     }
249 
250     /**
251      * Widget's run method
252      */
253     public function run()
254     {
255         $this->renderField();
256         $this->registerClientScript();
257     }
258 
259     /**
260      * Renders field and tag
261      */
262     public function renderField()
263     {
264         list($name, $id) = $this->resolveNameID();
265 
266         if ($this->hasModel()) {
267             echo CHtml::activeHiddenField($this->model, $this->attribute, $this->htmlOptions);
268         } else {
269             echo CHtml::hiddenField($name, $this->value, $this->htmlOptions);
270         }
271 
272         echo '<div id="slider_' . $id . '"></div>';
273     }
274 
275     /**
276      * Registers required files and initialization script
277      */
278     public function registerClientScript()
279     {
280         /* publish assets dir */
281         $path = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'assets';
282         $assetsUrl = $this->getAssetsUrl($path);
283         $id = TbArray::getValue('id', $this->htmlOptions, $this->getId());
284 
285         $jsFile = !empty($this->scales)
286             ? 'jQAllRangeSliders-withRuler-min.js'
287             : 'jQAllRangeSliders-min.js';
288 
289         /* @var $cs CClientScript */
290         $cs = Yii::app()->getClientScript();
291 
292         $cs->registerCoreScript('jquery');
293         $cs->registerCoreScript('jquery.ui');
294         $this->getYiiWheels()->registerAssetJs('jquery.mousewheel.min.js', CClientScript::POS_HEAD);
295 
296         $cs->registerCssFile($assetsUrl . '/css/' . $this->theme . '.css');
297         $cs->registerScriptFile($assetsUrl . '/js/' . $jsFile);
298 
299         $options = !empty($this->options) ? CJavaScript::encode($this->options) : '';
300 
301         $inputValSet = "$('#{$id}').val(data.values.min+','+data.values.max);";
302 
303         //inserting trigger
304         if (isset($this->events['valuesChanged'])) {
305             $orig = $this->events['valuesChanged'];
306             if (strpos($orig, 'js:') === 0) {
307                 $orig = substr($orig, 3);
308             }
309             $orig = "\n($orig).apply(this, arguments);";
310         } else {
311             $orig = '';
312         }
313         $this->events['valuesChanged'] = "js: function(id, data) {
314             $inputValSet $orig
315         }";
316 
317         ob_start();
318         echo "jQuery('#slider_{$id}').{$this->type}Slider({$options})";
319         foreach ($this->events as $event => $handler) {
320             echo ".on('{$event}', " . CJavaScript::encode($handler) . ")";
321         }
322 
323         $cs->registerScript(__CLASS__ . '#' . $this->getId(), ob_get_clean() . ';');
324     }
325 
326     /**
327      * Builds the options
328      */
329     protected function buildOptions()
330     {
331         $options       = array(
332             'arrows'      => $this->arrows,
333             'delayOut'    => $this->delayOut,
334             'durationIn'  => $this->durationIn,
335             'durationOut' => $this->durationOut,
336             'valueLabels' => $this->valueLabels,
337             'formatter'   => $this->formatter,
338             'step'        => $this->step,
339             'wheelMode'   => $this->wheelMode,
340             'wheelSpeed'  => $this->wheelSpeed,
341             'type'        => ($this->type == 'dateRange' ? null : $this->inputType)
342         );
343         $this->options = array_filter($options);
344 
345         if ($this->minRange && $this->maxRange && $this->minRange < $this->maxRange) {
346             $this->options = CMap::mergeArray(
347                 $this->options,
348                 array('range' => array('min' => $this->minRange, 'max' => $this->maxRange))
349             );
350         }
351         if ($this->minValue && $this->maxValue && $this->minValue < $this->maxValue) {
352             $this->options = CMap::mergeArray(
353                 $this->options,
354                 array('bounds' => array('min' => $this->minValue, 'max' => $this->maxValue))
355             );
356         }
357         if ($this->minDefaultValue && $this->maxDefaultValue && $this->minDefaultValue < $this->maxDefaultValue) {
358             $this->options = CMap::mergeArray(
359                 $this->options,
360                 array(
361                     'defaultValues' => array(
362                         'min' => $this->minDefaultValue,
363                         'max' => $this->maxDefaultValue
364                     )
365                 )
366             );
367         }
368     }
369 
370     /**
371      * Checks whether the option set is supported by the plugin
372      * @param mixed $attribute attribute
373      * @param array $availableOptions the possible values
374      * @param string $name the name of the attribute
375      * @throws CException
376      */
377     protected function checkOptionAttribute($attribute, $availableOptions, $name)
378     {
379         if(!in_array($attribute, $availableOptions))
380         {
381             throw new CException(Yii::t(
382                 'zii',
383                 'Unsupported "{attribute}" setting.',
384                 array('{attribute}' => $name)
385             ));
386         }
387     }
388 }
YiiWheels API documentation generated by ApiGen 2.8.0