Do You PHP はてブロ

Do You PHPはてなからはてブロに移動しました

Symfony2でjQuery UIを簡単に扱うGenemuFormBundleを試してみた

KnpBundlesjQueryを扱うBundleを探していたら、何だかいい感じっぽいGenemuFormBundleというのが見つかったので試してみました。

今回はjQuery UIのDatepickerを使うまでの手順をまとめてます。

GenemuFormBundleとは

javascriptライブラリを使うカスタムForm集で、jQuery UIだけではなくReCaptchaTinymceuploadifyといったものを使ったカスタムFormも用意されています。

GenemuFormBundleのインストール

インストール手順はREADME.markdownにある通りです:-)

1. GenemuFormBundleのインストール

Symfony/depsファイルに以下の内容を追加

[GenemuFormBundle]
    git=git://github.com/genemu/GenemuFormBundle.git
    target=bundles/Genemu/Bundle/FormBundle
    version=origin/2.0

して、

$ php bin/vendors install

を実行。この辺は楽ですね。

2. GenemuFormBundleの設定

お決まりのapp/AppKernel.php、app/autoload.php、app/config/config.ymlへの追記です。
まずはapp/AppKernel.php

<?php
// app/AppKernel.php

public function registerBundles()
{
    $bundles = array(
        // ...
        new Genemu\Bundle\FormBundle\GenemuFormBundle(),
    );
}

次にapp/autoload.php

<?php
// app/autoload.php

$loader->registerNamespaces(array(
    // ...
    'Genemu' => __DIR__.'/../vendor/bundles',
));

最後にapp/config/config.yml。

genemu_form: ~
3. jQueryjQuery UIを含むjavascriptライブラリのインストール

Bundle自体にjavascriptライブラリは含まれていませんので、別途ダウンロード・設置する必要があります。今回はDownload Builder | jQuery UIからカスタムテーマ(テーマ名は"theme")をダウンロードしました。バージョンは1.8.18です。また、ダウンロードしたファイルをSymfony/webや直下のbundles辺りに展開しておきます。この辺は適宜ということで;-)
今回は、以下のように設置しました。

Symfony
└─web
    ├─js
    │  └─i18n
    └─css
        └─theme      <==== カスタムテーマ名
            └─images

なお、カレンダーの表示を日本語化したいので、jquery-ui-1.8.18.custom.zipのdevelopment-bundle/ui下にあるi18nディレクトリもコピーしています。

4. Twigテンプレートの用意

GenemuFormBundle/template.md at master · genemu/GenemuFormBundle · GitHubにありますが、テンプレートのstylesheetsブロック・javascriptsブロックで必要なjavascriptファイル、cssファイルを読み込みます。
form_stylesheetとform_javascriptというTwig関数がありますが、これらはGenemuFormBundleによって提供されているものになります。

{% extends "::base.html.twig" %}
{% block stylesheets %}
    <link href="{{ asset('css/theme/jquery-ui-1.8.18.custom.css') }}" rel="stylesheet" />
    {% if form is defined %}
    {{ form_stylesheet(form) }}
    {% endif %}
{% endblock %}

{% block javascripts %}
    <script src="{{ asset('js/jquery-1.7.1.min.js') }}"></script>
    <script src="{{ asset('js/jquery-ui-1.8.18.custom.min.js') }}"></script>
    <script src="{{ asset('js/i18n/jquery-ui-i18n.js') }}"></script>
    {% if form is defined %}
    {{ form_javascript(form) }}
    {% endif %}
    {% block page_javascript %}{% endblock page_javascript %}
{% endblock %}

簡単なサンプル

前述のとおり、GenemuFormBundleはカスタムForm集なので、FormBuilderでフォームを組み立てる際に指定するFormTypeに用意されたものを指定します。
Datepickerを使う場合、GenemuFormBundle/index.md at master · genemu/GenemuFormBundle · GitHubにあるとおり"genemu_jquerydate"を指定します。

<?php
// ...
public function buildForm(FormBuilder $builder, array $options)
{
    $builder
        // ...
        ->add('createdAt', 'genemu_jquerydate')
        ->add('updatedAt', 'genemu_jquerydate', array(
            'widget' => 'single_text'
        ));
}

本来のDatepickerで使えるはずのオプションは、Datepickerのオプション名をキーとして値にオプション値を持つ連想配列を用意し、それをキー"configs"としてFormTypeのオプションに渡してやります。たとえば、

  • 選択後のフォーマット(dateFormatオプション)を"yymmdd"形式
  • 選択できる日付の範囲を1年前(minDateオプション)〜1ヶ月10日後(maxDateオプション)

にしたい場合は、以下のようになります。

<?php
// ...
public function buildForm(FormBuilder $builder, array $options)
{
    $builder
        // ...
        ->add('createdAt', 'genemu_jquerydate')
        ->add('updatedAt', 'genemu_jquerydate', array(
            'widget' => 'single_text',
            'configs' => array(                 // キー"configs"にオプションを指定
                'dateFormat' => 'yymmdd',       // 選択後のフォーマット
                'minDate' => '-1y',             // 1年前まで選択可能
                'maxDate' => '+1m +10d',        // 1ヶ月と10日後まで選択可能
            ),
        ));
}

これを実行すると、次のような画面になります(Updateat右のテキストボックスをクリックした状態)。

ちなみに、出力されるHTMLソースは以下の様な感じです。

         :
    (formのHTML)
         :
    <script src="/js/jquery-1.7.1.min.js"></script>
    <script src="/js/jquery-ui-1.8.18.custom.min.js"></script>
    <script src="/js/i18n/jquery-ui-i18n.js"></script>
    <script type="text/javascript">
        jQuery(document).ready(function($) {
            var $configs = $.extend({
                minDate: new Date(2007, 0, 1),
                maxDate: new Date(2017, 11, 31)
            }, $.datepicker.regional['ja'] ,{"dateFormat":"yymmdd","minDate":"-1y","maxDate":"+1m +10d"});

        
            $('#form_updatedAt').datepicker($configs);
        });
    </script>
         :

独自のカスタムFormにGenemuFormBundleのカスタムFormを使う

getParentメソッドの戻り値を変更するだけです。

<?php
// ...
class SingleDateType extends AbstractType
{
    // ...
    public function getParent(array $options)
    {
        return 'genemu_jquerydate';    // 親Typeを'genemu_jquerydate'とする
    }
}

まとめ

今回はjQuery UIのDatepickerだけでしたが、用意されているFormTypeだけでほとんどの部分ができてしまうのは良いですね。
その他のFormTypeについてもいくつか使う予定がある(かも知れない)ので、今後もうちょっと掘り下げてようと思います。