PHPを用いてjQueryのDatepickerの特定の日付のみ選択可能にする

 このブログを立ち上げるにあたって、やたら情報がある割には目当ての内容もしくはそれに繋がるモノ

が余り無かった jQueryのDatepicker上の特定の日付のみ選択可能にする方法について書いてみたいと

思います。ちなみに、特定の日付はPHPを使って取って来ることにします。

(※jQuery並びにDatepickerの設定については省略します)



まずはハイライト前のDatepickerを表示させてみます

html↓
<!DOCTYPR html>
<html>
 <head>
  <meta charset="utf-8">
  <title>Datepicker Demo</title>
  <link href="./../../css/jquery-ui.min.css" rel="stylesheet" type="text/css" />
  <link href="./../../css/jquery.ui.datepicker.min.css" rel="stylesheet" type="text/css" />
  <script src="./../../js/jquery/jquery-1.9.1.min.js"></script>
  <script src="./../../js/jquery/jquery-ui.custom.min.js"></script>
  <script src="./../../js/jquery/jquery.ui.datepicker-ja.min.js"></script>
  <script src="./demo_dp.js"></script>
 </head>
    <body>
        <div id="demo_cal" style="font-size:18px;"></div>
    </body>
</html>
 
datepickerを表示するjavascript( demo_dp.js )↓
 $(function()
{
  $('#demo_cal').datepicker();

});
これらを適切な場所に置けば、以下の画像の様に表示されます。(デモページ)

demo_dp_plane.PNG

 さて、見ただけで全ての日付が選択可能な状態だと分かりますね。今からこれを、ブログに記事を投稿

した日付のみ選択可能にするといった要望に応えられる様にするのですが、とりあえず話を簡単にする

為に、決め打ちの日付だけ選択可能にした例を書いてみます。

※htmlは基本上記と同じなので省略


決め打ちの日付のみ選択可能にするjavascript( demo_slct_dp.js )↓
$(function()
{
	$('#demo_cal').datepicker
	({

		beforeShowDay: function(date) 
		{
			var month = String( date.getMonth() + 1 );

			var day = String( date.getDate() );

			if( month.length == 1 )
				month = '0'+month;

			if( day.length == 1)
				day = '0'+day;

			var check_date = date.getFullYear()+"-"+month +"-"+day;


			if(check_date == "2014-05-02")
			  return [true];

 			else
		          return [false];
		}

	});

});
これを実行すると、次の様に表示されます。(デモページ)
demo_dp_sselect.PNG"

ここで重要なのは、beforeShowDay で、これは各日付をDatePicker内に表示する直前に呼び出さ

れる関数で、引数のdateには表示されている月の日付( 実際には表示枠にある前後の月の数日分も

含まれる )の1つが入っており、この中で選択可能か否かの設定を行います。この処理が前後の月の

数日分を含めて35回行われることで、カレンダーを表示させている形となるわけです。

 このbeforeShowDayで戻り値として[true]とすると選択可能、[false]とすると選択不能と出来ます。

※実際には配列の2,3番目に要素を指定する事も出来ますが、ここでは扱いません。

 あとは$.postなり、$.ajaxでPHPに処理を任せて終わりだと、このブログを作成中に思ったのですが

$.post , $.ajaxは指定をしない限り、非同期通信だということを知らなかった為ドツボに嵌ったのは

言うまでもありませんw

PHPのコードは直接関係のないmysql部分などに関しては省略します。
PHP( get_data.php )↓
<?php
 /*
  mysqlへの接続及びデータ取得処理など
              .
              .
              .
 該当する日付のデータが あったら $flg = true;
                     なかったら $flg = false
 */
  if( $flg )
    echo  "true";   //js側に戻り値として文字列"true"を渡す

  else
    echo  "false";  //js側に戻り値として文字列"false"を渡す
?>
javascript側↓
$(function()
{
	$('#demo_cal').datepicker
	({

		beforeShowDay: function(date) 
		{
            var flg = false;

			var month = String( date.getMonth() + 1 );

			var day = String( date.getDate() );

			if( month.length == 1 )
				month = '0'+month;

			if( day.length == 1)
				day = '0'+day;

			var check_date = date.getFullYear()+"-"+month +"-"+day;

             $.ajax({
				type: 'POST',
				url:'./../../get_data.php',
				data:{
				"date":chk_date
				},
				async: false,
                  
                success:function(res){
					
				if(res == "true")
					flg = true;

				else
					flg =false;		
			
		       },});

			if(flg)
			  return [true];

 			else
		          return [false];
		}

	});

});
$.ajax内の async:false が重要 といったカタチでやってやれば、特定の日付のみを選択可能にすることが出来ます。

 ただし、上記の方法だと35回もPHPファイルにPOSTでアクセスする為データベースを用いてなくとも

表示に時間が掛かると思われるので、本番で稼動させる場合は$(function()内と、datepicker内の

onChangeMonthYearにて、$.ajaxで該当する全ての日付を取得するPHPにアクセスさせて、アク

セス回数を減らすのが妥当かと思います。またその際に複数のデータをPHPからjs側に渡すことになると

思いますが、その場合はPHP側で一度該当データを配列に入れて、それを

join( ',' , $配列 );

としたものを echo してjs側で split を使って配列にして扱うと良いかと思います。