From 0ff8518c2103a83587a53e44dd3d82e5d58c5a65 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Sat, 21 Dec 2013 17:07:31 -0500 Subject: [PATCH] Fixes #1550: fixed the issue that JUI input widgets did not property input IDs. --- extensions/yii/jui/CHANGELOG.md | 2 +- extensions/yii/jui/DatePicker.php | 23 +++++++++++++++++++---- extensions/yii/jui/InputWidget.php | 6 +++++- extensions/yii/jui/SliderInput.php | 30 +++++++++++++++++++++--------- extensions/yii/jui/Widget.php | 18 +++++++++++------- framework/CHANGELOG.md | 4 +++- framework/yii/captcha/Captcha.php | 7 ------- framework/yii/widgets/InputWidget.php | 10 +++++++++- framework/yii/widgets/MaskedInput.php | 8 -------- 9 files changed, 69 insertions(+), 39 deletions(-) diff --git a/extensions/yii/jui/CHANGELOG.md b/extensions/yii/jui/CHANGELOG.md index eb30e09..b31c34e 100644 --- a/extensions/yii/jui/CHANGELOG.md +++ b/extensions/yii/jui/CHANGELOG.md @@ -4,7 +4,7 @@ Yii Framework 2 jui extension Change Log 2.0.0 beta under development ---------------------------- -- no changes in this release. +- Bug #1550: fixed the issue that JUI input widgets did not property input IDs. 2.0.0 alpha, December 1, 2013 ----------------------------- diff --git a/extensions/yii/jui/DatePicker.php b/extensions/yii/jui/DatePicker.php index 06ca356..bab2abe 100644 --- a/extensions/yii/jui/DatePicker.php +++ b/extensions/yii/jui/DatePicker.php @@ -54,14 +54,30 @@ class DatePicker extends InputWidget * @var boolean If true, shows the widget as an inline calendar and the input as a hidden field. */ public $inline = false; + /** + * @var array the HTML attributes for the container tag. This is only used when [[inline]] is true. + */ + public $containerOptions = []; /** + * @inheritdoc + */ + public function init() + { + parent::init(); + if ($this->inline && !isset($this->containerOptions['id'])) { + $this->containerOptions['id'] = $this->options['id'] . '-container'; + } + } + + /** * Renders the widget. */ public function run() { echo $this->renderWidget() . "\n"; + $containerID = $this->inline ? $this->containerOptions['id'] : $this->options['id']; if ($this->language !== false) { $view = $this->getView(); DatePickerRegionalAsset::register($view); @@ -71,10 +87,10 @@ class DatePicker extends InputWidget $options = $this->clientOptions; $this->clientOptions = false; // the datepicker js widget is already registered - $this->registerWidget('datepicker', DatePickerAsset::className()); + $this->registerWidget('datepicker', DatePickerAsset::className(), $containerID); $this->clientOptions = $options; } else { - $this->registerWidget('datepicker', DatePickerAsset::className()); + $this->registerWidget('datepicker', DatePickerAsset::className(), $containerID); } } @@ -101,8 +117,7 @@ class DatePicker extends InputWidget $this->clientOptions['defaultDate'] = $this->value; } $this->clientOptions['altField'] = '#' . $this->options['id']; - $this->options['id'] .= '-container'; - $contents[] = Html::tag('div', null, $this->options); + $contents[] = Html::tag('div', null, $this->containerOptions); } return implode("\n", $contents); diff --git a/extensions/yii/jui/InputWidget.php b/extensions/yii/jui/InputWidget.php index e100d6c..0facfb9 100644 --- a/extensions/yii/jui/InputWidget.php +++ b/extensions/yii/jui/InputWidget.php @@ -10,6 +10,7 @@ namespace yii\jui; use Yii; use yii\base\Model; use yii\base\InvalidConfigException; +use yii\helpers\Html; /** * InputWidget is the base class for all jQuery UI input widgets. @@ -44,7 +45,10 @@ class InputWidget extends Widget public function init() { if (!$this->hasModel() && $this->name === null) { - throw new InvalidConfigException("Either 'name' or 'model' and 'attribute' properties must be specified."); + throw new InvalidConfigException("Either 'name', or 'model' and 'attribute' properties must be specified."); + } + if ($this->hasModel() && !isset($this->options['id'])) { + $this->options['id'] = Html::getInputId($this->model, $this->attribute); } parent::init(); } diff --git a/extensions/yii/jui/SliderInput.php b/extensions/yii/jui/SliderInput.php index 8ded4e8..8a43eb1 100644 --- a/extensions/yii/jui/SliderInput.php +++ b/extensions/yii/jui/SliderInput.php @@ -50,30 +50,42 @@ class SliderInput extends InputWidget 'start' => 'slidestart', 'stop' => 'slidestop', ]; + /** + * @var array the HTML attributes for the container tag. + */ + public $containerOptions = []; + + /** + * @inheritdoc + */ + public function init() + { + parent::init(); + if (!isset($this->containerOptions['id'])) { + $this->containerOptions['id'] = $this->options['id'] . '-container'; + } + } /** * Executes the widget. */ public function run() { - echo Html::tag('div', '', $this->options); + echo Html::tag('div', '', $this->containerOptions); - $inputId = $this->id.'-input'; - $inputOptions = $this->options; - $inputOptions['id'] = $inputId; if ($this->hasModel()) { - echo Html::activeHiddenInput($this->model, $this->attribute, $inputOptions); + echo Html::activeHiddenInput($this->model, $this->attribute, $this->options); } else { - echo Html::hiddenInput($this->name, $this->value, $inputOptions); + echo Html::hiddenInput($this->name, $this->value, $this->options); } if (!isset($this->clientEvents['slide'])) { $this->clientEvents['slide'] = 'function(event, ui) { - $("#'.$inputId.'").val(ui.value); + $("#' . $this->options['id'] . '").val(ui.value); }'; } - $this->registerWidget('slider', SliderAsset::className()); - $this->getView()->registerJs('$("#'.$inputId.'").val($("#'.$this->id.'").slider("value"));'); + $this->registerWidget('slider', SliderAsset::className(), $this->containerOptions['id']); + $this->getView()->registerJs('$("#' . $this->options['id'] . '").val($("#' . $this->id . '").slider("value"));'); } } diff --git a/extensions/yii/jui/Widget.php b/extensions/yii/jui/Widget.php index 90bad68..8881a77 100644 --- a/extensions/yii/jui/Widget.php +++ b/extensions/yii/jui/Widget.php @@ -76,11 +76,11 @@ class Widget extends \yii\base\Widget /** * Registers a specific jQuery UI widget options * @param string $name the name of the jQuery UI widget + * @param string $id the ID of the widget */ - protected function registerClientOptions($name) + protected function registerClientOptions($name, $id) { if ($this->clientOptions !== false) { - $id = $this->options['id']; $options = empty($this->clientOptions) ? '' : Json::encode($this->clientOptions); $js = "jQuery('#$id').$name($options);"; $this->getView()->registerJs($js); @@ -90,11 +90,11 @@ class Widget extends \yii\base\Widget /** * Registers a specific jQuery UI widget events * @param string $name the name of the jQuery UI widget + * @param string $id the ID of the widget */ - protected function registerClientEvents($name) + protected function registerClientEvents($name, $id) { if (!empty($this->clientEvents)) { - $id = $this->options['id']; $js = []; foreach ($this->clientEvents as $event => $handler) { if (isset($this->clientEventMap[$event])) { @@ -112,11 +112,15 @@ class Widget extends \yii\base\Widget * 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 + * @param string $id the ID of the widget. If null, it will use the `id` value of [[options]]. */ - protected function registerWidget($name, $assetBundle) + protected function registerWidget($name, $assetBundle, $id = null) { + if ($id === null) { + $id = $this->options['id']; + } $this->registerAssets($assetBundle); - $this->registerClientOptions($name); - $this->registerClientEvents($name); + $this->registerClientOptions($name, $id); + $this->registerClientEvents($name, $id); } } diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index a1d7bdf..9694cb7 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -9,6 +9,7 @@ Yii Framework 2 Change Log - Bug #1500: Log messages exported to files are not separated by newlines (omnilight, qiangxue) - Bug #1509: The SQL for creating Postgres RBAC tables is incorrect (qiangxue) - Bug #1545: It was not possible to execute db Query twice, params where missing (cebe) +- Bug #1550: fixed the issue that JUI input widgets did not property input IDs. - Bug #1591: StringValidator is accessing undefined property (qiangxue) - Bug: Fixed `Call to a member function registerAssetFiles() on a non-object` in case of wrong `sourcePath` for an asset bundle (samdark) - Bug: Fixed incorrect event name for `yii\jui\Spinner` (samdark) @@ -24,7 +25,8 @@ Yii Framework 2 Change Log - Enh: Added `Widget::autoIdPrefix` to support prefixing automatically generated widget IDs (qiangxue) - Enh: Support for file aliases in console command 'message' (omnilight) - Enh: Sort and Paginiation can now create absolute URLs (cebe) -- Chg: Renamed yii\jui\Widget::clientEventsMap to clientEventMap (qiangxue) +- Chg: Renamed `yii\jui\Widget::clientEventsMap` to `clientEventMap` (qiangxue) +- Chg: Added `yii\widgets\InputWidget::options` (qiangxue) - New #1438: [MongoDB integration](https://github.com/yiisoft/yii2-mongodb) ActiveRecord and Query (klimov-paul) - New #1393: [Codeception testing framework integration](https://github.com/yiisoft/yii2-codeception) (Ragazzo) diff --git a/framework/yii/captcha/Captcha.php b/framework/yii/captcha/Captcha.php index 76090a2..18b8765 100644 --- a/framework/yii/captcha/Captcha.php +++ b/framework/yii/captcha/Captcha.php @@ -39,10 +39,6 @@ class Captcha extends InputWidget */ public $captchaAction = 'site/captcha'; /** - * @var array HTML attributes to be applied to the text input field. - */ - public $options = []; - /** * @var array HTML attributes to be applied to the CAPTCHA image tag. */ public $imageOptions = []; @@ -62,9 +58,6 @@ class Captcha extends InputWidget $this->checkRequirements(); - if (!isset($this->options['id'])) { - $this->options['id'] = $this->hasModel() ? Html::getInputId($this->model, $this->attribute) : $this->getId(); - } if (!isset($this->imageOptions['id'])) { $this->imageOptions['id'] = $this->options['id'] . '-image'; } diff --git a/framework/yii/widgets/InputWidget.php b/framework/yii/widgets/InputWidget.php index e1981c9..0a4b5b7 100644 --- a/framework/yii/widgets/InputWidget.php +++ b/framework/yii/widgets/InputWidget.php @@ -11,6 +11,7 @@ use Yii; use yii\base\Widget; use yii\base\Model; use yii\base\InvalidConfigException; +use yii\helpers\Html; /** * InputWidget is the base class for widgets that collect user inputs. @@ -40,6 +41,10 @@ class InputWidget extends Widget * @var string the input value. */ public $value; + /** + * @var array the HTML attributes for the input tag. + */ + public $options = []; /** @@ -49,7 +54,10 @@ class InputWidget extends Widget public function init() { if (!$this->hasModel() && $this->name === null) { - throw new InvalidConfigException("Either 'name' or 'model' and 'attribute' properties must be specified."); + throw new InvalidConfigException("Either 'name', or 'model' and 'attribute' properties must be specified."); + } + if (!isset($this->options['id'])) { + $this->options['id'] = $this->hasModel() ? Html::getInputId($this->model, $this->attribute) : $this->getId(); } parent::init(); } diff --git a/framework/yii/widgets/MaskedInput.php b/framework/yii/widgets/MaskedInput.php index fc21cef..7eb42a7 100644 --- a/framework/yii/widgets/MaskedInput.php +++ b/framework/yii/widgets/MaskedInput.php @@ -61,10 +61,6 @@ class MaskedInput extends InputWidget * @var string a JavaScript function callback that will be invoked when user finishes the input. */ public $completed; - /** - * @var array the HTML attributes for the input tag. - */ - public $options = []; /** @@ -77,10 +73,6 @@ class MaskedInput extends InputWidget if (empty($this->mask)) { throw new InvalidConfigException('The "mask" property must be set.'); } - - if (!isset($this->options['id'])) { - $this->options['id'] = $this->hasModel() ? Html::getInputId($this->model, $this->attribute) : $this->getId(); - } } /**