From e2073612556db4f74fc3089d6b7dd556e3af69c0 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Wed, 29 May 2013 07:47:33 -0400 Subject: [PATCH] Refactored the widget usage with ActiveField. --- apps/basic/views/site/contact.php | 12 ++----- framework/yii/widgets/ActiveField.php | 12 ++++++- framework/yii/widgets/Captcha.php | 64 ++++++++++++++++++++++++++++------- 3 files changed, 65 insertions(+), 23 deletions(-) diff --git a/apps/basic/views/site/contact.php b/apps/basic/views/site/contact.php index e740d0f..14a82bc 100644 --- a/apps/basic/views/site/contact.php +++ b/apps/basic/views/site/contact.php @@ -31,15 +31,9 @@ $this->params['breadcrumbs'][] = $this->title; field($model, 'email')->textInput(); ?> field($model, 'subject')->textInput(); ?> field($model, 'body')->textArea(array('rows' => 6)); ?> - field($model, 'verifyCode'); - echo $field->begin() - . $field->label() - . Captcha::widget() - . Html::activeTextInput($model, 'verifyCode', array('class' => 'input-medium')) - . $field->error() - . $field->end(); - ?> + field($model, 'verifyCode')->widget(Captcha::className(), array( + 'options' => array('class' => 'input-medium'), + )); ?>
'btn btn-primary')); ?>
diff --git a/framework/yii/widgets/ActiveField.php b/framework/yii/widgets/ActiveField.php index e3e7f2b..346f743 100644 --- a/framework/yii/widgets/ActiveField.php +++ b/framework/yii/widgets/ActiveField.php @@ -557,7 +557,14 @@ class ActiveField extends Component } /** - * Renders a field containing a widget. + * Renders a field containing an input widget. + * + * Note that the widget must have both `model` and `attribute` properties. They will + * be initialized with [[model]] and [[attribute]] of this field, respectively. + * + * If you want to use a widget that does not have `model` and `attribute` properties, + * please use [[render()]] instead. + * * @param string $class the widget class name * @param array $config name-value pairs that will be used to initialize the widget * @return string the rendering result @@ -565,6 +572,9 @@ class ActiveField extends Component public function widget($class, $config = array()) { /** @var \yii\base\Widget $class */ + $config['model'] = $this->model; + $config['attribute'] = $this->attribute; + $config['view'] = $this->form->getView(); return $this->render($class::widget($config)); } } diff --git a/framework/yii/widgets/Captcha.php b/framework/yii/widgets/Captcha.php index 918e30c..ffe8802 100644 --- a/framework/yii/widgets/Captcha.php +++ b/framework/yii/widgets/Captcha.php @@ -9,13 +9,12 @@ namespace yii\widgets; use Yii; use yii\base\InvalidConfigException; -use yii\base\Widget; use yii\helpers\Html; use yii\helpers\Json; use yii\web\CaptchaAction; /** - * Captcha renders a CAPTCHA image element. + * Captcha renders a CAPTCHA image and an input field that takes user-entered verification code. * * Captcha is used together with [[CaptchaAction]] provide [CAPTCHA](http://en.wikipedia.org/wiki/Captcha) * - a way of preventing Website spamming. @@ -32,7 +31,7 @@ use yii\web\CaptchaAction; * @author Qiang Xue * @since 2.0 */ -class Captcha extends Widget +class Captcha extends InputWidget { /** * @var string the route of the action that generates the CAPTCHA images. @@ -40,27 +39,66 @@ class Captcha extends Widget */ public $captchaAction = 'site/captcha'; /** - * @var array HTML attributes to be applied to the rendered image element. + * @var array HTML attributes to be applied to the text input field. */ public $options = array(); - + /** + * @var array HTML attributes to be applied to the CAPTCHA image tag. + */ + public $imageOptions = array(); + /** + * @var string the template for arranging the CAPTCHA image tag and the text input tag. + * In this template, the token `{image}` will be replaced with the actual image tag, + * while `{input}` will be replaced with the text input tag. + */ + public $template = '{image} {input}'; /** - * Renders the widget. + * Initializes the widget. */ - public function run() + public function init() { + parent::init(); + $this->checkRequirements(); if (!isset($this->options['id'])) { - $this->options['id'] = $this->getId(); + $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'; + } + } + + /** + * Renders the widget. + */ + public function run() + { + $this->registerClientScript(); + if ($this->hasModel()) { + $input = Html::activeTextInput($this->model, $this->attribute, $this->options); + } else { + $input = Html::textInput($this->name, $this->value, $this->options); } - $id = $this->options['id']; - $options = Json::encode($this->getClientOptions()); - $this->view->registerAssetBundle('yii/captcha'); - $this->view->registerJs("jQuery('#$id').yiiCaptcha($options);"); $url = Yii::$app->getUrlManager()->createUrl($this->captchaAction, array('v' => uniqid())); - echo Html::img($url, $this->options); + $image = Html::img($url, $this->imageOptions); + echo strtr($this->template, array( + '{input}' => $input, + '{image}' => $image, + )); + } + + /** + * Registers the needed JavaScript. + */ + public function registerClientScript() + { + $options = $this->getClientOptions(); + $options = empty($options) ? '' : Json::encode($options); + $id = $this->imageOptions['id']; + $this->getView()->registerAssetBundle('yii/captcha'); + $this->getView()->registerJs("jQuery('#$id').yiiCaptcha($options);"); } /**