CakePHP2 で Form ヘルパーの dateFormat の日本語対応を、独自に修正したりしないで泥臭く対応する方法。

FormHelper::input の ‘type’ => ‘date’ を使うと一発で「年月日」のセレクトフォームを作れて幸せな気持ちになります。しかし!しかしはまりました。

年と月と、月と日の間に入れる文字列を自由にできないのです!そこで、不完全ながら何とかした記録を残しておきます。

なんとかしたソース

誕生日<?php echo $this->Form->datetime('User.birth_date', 'Y', null, array('minYear' => 1980,'empty' => '----','orderYear' => 'asc'));?>年
<?php echo $this->Form->datetime('User.birth_date', 'M', null, array('monthNames' => false,'empty' => '--'));?>月
<?php echo $this->Form->datetime('User.birth_date', 'D', null, array('empty' => '--'));?>日
<?php
if ($this->Form->isFieldError('User.birth_date')) {
	echo $this->Form->error('User.birth_date');
}
?>

方針としては、年、月、日をそれぞれ独立して出力し、間を自由な文字でつなぐ、という形になります。

そして最後に、バリデーションエラーとなったときのために、エラーを出しています。

年、月、日、エラーと4つも出力させるの、面倒ですけれども、仕方がないですね。。。何とかならないものでしょうか?

このときの HTML はこちらになります。

誕生日<select name="data[User][birth_date][year]" id="UserBirthDateYear">
<option value="">----</option>
<option value="1980">1980</option>
…略…
<option value="2032">2032</option>
</select>年
<select name="data[User][birth_date][month]" id="UserBirthDateMonth">
<option value="">--</option>
<option value="01">01</option>
…略…
<option value="12">12</option>
</select>月
<select name="data[User][birth_date][day]" id="UserBirthDateDay">
<option value="">--</option>
<option value="01">1</option>
…略…
<option value="31">31</option>
</select>日

また、FormHelper::datetime を使用しましたが、年月日それぞれの FormHelper::year、FormHelper::month、FormHelper::day を使ってもよいと思います。わたくしは、検証していないですけれども。

いろいろなこと

本当は次のように、1行で済ませたかったのです。

特別日<?php echo $this->Form->input('User.special_date', array('label' => false, 'type' => 'date', 'dateFormat' => 'YMD', 'monthNames' => false, 'div' => false)); ?>

このように書きますと、HTML は次のようになります。

特別日<select name="data[User][special_date][year]" id="UserSpecialDateYear">
<option value="2032">2032</option>
…略…
<option value="1992">1992</option>
</select>-<select name="data[User][special_date][month]" id="UserSpecialDateMonth">
<option value="01">01</option>
…略…
<option value="12">12</option>
</select>-<select name="data[User][special_date][day]" id="UserSpecialDateDay">
<option value="01">1</option>
…略…
<option value="31">31</option>
</select>

これですと、年と月と日の間が「-」でつなげられてしまいます。このセパレーター文字は実は変更可能です!おおっ!オプションは、’separator’ だっ!!!

しかし、1種類しか指定できないので、意味がないです。「年」と「月」のどちらかしか入れられないのでは、まったく意味がありません。

ちなみに、「日」も別のオプションで指定可能です。’after’ を使います。ひっくるめて、こんな感じで書くことができます。

特別日<?php echo $this->Form->input('User.special_date', array('label' => false, 'type' => 'date', 'dateFormat' => 'YMD', 'monthNames' => false, 'div' => false, 'before' => '--before--', 'after' => '--after--', 'between' => '--between---', 'separator' => '--separator--')); ?>

そうすると、 HTML はこんな感じになります。

特別日--before----between---<select name="data[User][special_date][year]" id="UserSpecialDateYear">
<option value="2032">2032</option>
…略…
<option value="1992">1992</option>
</select>--separator--<select name="data[User][special_date][month]" id="UserSpecialDateMonth">
<option value="01">01</option>
…略…
<option value="12">12</option>
</select>--separator--<select name="data[User][special_date][day]" id="UserSpecialDateDay">
<option value="01">1</option>
…略…
<option value="31">31</option>
</select>--after--

年と、月がなんとかなれば。。。あと1箇所なのに。。。と思わずにはいられません。

ちなみに、これらのオプションは、こちらが参考になりました。やはり本家ドキュメントはすばらしいです。

このページの、For radio inputs the ‘separator’ attribute can be used to inject markup to separate each input/label pair: の部分です。

おわりに

この投稿を書いていて改めて気がついたのですが、分けて書くバージョン、1行で済ますバージョン、どちらも HTML の id と name は同じ形式ですね。当たり前といわれれば当たり前ですけれども、JavaScript を絡めたり、ビューを書くときに、スムースにいったり迷いが減ったりと、いいことがありそうです。

また、こんな泥臭い方法をとる前に、華麗にオリジナルのヘルパーを作りましょうよ!という声が聞こえてきそうです。実際、探したらありました。すばらしい投稿です。また、コアをいじって何とかしようとしている猛者の方もいらっしゃいました。

もしわたくしが、どちらかをとれといわれれば前者のヘルパー化を採用しますけれども、どちらも勉強になりました。ありがとうございます。

以上です♪

ディスカッションに参加

1件のコメント

コメントを残す

コメントを残す