From 75aa6659300edd4d85a82789ed165404e926fc49 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Fri, 22 Nov 2013 16:08:24 +0400 Subject: [PATCH] Fixes #1222: refactored jui/Widget, intorduced jui/Slider and jui/SliderInput --- extensions/jui/Slider.php | 45 ++++++++++++++++++++++++ extensions/jui/SliderInput.php | 79 ++++++++++++++++++++++++++++++++++++++++++ extensions/jui/Widget.php | 55 +++++++++++++++++++++++------ 3 files changed, 169 insertions(+), 10 deletions(-) create mode 100644 extensions/jui/Slider.php create mode 100644 extensions/jui/SliderInput.php diff --git a/extensions/jui/Slider.php b/extensions/jui/Slider.php new file mode 100644 index 0000000..f051b9e --- /dev/null +++ b/extensions/jui/Slider.php @@ -0,0 +1,45 @@ + [ + * 'min' => 1, + * 'max' => 10, + * ], + * ]); + * ``` + * + * @see http://api.jqueryui.com/slider/ + * @author Alexander Makarov + * @since 2.0 + */ +class Slider extends Widget +{ + protected $clientEventsMap = [ + 'change' => 'slidechange', + 'create' => 'slidecreate', + 'slide' => 'slide', + 'start' => 'slidestart', + 'stop' => 'slidestop', + ]; + + /** + * Executes the widget. + */ + public function run() + { + echo Html::tag('div', '', $this->options); + $this->registerWidget('slider', SliderAsset::className()); + } +} \ No newline at end of file diff --git a/extensions/jui/SliderInput.php b/extensions/jui/SliderInput.php new file mode 100644 index 0000000..40fb0d9 --- /dev/null +++ b/extensions/jui/SliderInput.php @@ -0,0 +1,79 @@ + $model, + * 'attrbute' => 'amount', + * 'clientOptions' => [ + * 'min' => 1, + * 'max' => 10, + * ], + * ]); + * ``` + * + * The following example will use the name property instead: + * + * ``` + * echo Slider::widget([ + * 'name' => 'amount', + * 'clientOptions' => [ + * 'min' => 1, + * 'max' => 10, + * ], + * ]); + * ``` + * + * @see http://api.jqueryui.com/slider/ + * @author Alexander Makarov + * @since 2.0 + */ +class SliderInput extends InputWidget +{ + protected $clientEventsMap = [ + 'change' => 'slidechange', + 'create' => 'slidecreate', + 'slide' => 'slide', + 'start' => 'slidestart', + 'stop' => 'slidestop', + ]; + + /** + * Executes the widget. + */ + public function run() + { + echo Html::tag('div', '', $this->options); + + $inputId = $this->id.'-input'; + $inputOptions = $this->options; + $inputOptions['id'] = $inputId; + if ($this->hasModel()) { + echo Html::activeHiddenInput($this->model, $this->attribute, $inputOptions); + } else { + echo Html::hiddenInput($this->name, $this->value, $inputOptions); + } + + if (!isset($this->clientEvents['slide'])) { + $this->clientEvents['slide'] = 'function(event, ui) { + $("#'.$inputId.'").val(ui.value); + }'; + } + + $this->registerWidget('slider', SliderAsset::className()); + $this->getView()->registerJs('$("#'.$inputId.'").val($("#'.$this->id.'").slider("value"));'); + } +} \ No newline at end of file diff --git a/extensions/jui/Widget.php b/extensions/jui/Widget.php index 8833fbe..ced00fb 100644 --- a/extensions/jui/Widget.php +++ b/extensions/jui/Widget.php @@ -42,6 +42,11 @@ class Widget extends \yii\base\Widget */ public $clientEvents = []; + /** + * @var array event names mapped to what should be specified in .on( + * If empty, it is assumed that event passed to clientEvents is prefixed with widget name. + */ + protected $clientEventsMap = []; /** * Initializes the widget. @@ -56,32 +61,62 @@ class Widget extends \yii\base\Widget } /** - * Registers a specific jQuery UI widget and the related events - * @param string $name the name of the jQuery UI widget + * Registers a specific jQuery UI widget assets * @param string $assetBundle the asset bundle for the widget */ - protected function registerWidget($name, $assetBundle) + protected function registerAssets($assetBundle) { - $view = $this->getView(); /** @var \yii\web\AssetBundle $assetBundle */ - $assetBundle::register($view); + $assetBundle::register($this->getView()); /** @var \yii\web\AssetBundle $themeAsset */ $themeAsset = static::$theme; - $themeAsset::register($view); + $themeAsset::register($this->getView()); + } - $id = $this->options['id']; + /** + * Registers a specific jQuery UI widget options + * @param string $name the name of the jQuery UI widget + */ + protected function registerClientOptions($name) + { if ($this->clientOptions !== false) { + $id = $this->options['id']; $options = empty($this->clientOptions) ? '' : Json::encode($this->clientOptions); $js = "jQuery('#$id').$name($options);"; - $view->registerJs($js); + $this->getView()->registerJs($js); } + } + /** + * Registers a specific jQuery UI widget events + * @param string $name the name of the jQuery UI widget + */ + protected function registerClientEvents($name) + { if (!empty($this->clientEvents)) { + $id = $this->options['id']; $js = []; foreach ($this->clientEvents as $event => $handler) { - $js[] = "jQuery('#$id').on('$name$event', $handler);"; + if (isset($this->clientEventsMap[$event])) { + $eventName = $this->clientEventsMap[$event]; + } else { + $eventName = $name.$event; + } + $js[] = "jQuery('#$id').on('$eventName', $handler);"; } - $view->registerJs(implode("\n", $js)); + $this->getView()->registerJs(implode("\n", $js)); } } + + /** + * Registers a specific jQuery UI widget asset bundle, initializes it with client options and registers related events + * @param string $name the name of the jQuery UI widget + * @param string $assetBundle the asset bundle for the widget + */ + protected function registerWidget($name, $assetBundle) + { + $this->registerAssets($assetBundle); + $this->registerClientOptions($name); + $this->registerClientEvents($name); + } }