Smarty: html_select_date
日付の設定
html_select_date を使うと、
簡単に日付を設定するフォームが作れます。
{html_select_date time=デフォルトの年月日
start_year=開始年 end_year=終了年 field_separator=区切り文字
field_order=年月日の並び順
month_format=月のフォーマット}
・time
表示時点で選択しておく年月日を
Unix タイムスタンプか、'YYYY-MM-DD' フォーマットで指定します。
省略すると、年月日、それぞれリストの最初になります。
・start_year
年のリストの開始を指定します。
-3 などと指定すると、現在から3年前の年を指定した事になります。
省略すると、現在の年になります。
・end_year
年のリストの終了を指定します。
+2 などと指定すると、現在から2年後の年を指定した事になります。
省略すると、現在の年になります。
「プラスの数値」にすることを推奨。
・field_separator
年、月、日、それぞれの間に挿入する文字を指定します。
省略すると、'\n' になります。
・field_order
年月日の並び順を指定します。
月を M、日を D、年を Y として、3文字で表記します。
省略すると、MDY になります。
・month_format
月のリストのフォーマットを指定します。
PHP の strftime 関数の書式を参照してください。
省略すると、'%B' になります。
例えば、
sample.tpl で、
{html_select_date} とすると、見た目は、
{html_select_date start_year='-3' end_year='+3'
field_separator='/' field_order=YMD month_format='%m'}
とすると、見た目は、
//
注意が必要なのは、 この関数は、 あくまでプルダウンメニューの HTML を展開するだけだ、ということです。 2月31日と選んでも、そのまま submit するので、 日時の妥当性は、別途プログラムでチェックする必要があります。
start_year、end_year、time パラメータの組み合わせについては注意が必要です。 start_year、end_year を省略すると、表示される年の選択肢は「現在の1年分だけ」になります。 よって、現在が 2025年で {html_select_date time='2024-01-01' field_order=YMD} と書いていると、画面上は 2025 になってしまいます。 # 年の選択肢に 2024 がないから、選択できる一番少ない値になる。 {html_select_date time='2024-01-01' start_year='2020' end_year='2023' field_order=YMD} と書いた場合は、2020 になります。 start_year は、サポートすべき最小値にするとして、 end_year は、絶対値ではなく、プラスの数値にするのが良いかと思います。
日付の妥当性をチェックするのに一番簡単なのは、 PHP の checkdate 関数を用いる事です。 # bool checkdate ( int $month , int $day , int $year ) ですが、これだと、 フォームを送信した後でないとチェックできません。 2月31日とか指定されたとき、 入力済みの他のデータを保ったままデータ入力画面に戻るのは、 コード的に面倒ですし、 何より、ユーザーに優しくありません。 そこで、送信する前に HTML 内部の JavaScript でチェックし、 NG なら送信させないようにするのが妥当です。 例えば、以下のようにします。
<html> <head> <meta http-equiv="Content-Script-Type" content="JavaScript" /> <script type="text/javascript"> <!-- function checkDate(year_name, month_name, day_name) { // html_select_date 展開後の select の名前からオブジェクトを取得する // 同じ name が複数無い前提。 var year_id = document.getElementsByName(year_name).item(0); var month_id = document.getElementsByName(month_name).item(0); var day_id = document.getElementsByName(day_name).item(0); // 現在選択されている設定値を取り出す // parseInt するのは、09 などの値が8進数に間違われないように、念のため var year = parseInt(year_id.options[year_id.selectedIndex].value, 10); var month = parseInt(month_id.options[month_id.selectedIndex].value, 10)-1; // JavaScript の月は 0 始まり var day = parseInt(day_id.options[day_id.selectedIndex].value, 10); // 範囲が正しいか調べる if(year>=0 && month>=0 && month<=11 && day>=1 && day<=31) { // 一旦 JavaScript で日付を生成させてから、再度分解し、元の値と比べる var date = new Date(year, month, day); if(date.getFullYear()==year && date.getMonth()==month && date.getDate()==day) { return true; } } // 範囲が正しくなければメッセージを出して false で返す (submit させない) alert("Invalid Date!!"); // 実際の文字列は適切なものを選んでください。 return false; } // --> </script> </head> <body> <form method="post"> {html_select_date start_year='-3' end_year='+3' field_separator='/' field_order=YMD month_format='%m'} <input type="submit" onClick="return checkDate('Date_Year', 'Date_Month', 'Date_Day')"> </form> </body> </html>
start_year、end_year、time パラメータの組み合わせについては注意が必要です。
start_year、end_year を省略すると、表示される年の選択肢は「現在の1年分だけ」になります。
よって、現在が 2025年で
{html_select_date time='2024-01-01' field_order=YMD}
と書いていると、画面上は 2025 になってしまいます。
# 年の選択肢に 2024 がないから、選択できる一番少ない値になる。
{html_select_date time='2024-01-01' start_year='2020' end_year='2023' field_order=YMD}
と書いた場合は、2020 になります。
start_year は、サポートすべき最小値にするとして、
end_year は、絶対値ではなく、プラスの数値にするのが良いかと思います。
日付の妥当性をチェックするのに一番簡単なのは、
PHP の checkdate 関数を用いる事です。
# bool checkdate ( int $month , int $day , int $year )
ですが、これだと、
フォームを送信した後でないとチェックできません。
2月31日とか指定されたとき、
入力済みの他のデータを保ったままデータ入力画面に戻るのは、
コード的に面倒ですし、
何より、ユーザーに優しくありません。
そこで、送信する前に HTML 内部の JavaScript でチェックし、
NG なら送信させないようにするのが妥当です。
例えば、以下のようにします。