PHP+jQueryでカレンダーを作る&日付も取得する
前回作った祝日対応カレンダーを利用して、日付をクリックしたら、その日付を取得して、フォームに代入する処理を行います。
▼前回のカレンダーはこちらです
日付取得にはjQueryを使います。
イマドキjQueryなんて、と言われそうですが、jQuery使う方が簡単なので許してください。
jQueryが苦手な方はこちらの記事を読むのがオススメです。
日付取得の流れを考えて言語化する
PHP+HTMLで作られたカレンダーから、クリックした日付を取得したいので、トリガーが「日付をクリック」になります。
もう少し具体的に言うと、日付を表示させている<td>タグをクリックしたら、がトリガーです。
クリックした日付を取得したいので、<td>にdata-dateという属性を追加して、それを取得します。
取得した日付のdata-dateをフォームタグに代入します。
言語化した内容をプログラムで組む
やりたいことが言語化できたので、これをjQueryの文法に当てはめれば完了ですね。
言語化できればプログラムは組めます。
前回作ったカレンダーのプログラム
完成版のソースを先に出しておきます。
要件を整理すると、土日祝日は予約のできないカレンダーを作ってほしい、というものでした。
PHPソース
//祝日の読み込み
$file = new SplFileObject("img/syukujitsu.csv");
$file->setFlags(SplFileObject::READ_CSV);
$syuku_array = array();
foreach ($file as $line) {
if(isset($line[1])){
$date = date("Y-m-d",strtotime($line[0]));
$name = $line[1];
$syuku_array[$date] = $name;
}
}
$week = array('日','月','火','水','木','金','土');
$now_month = date("Y年n月"); //表示する年月
$start_date = date('Y-m-01'); //開始の年月日
$end_date = date("Y-m-t"); //終了の年月日
$start_week = date("w",strtotime($start_date)); //開始の曜日の数字
$end_week = 6 - date("w",strtotime($end_date)); //終了の曜日の数字
echo '<table class="cal">';
//該当月の年月表示
echo '<tr>';
echo '<td colspan="7" class="center">'.$now_month.'</td>';
echo '</tr>';
//曜日の表示 日~土
echo '<tr>';
foreach($week as $key => $youbi){
if($key == 0){ //日曜日
echo '<th class="sun">'.$youbi.'</th>';
}else if($key == 6){ //土曜日
echo '<th class="sat">'.$youbi.'</th>';
}else{ //平日
echo '<th>'.$youbi.'</th>';
}
}
echo '</tr>';
//日付表示部分ここから
echo '<tr>';
//開始曜日まで日付を進める
for($i=0; $i<$start_week; $i++){
echo '<td></td>';
}
//1日~月末までの日付繰り返し
for($i=1; $i<=date("t"); $i++){
$set_date = date("Y-m",strtotime($start_date)).'-'.sprintf("%02d",$i);
$week_date = date("w", strtotime($set_date));
//土日で色を変える
if($week_date == 0){
//日曜日
echo '<td class="sun ng">'.$i.'</td>';
}else if($week_date == 6){
//土曜日
echo '<td class="sat ng">'.$i.'</td>';
}else if(array_key_exists($set_date,$syuku_array)){
//祝日
echo '<td class="sun ng">'.$i.'</td>';
}else if($i < $now_date){
//過去日付はNG
echo '<td class="ng">'.$i.'</td>';
}else{
//平日
echo '<td data-date="'.$set_date.'" class="ok">'.$i.'</td>';
}
if($week_date == 6){
echo '</tr>';
echo '<tr>';
}
}
//末日の余りを空白で埋める
for($i=0; $i<$end_week; $i++){
echo '<td></td>';
}
echo '</tr>';
echo '</table>';
jQuery ソース
<script>
$(".ok").click(function(){
let get_date = $(this).data("date");
$('input[name="get_date"]').val(get_date);
});
</script>
出来上がった祝日がクリックできないカレンダー
クリックできない日付はグレーになり、白い日付はマウスオーバーでカーソルになり、クリックすると日付のテキストがフォームに代入されます。
また、予約日を選択するカレンダーであるため、過去の日付もクリックできないようにしています。
| 2026年2月 | ||||||
| 日 | 月 | 火 | 水 | 木 | 金 | 土 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
日付:
土日祝日除外カレンダーPHPソースの解説
カレンダー制作の基礎的な解説は前回の記事を見ていただくとして、今回付け加えた部分を解説します。
付け足したのは、CSSのクラスと、現在日付の取得、data属性になります。
予約可能日はclass="ok" それ以外はngを設定
予約可能日のtdにはclass="ok"を設定し、それ以外の日付にはngのクラスを振ります。
css側で見た目と、マウスオーバー時のアクションを設定します。
予約が可能な日付の場合、data-dateという属性をつけて、日付を設定します。
echo '<td data-date="'.$set_date.'" class="ok">'.$i.'</td>';
jQueryでクリックした日付を取得→代入の処理
予約可能な日付の<td>をクリックした場合をトリガーにするので、okのクラスを持っているtdをクリックした場合、に処理をします。
$(".ok").click(function(){
クリックしたtdのdata-dateを取得する変数を作ります。
let get_date = $(this).data("date");
取得した日付をinputのvalueに代入します。
$('input[name="get_date"]').val(get_date);
これで土日祝日がクリックできないカレンダーが完成しました。
見せ方や出し方はCSSで調節して、お好みに合わせて完成です。
といいたいところなんですが、このままだと月末に近づくにつれて、予約できる日付が存在しなくなる問題があります。
なので、三ヵ月先まで進めるカレンダーにします。
何か月でもいいんですが、あまり先の予約ができても仕方がないので、三ヵ月くらいがいいんじゃないかと。
月送り&戻し機能をつけたカレンダー
現在の月から3ヵ月先までめくれるカレンダーがこちら。
矢印の↑をクリックで次月、↓をクリックで前月に戻ります。
前後3ヵ月を超える場合は矢印が表示されません。
| 2026年2月 | ↓ | |||||
| 日 | 月 | 火 | 水 | 木 | 金 | 土 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
| ↑ | 2026年3月 | ↓ | ||||
| 日 | 月 | 火 | 水 | 木 | 金 | 土 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
| 29 | 30 | 31 | ||||
| ↑ | 2026年4月 | |||||
| 日 | 月 | 火 | 水 | 木 | 金 | 土 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | ||
基本的な作り方がわかれば、この辺の応用はいろいろなやり方が考えられますね。
月縛りなしで、カレンダーのめくり機能をつけるなら、ajaxを使って取得したい年月日をカレンダー化するのが良いかと思います。
今回のサンプルは、カレンダーを3つ(3ヵ月分)作って、jQueryのfadeInで月の切り替えを行う方式にしています。
細かい解説はあえてしませんが、同じことの繰り返しとなっています。
最終のソースと概要だけ解説して終わりたいと思います!
echo '<div class="cal_disp">';
//祝日の読み込み
$file = new SplFileObject("img/syukujitsu.csv");
$file->setFlags(SplFileObject::READ_CSV);
$syuku_array = array();
foreach ($file as $line) {
if(isset($line[1])){
$date = date("Y-m-d",strtotime($line[0]));
$name = $line[1];
$syuku_array[$date] = $name;
}
}
$week = array('日','月','火','水','木','金','土');
$get_date = date("Y-m");
//3ヵ月分なので3回繰り返し
for($x=0; $x<3; $x++){
//▼年月に-1を付けて月初を生成
$tt = $get_date.'-1';
//▼現在の日付を起点にfor文の該当月を生成
$now_date = date('Y-m-01', strtotime($tt.'+'.$x.' month'));
//▼カレンダーの見出しの年月用
$now_month = date("Y年n月",strtotime($now_date."+".$x." month"));
//▼毎月の月末日付取得
$end_day = date("t",strtotime($now_date));
//▼月初めの空セルの生成用
$start_week = date("w", strtotime($now_date.'-01'));
//▼jQueryで制御するためユニークなクラスをつける
echo '<div class="set_cal'.$x.'">';
echo '<table class="cal">';
//該当月の年月表示
echo '<tr>';
if($x != 0){
$set_x = $x -1;
//▼前月に戻す
echo '<td class="pre" data-pre="'.$set_x.'">↑</td>';
}else{
echo '<td></td>';
}
echo '<td colspan="5" class="center">'.date("Y年n月",strtotime($now_date)).'</td>';
if($x != 2){
$set_n = $x +1;
//▼次月にすすむ
echo '<td class="next" data-next="'.$set_n.'">↓</td>';
}else{
echo '<td></td>';
}
echo '</tr>';
//曜日の表示 日~土
echo '<tr>';
foreach($week as $key => $youbi){
if($key == 0){ //日曜日
echo '<th class="sun">'.$youbi.'</th>';
}else if($key == 6){ //土曜日
echo '<th class="sat">'.$youbi.'</th>';
}else{ //平日
echo '<th>'.$youbi.'</th>';
}
}
echo '</tr>';
//日付表示部分ここから
echo '<tr>';
//開始曜日まで日付を進める
for($i=0; $i<$start_week; $i++){
echo '<td></td>';
}
//1日~月末までの日付繰り返し
$now_date_ymd = strtotime(date("ymd"));
for($i=1; $i<=$end_day; $i++){
$set_date = date("Y-m",strtotime($now_date)).'-'.sprintf("%02d",$i);
$week_date = date("w", strtotime($set_date));
$set_date_ymd = strtotime($set_date);
//土日で色を変える
if($week_date == 0){
//日曜日
echo '<td class="sun ng">'.$i.'</td>';
}else if($week_date == 6){
//土曜日
echo '<td class="sat ng">'.$i.'</td>';
}else if(array_key_exists($set_date,$syuku_array)){
//祝日
echo '<td class="sun ng">'.$i.'</td>';
}else if($now_date_ymd >= $set_date_ymd){
//過去日付はNG
echo '<td class="ng">'.$i.'</td>';
}else{
//平日
echo '<td data-date="'.$set_date.'" class="ok">'.$i.'</td>';
}
if($week_date == 6){
echo '</tr>';
echo '<tr>';
}
}
//末日の余りを空白で埋める
for($i=$week_date; $i<6; $i++){
echo '<td></td>';
}
echo '</tr>';
echo '</table>';
echo '</div>';
}//end for
echo '</div>';
月送りのjQuery
.nextと.preが追加されています。
.next か .pre をクリックすると次のカレンダーをfadeInして表示してます。
<script>
$(".ok").click(function(){
let get_date = $(this).data("date");
$('input[name="get_date"]').val(get_date);
});
$(".pre").click(function(){
let pre = $(this).data("pre");
$(".cal_disp div").hide();
$(".cal_disp .set_cal" + pre).fadeIn();
});
$(".next").click(function(){
let next = $(this).data("next");
$(".cal_disp div").hide();
$(".cal_disp .set_cal" + next).fadeIn();
console.log(next);
});
</script>







![3ステップでしっかり学ぶ MySQL入門 [改訂2版]](https://m.media-amazon.com/images/I/51FX0tNDn0L._SL500_.jpg)

![WordPressユーザーのためのPHP入門 はじめから、ていねいに。[第3版] 〈WordPress 5.x/Gutenberg対応〉](https://m.media-amazon.com/images/I/51rM2DlCdlL._SL500_.jpg)
