sfFormでjQueryのカレンダーを日本語化して使ってみる

sfFormExtraPluginをインストールする

まず、sfFormの標準のwidgetにはjQueryのカレンダー(Datepicker)を利用したwidgetがありません。
sfFormExtraPluginをインストールする必要があります。

参照: symfony 1.x legacy website

jQuery関連のライブラリを用意する

jQuery本体のライブラリをjQueryのサイトからダウンロードします。

参照: jQuery

カレンダーはjQuery UIというライブラリに含まれるので、これもダウンロードしておきます。

参照:Download Builder | jQuery UI

あと、日本語パッケージがUIのdevelopment-bundleディレクトリに含まれていますので、合計で以下の3ファイルが必要になります。

  • jquery-1.3.2.min.js
  • jquery-ui-1.7.1.custom.min.js
  • /development-bundle/ui/i18n/ui.datepicker-ja.js

また、スタイルシートもUIに含まれています。今回はsmoothnessというテーマでダウンロードしたので、以下のファイルを利用します。

jQuery関連ファイルのアップロード

jsファイル

webディレクトリにあるjsディレクトリにjQueryディレクトリを用意し以下のようなパスで配置しました。

  • アプリケーションルート/web/js/jquery/jquery-1.3.2.min.js
  • アプリケーションルート/web/js/jquery/jquery-ui-1.7.1.custom.min.js
  • アプリケーションルート/web/js/jquery/ui/i18n/ui.datepicker-ja.js
cssファイル

こちらも同じくwebディレクトリにあるcssディレクトリにsmoothnessディレクトリを用意し、以下のようなパスで配置しました。

  • アプリケーションルート/web/css/smoothness/jquery-ui-1.7.1.custom.css

日本語化したwidgetを用意する

sfFormExtraPluginにあるsfWidgetFormJQueryDateウィジットを使うのですが、どうせ日本語化に特化させるためにいろいろとオプションを指定することになるので、jpWidgetFormJQueryDateという新しいウィジットを作ってしまう事にします。

実際はプラグインで作ったのですが、ここではとりあえずライブラリとして作った場合で説明します。

jpWidgetFormJQueryDate.class.php

以下のような内容でjpWidgetFormJQueryDate.class.phpを用意します。

  • アプリケーションルート/lib/widget/jpWidgetFormJQueryDate.class.php
<?php
class jpWidgetFormJQueryDate extends sfWidgetFormJQueryDate
{
  protected function configure($options = array(), $attributes = array())
  {
    parent::configure($options, $attributes);
    $this->setOption('culture', 'ja');
    # $this->setOption('format', '%year%年%month%月%day%日'); // 古いsfWidgetFormJqueryDataを利用している場合
    $this->getOption('date_widget')->setOption('format', '%year%年%month%月%day%日');
    if ($this->getOption('config') === '{}') {
      $this->setOption('config', '{buttonText: "カレンダーで選択"}');
    }
  }
  public function getStylesheets()
  {
    return array(
                 'smoothness/jquery-ui-1.7.1.custom' => 'all'
                 );
  }
  public function getJavaScripts()
  {
    return array(
                 'jquery/jquery-1.3.2.min',
                 'jquery/jquery-ui-1.7.1.custom.min',
                 'jquery/ui/i18n/ui.datepicker-ja'
                 );
  }
}

cultureでjaを指定することで日本語化されたカレンダーを利用できます。
また、このウィジットで読み込む必要があるファイルはgetStyleSheetsとgetJavaScriptsメソッドの戻り値に配列で指定することで用意できます。ただし、自動的には読み込んでくれません。これは後述にテンプレートの部分に追記が必要。

Formクラスでwidgetを指定

そして、フォームクラスでwidgetSchemaとして指定します。

  • HogeForm.class.php
    $this->widgetSchema['expired_at'] = new jpWidgetFormJQueryDate();
CSSとJSファイルを読み込む

最後に、テンプレートで追加したスタイルシートとJSファイルを読み込むように以下のように加えます。
ウィジットに書いただけでは自動的に読み込んでくれないという不親切設計です。

  • editSuccess.php
ここでは$formにsfFormオブジェクトがアサインされている場合の例です。
<?php include_javascripts_for_form($form) ?>
<?php include_stylesheets_for_form($form) ?>
日本語化(ちょっと不自然)

これで準備は完了です。フォームを表示すると以下のようにカレンダーを利用できます。


うまくファイルが読み込まれない、日本語化されない場合は
symfony ccと、クッキーを削除するとうまくいくかも。

でも、よくみると、カレンダーのヘッダー部分の年月が惜しいことになっています。
「年」という表示が年月の間に無いために不自然な表示になってしまっています。

年月の間に「年」という文字を追加する

そこで、jQueryを使ってこのヘッダー部分に「年」という文字を追加するようにしてみます。

widgetのrenderメソッドをオーバーライドして、親クラスのレンダー結果に「年」を追加するjavascriptを書き加えます。

  • jpWidgetFormJQueryDate.class.php
<?php
...
  public function render($name, $value = null, $attributes = array(), $errors = array())
  {
    return parent::render($name, $value, $attributes, $errors).<<<EOF
<script type="text/javascript">
jQuery(document).ready(function(){
  var  eleYear = ".ui-datepicker-year";
  jQuery(".ui-datepicker-trigger, div#ui-datepicker-div").click(function() {
    jQuery("span.jpYearSuffix").remove();
    jQuery(eleYear).after("<span class='jpYearSuffix'>年</span>");
  });
});
</script>
EOF
;
  }

これで、もう一度表示させてみると

月を移動しても、ちゃんと表示されています。
このように、jQueryのおかげで、コアファイルには修正を加えずにそれらしく日本語化もできましたとさ。
ただし、年をプルダウンで表示させたりすると崩れちゃいますけどね。。