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 init()
{
}
//このwidgetが表示するHTMLタグを書き出す
public 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 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 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 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: (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:(hex, opacity) {
console.log(hex + \' - \' + opacity);
}',
)));?> のようにします。
この際、minicolorsのオプションとして、Javascriptの処理を記述する場合は、先頭に「js:」をつけておく必要があります。