6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

YiiAdvent Calendar 2012

Day 19

はじめてのウィジェット

Last updated at Posted at 2012-12-18

YiiFramework.comでは、毎日のようにエクステンションが登録されたり、チュートリアルが投稿されています。眺めていると使えそうなものや、アイデアに出会えたりして楽しいですよね。

さて、今回はエクステンションを自作してみます。一口にエクステンションといってもいろいろありますが、jQuery UI MultiSelect WidgetをYiiFrameworkのウィジェットにします。

ウィジェットを作る前に

ビューで直接jQuery UI MultiSelect Widgetを使ったコードです。

view.php
MultiSelect on View
<?php 
// データ
$data = array(
    1=>'Yii',
    2=>'Advent',
    3=>'Calendar',
    4=>'2012',
);
$select = array(1, 3);

// 依存する JavaScript,CSS をインクルードする (一部)
$url = Yii::app()->getAssetManager()->publish($assets_dir.DIRECTORY_SEPARATOR.'jquery.multiselect.js');
Yii::app()->getClientScript()->registerScriptFile($url, CClientScript::POS_END);

// SELECTタグ出力
echo CHtml::dropDownList('multiselect',$select,$data,array(
    'id'=>'multiselect',
    'multiple'=>'multiple',
));

// SELECTタグにjquery.multiselectを適用する
Yii::app()->getClientScript()->registerScript('#multiselect', "$('#multiselect').multiselect();");
?>

なんかいろいろやっててとてもビューに見えません。これでもJavaScript、CSSのインクルードを省略しているんですが。。。えーと、他のビューで同じマルチセレクトを使いたいとき、これらをコピペするのでしょうか?!

いいえ、YiiFrameworkではウィジェット化するんです!

ウィジェットは、ユーザインタフェースコードの再利用性を高めてくれます。
http://www.yiiframework.com/doc/guide/1.1/ja/basics.view#sec-3

MultiSelect on View

ウィジェットを作る

jQuery UIウィジェットのYiiウィジェット化は、決して難しくありません。どのjQuery UIウィジェットでも、最低限やるべきことは3つです。

  1. 依存するjsファイル、cssファイルをインクルードする
  2. ウィジェットに必要なHTMLを出力する
  3. オプションをjQuery UIウィジェット設定インタフェースに渡す

そして作成したウィジェットはこちら。
EMultiSelectWidget.php

EMultiSelectWidgetを使う

EMultiSelectWidgetを使うと、ビューはこのようにすっきりします。

view.php
EMultiSelectWidget :
<?php 
$this->widget('ext.emultiselectwidget.EMultiSelectWidget', array(
    'name'=>'EMultiSelectWidget',
    'data'=>$data,
    'select'=>$select,
));

$data$selectは省略しましたが、上のコードと同じです。

EMultiSelectWidgetの設定

options からjQuery UI MultiSelect Widgetのオプションを設定できます。CJavaScriptExpressionを使ってJavaScriptも注入できる!jQueryウィジェットとYiiウィジェットって相性いいなあ。
htmlOptionsから出力するSELECTタグの属性を設定できます。

view.php
EMultiSelectWidget :
<?php 
$this->widget('ext.emultiselectwidget.EMultiSelectWidget', array(
    'name'=>'EMultiSelectWidget',
    'data'=>$data,
    'select'=>$select,
    'options'=>array(
    	'checkAllText'=>'すべて選択',
    	'uncheckAllText'=>'選択解除',
    	'noneSelectedText'=>'選択してください',
    	'selectedText'=>'#つ選択中',
    	'click'=>new CJavaScriptExpression('function(){console.log(\'click!!\')}'),
    )
    'htmlOptions'=>array(
        'id'=>'hogeid',
        'class'=>'piyoclass',
    )
));

Yii Advent Calendar 2012でも何度か触れられていますが、CWidgetFactoryにまとめて設定することで、使う度に設定する手間も省けます。

EMultiSelectWidget

まとめ

PHP+HTML+JavaScript+CSSを一括りにするときはウィジェット化しよう。ウィジェット単体でテストできるし、再利用もできる。

もうひとつ - 思いつき

ウィジェット化すると、PHP+HTML+JavaScript+CSSが一括りにできて便利なのですが、HTMLとしては読みにくくなります。そこで思いついたのですが、次だとどうでしょう。

view.php
<?php $w = $this->beginWidget("multiselect"); ?>
<select id="<?php echo $w->id; ?>" class="...">
  <?php echo CHtml::listOptions($select, $data); ?>
</select>
<?php $this->endWidget(); ?>

未検証ですが、次のメリットがあるかなーと。

  • select タグを使っていることを明確にできる
  • select タグの属性を、array('htmlOptions'=>)でなく、HTMLに書ける
6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?