Yiiのwidgetを理解するために、datepicker widgetを参考にcolorpicker widgetを作成してみました。
まず最初に、colorpickerとして、jquery minicolorsを利用しますので、関係ファイルをダウンロードし、protected/extensions/colorPicker/assets/以下に設置します。
次に、protected/extensions/colorPicker/colorPicker.phpにwidgetの内容を記述します。widgetの構成は、おおまかには以下のような感じになります。
class ColorPicker extends CWidget { //widgetに渡したい引数はpublicで宣言しておく public $model; //widgetの初期化 public function init() { } //このwidgetが表示するHTMLタグを書き出す public function run() { } }
で、datepickerを参考に作成したcolorpickerは以下のような感じです。なお、widgetを作成するときはCWidgetを継承するのですが、今回はフォームの入力欄を利用するのでCInputWidgetを継承します。
class ColorPicker extends CInputWidget { /** * @var array minicolorsに渡すオプション */ public $defaultOptions; /** * @var string デフォルトで選択する色 */ private $_defaultColor="#eeeeee"; /** * @var string asset url */ protected $_assetsUrl; /** * widgetの初期化 * minicolorsのjsとcssファイルをassetsに設置する。 */ public function init() { if (Yii::getPathOfAlias('ext.colorPicker.assets') === false) Yii::setPathOfAlias('ext.colorPicker.assets', realpath(dirname(__FILE__) . '/..')); $cs=Yii::app()->getClientScript(); $cs->registerScriptFile($this->getAssetsUrl() . "/jquery.minicolors.js"); $cs->registerCssFile($this->getAssetsUrl() . "/jquery.minicolors.css"); parent::init(); } /** * Returns 公開assetsディレクトリのURLを返す * @return string the URL */ public function getAssetsUrl() { if (isset($this->_assetsUrl)) return $this->_assetsUrl; else { $assetsPath = Yii::getPathOfAlias('ext.colorPicker.assets'); $assetsUrl = Yii::app()->assetManager->publish($assetsPath, false, -1, YII_DEBUG); return $this->_assetsUrl = $assetsUrl; } } /** * 表示するHTMLタグを書き出す * @see CWidget::run() */ public function run() { list($name,$id)=$this->resolveNameID(); if(isset($this->htmlOptions['id'])) $id=$this->htmlOptions['id']; else $this->htmlOptions['id']=$id; if(isset($this->htmlOptions['name'])) $name=$this->htmlOptions['name']; //colorpicker用のinputフィールドを書き出す if($this->hasModel()) { echo CHtml::activeTextField($this->model,$this->attribute,$this->htmlOptions); } else { echo CHtml::textField($name,$this->value,$this->htmlOptions); } if(!empty($this->value)) $this->defaultOptions['defaultValue']=$this->value; else if(empty($this->defaultOptions['defaultValue'])) $this->defaultOptions['defaultValue']=$this->_defaultColor; //minicolorsに渡すオプションをJavascriptに変換 $options=CJavaScript::encode($this->defaultOptions); //minicolorsをregisterScriptで登録 $js = "jQuery('#{$id}').minicolors($options);"; $cs=Yii::app()->getClientScript(); $cs->registerScript(__CLASS__.'#'.$id,$js); } }
なお、このwidgetを利用するには、ビューなどで以下のように書けばよいです。
<?php $this->widget('ext.colorPicker.colorPicker', array( 'model'=>$model, 'attribute'=>'bgcolor', 'value'=>$model->bgcolor, 'defaultOptions'=>array( 'defaultValue'=>'#eeeeee', )));?>
また、
$('INPUT.minicolors').minicolors({ defaultValue: '#eeeeee', animationSpeed: 100, change: function(hex, opacity) { console.log(hex + ' - ' + opacity); } });
のようにminicolorsのオプションを設定するには、
<?php $this->widget('ext.colorPicker.colorPicker', array( 'model'=>$model, 'attribute'=>'bgcolor', 'value'=>$model->bgcolor, 'defaultOptions'=>array( 'defaultValue'=>'#eeeeee', 'animationSpeed'=>100, 'change'=>'js:function(hex, opacity) { console.log(hex + \' - \' + opacity); }', )));?>
のようにします。
この際、minicolorsのオプションとして、Javascriptの処理を記述する場合は、先頭に「js:」をつけておく必要があります。