フロントの人の雑多メモ

jQuery UIのDatepickerで土日祝や特定の日付を選ばせない方法

jQuery UIのDatepickerで土日祝や特定の日付を選ばせない方法

jQuery UIの「Datepicker」を使って、フォームの日付入力欄で土日祝や特定の日付を選択不可にする方法をご紹介します。

ちなみに、jQuery UIを使わずとも、普通の<input type="date">でやる方法も紹介してますのでよければご覧ください。

実装

まずは最低限のDatepickerを実装します。

必要ファイルを読み込みます。

jQuery本体とjQuery UI、CSS、日本語化ファイルの4つです。

<!-- jQuery UIのCSS -->
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.13.2/themes/base/jquery-ui.css">
<!-- jQuery本体 -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<!-- jQuery UI本体 -->
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.13.2/jquery-ui.min.js"></script>
<!-- 日本語化ファイル -->
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1/i18n/jquery.ui.datepicker-ja.min.js"></script>

inputタグを作ります。typeは"text"にしましょう。

<input type="text" id="datepicker">

③ 作ったinputタグに「datepicker()」を実行します。

$("#datepicker").datepicker();

完成したものがこちら。

クリックするとカレンダーが表示されます。

予備知識

実際に、土日を選べないサンプルがこちらなんですが

一度平日を選んでから、普通にテキスト編集して土日にできちゃうんですよね。

jQuery UIのDatepickerで土日祝や特定の日付を選ばせない方法

なので、datepickerの設定で土日を選べないようにはするんですが、

それとセットで、必ず値のチェックもしてあげないといけないです。

最終的には、サーバー側のチェックも必要ですが。

そのコードも一緒に書いていくので、頭に入れておいていただけるとスムーズです!

目次

土日を選ばせないサンプル

サンプル 土日が選べないと思います。

ソースコードはこんな感じ。

//Datepicker
$("#datepicker").datepicker({
	beforeShowDay: function (date) {
		//日曜(0)または土曜(6)のとき
		if (date.getDay() == 0 || date.getDay() == 6) {
			return [false, "ui-state-disabled"];
		}else{
			return [true, ""];
		}
	}
});
//テキスト編集した際のアラート
$("#datepicker").on("change", function(){
	//内容を取得
	let val = $(this).val();
	//整形
	let date = new Date(val);
	//土日のとき
	if(date.getDay() == 0 || date.getDay() == 6){
		//アラート
		alert("その日は選択できません。");
		//inputを空に
		$(this).val("");
	}
});

Datepickerの設定の「beforeShowDay」というものを使っています。

.getDay()で取得した曜日が、日曜(0)または土曜(6)のときに選択不可にし、「ui-state-disabled」というクラスを付与しています。

ui-state-disabled」というクラスはjQuery UIのCSSで用意されてるクラスで、非アクティブのボタンを半透明にするスタイルが当たります。

そして、先述の通り、あとからテキスト編集して土日にできちゃうので、後半でその対処を行っています。

例えば、火曜日を選択不可にしたい場合は、if文2箇所を下記のように修正してください。

if(date.getDay() == 2)

土日祝を選ばせないサンプル

サンプル

祝日を判定するために、こちらのライブラリをお借りします。

japanese-holidays-js

このようにすると、祝日の場合、変数「holiday」に祝日の名前が。
祝日じゃない場合はundefinedが入ります。

<script src="https://cdn.rawgit.com/osamutake/japanese-holidays-js/v1.0.10/lib/japanese-holidays.min.js"></script>
<script>
let date = new Date();
let holiday = JapaneseHolidays.isHoliday(date);
</script>

これを使って土日祝を選ばせないサンプルを作ってみます。

サンプルコード

<script src="https://cdn.rawgit.com/osamutake/japanese-holidays-js/v1.0.10/lib/japanese-holidays.min.js"></script>
<script>
$(function(){
	//Datepicker
	$("#datepicker").datepicker({
		beforeShowDay: function (date) {
			//祝日かどうか
			let holiday = JapaneseHolidays.isHoliday(date);
			//日曜(0)または土曜(6)または祝日のとき
			if (date.getDay() == 0 || date.getDay() == 6 || holiday) {
				return [false, "ui-state-disabled"];
			}else{
				return [true, ""];
			}
		}
	});
	//テキスト編集した際のアラート
	$("#datepicker").on("change", function(){
		//内容を取得
		let val = $(this).val();
		//整形
		let date = new Date(val);
		//祝日かどうか
		let holiday = JapaneseHolidays.isHoliday(date);
		//土日または祝日のとき
		if(date.getDay() == 0 || date.getDay() == 6 || holiday){
			//アラート
			alert("その日は選択できません。");
			//inputを空に
			$(this).val("");
		}
	});
});
</script>

「holiday」に祝日の名前が入っていれば弾く という条件を追加しています。

こちらも先述の通り、後からテキスト編集できちゃうので、その対処を後半でやってます。

例えば火曜と祝日を選べないようにする場合は、if文2箇所をこのようにしてください。

if(date.getDay() == 2 || holiday)

過去と土日祝を選ばせないサンプル

サンプル

<script src="https://cdn.rawgit.com/osamutake/japanese-holidays-js/v1.0.10/lib/japanese-holidays.min.js"></script>
<script>
$(function(){
	//Datepicker
	$("#datepicker").datepicker({
		minDate: new Date(),
		beforeShowDay: function (date) {
			let holiday = JapaneseHolidays.isHoliday(date);
			//日曜(0)または土曜(6)または祝日のとき
			if (date.getDay() == 0 || date.getDay() == 6 || holiday) {
				return [false, "ui-state-disabled"];
			}else{
				return [true, ""];
			}
		}
	});
	//テキスト編集した際のアラート
	$("#datepicker").on("change", function(){
		//内容を取得
		let val = $(this).val();
		//整形
		let date = new Date(val);
		//祝日かどうか
		let holiday = JapaneseHolidays.isHoliday(date);
		//今日
		let today = new Date();
		//今日と選択された日付を比較 (過去ならマイナス、未来ならプラスになる)
		let is_future = new Date(formatDate(date)) - new Date(formatDate(today));
		//土日または祝日または過去のとき
		if(date.getDay() == 0 || date.getDay() == 6 || holiday || is_future < 0){
			//アラート
			alert("その日は選択できません。");
			//inputを空に
			$(this).val("");
		}
	});
	//YY-MM-DDで返す関数定義
	function formatDate(dt) {
		var y = dt.getFullYear();
		var m = ('0' + (dt.getMonth()+1)).slice(-2);
		var d = ('0' + dt.getDate()).slice(-2);
		return (y + '-' + m + '-' + d);
	}
});
</script>

ちょっと長くなっちゃったんですが、これで過去の判定もできます。

Datepickerの設定で、最小の日付を指定できる「minDate」を使い、今日に設定しています。

その後、またテキスト編集できちゃうので、今日の日付と比較してマイナスならアラートを出しています。

特定の日付を選ばせないサンプル

サンプル (20日が定休日の例です。)

//特定の日付をセット
const off = ["0120", "0220", "0320", "0420", "0520", "0620", "0720", "0820", "0920", "1020", "1120", "1220"];
//Datepicker
$("#datepicker").datepicker({
	beforeShowDay: function (date) {
		//定休日の中に、選ばれた日付が含まれているとき
		if (off.indexOf(formatDay(date)) !== -1) {
			return [false, "ui-state-disabled"];
		}else{
			return [true, ""];
		}
	}
});
//テキスト編集した際のアラート
$("#datepicker").on("change", function(){
	//内容を取得
	let val = $(this).val();
	//整形
	let date = new Date(val);
	//定休日の中に、選ばれた日付が含まれているとき
	if(off.indexOf(formatDay(date)) !== -1){
		//アラート
		alert("その日は選択できません。");
		//inputを空に
		$(this).val("");
	}
});
//MMDDで返す関数定義
function formatDay(dt) {
	var m = ('0' + (dt.getMonth()+1)).slice(-2);
	var d = ('0' + dt.getDate()).slice(-2);
	return (m + d);
}

最初に定休日の配列を作成します。

2/20なら"0220"、3/5なら"0305"のように、ゼロ詰めで記入します。

その配列の中にある日付を非アクティブにします。

土日祝と特定の日付を選ばせないサンプル

今までの組み合わせです。

土日祝か、20日が選べない例です。

<script src="https://cdn.rawgit.com/osamutake/japanese-holidays-js/v1.0.10/lib/japanese-holidays.min.js"></script>
<script>
$(function(){
	//特定の日付をセット
	const off = ["0120", "0220", "0320", "0420", "0520", "0620", "0720", "0820", "0920", "1020", "1120", "1220"];
	//Datepicker
	$("#datepicker").datepicker({
		beforeShowDay: function (date) {
			let holiday = JapaneseHolidays.isHoliday(date);
			//土日祝または定休日の中に、選ばれた日付が含まれているとき
			if (date.getDay() == 0 || date.getDay() == 6 || holiday || off.indexOf(formatDay(date)) !== -1) {
				return [false, "ui-state-disabled"];
			}else{
				return [true, ""];
			}
		}
	});
	//テキスト編集した際のアラート
	$("#datepicker").on("change", function(){
		//内容を取得
		let val = $(this).val();
		//整形
		let date = new Date(val);
		//祝日かどうか
		let holiday = JapaneseHolidays.isHoliday(date);
		//土日祝または定休日の中に、選ばれた日付が含まれているとき
		if(date.getDay() == 0 || date.getDay() == 6 || holiday || off.indexOf(formatDay(date)) !== -1){
			//アラート
			alert("その日は選択できません。");
			//inputを空に
			$(this).val("");
		}
	});
	//MMDDで返す関数定義
	function formatDay(dt) {
		var m = ('0' + (dt.getMonth()+1)).slice(-2);
		var d = ('0' + dt.getDate()).slice(-2);
		return (m + d);
	}
});
</script>

土日祝と特定の日付を除き、○営業日以降を選択可能にするサンプル

「○営業日以降」という条件を加えてみます。 (コメントでリクエストいただきました!)

土日祝以外と、20日以外、4営業日以降しか選べない例です。

//○営業日以降の設定
const after = 4;
//特定の日付をセット
const off = ["0120", "0220", "0320", "0420", "0520", "0620", "0720", "0820", "0920", "1020", "1120", "1220"];

//今日の日付を取得
let today = new Date();

//○営業日以降になるまで数える
let i = 0;
let days = 1;
while(i < after){
	//翌日
	let next = new Date();
	next.setDate(next.getDate() + days);
	next = new Date(next);

	//祝日か判定
	let holiday = JapaneseHolidays.isHoliday(next);

	//翌日が土日でも祝日でも特定の日でもないとき
	if (next.getDay() != 0 && next.getDay() != 6 && !holiday && off.indexOf(formatDay(next)) == -1) {
		//営業日カウント
		i++;
	}
	days++;
}

//○営業日後の日付
let later = new Date();
later.setDate(later.getDate() + days);
later = new Date(later);

//Datepicker
$("#datepicker").datepicker({
	minDate: later, //○営業日後をminDateに設定
	beforeShowDay: function (date) {
		let holiday = JapaneseHolidays.isHoliday(date);
		//日曜(0)または土曜(6)または祝日または特定の日のとき
		if (date.getDay() == 0 || date.getDay() == 6 || holiday || off.indexOf(formatDay(date)) !== -1) {
			return [false, "ui-state-disabled"];
		}else{
			return [true, ""];
		}
	}
});
//テキスト編集した際のアラート
$("#datepicker").on("change", function(){
	//内容を取得
	let val = $(this).val();
	//整形
	let date = new Date(val);
	//祝日かどうか
	let holiday = JapaneseHolidays.isHoliday(date);
	//○営業日後と選択された日付を比較 (過去ならマイナス、未来ならプラスになる)
	let is_future = new Date(formatDate(date)) - new Date(formatDate(later));
	//土日または特定の日または祝日または○営業日より前のとき
	if(date.getDay() == 0 || date.getDay() == 6 || holiday || off.indexOf(formatDay(date)) !== -1 || is_future < 0){
		//アラート
		alert("その日は選択できません。");
		//inputを空に
		$(this).val("");
	}
});

//YY-MM-DDで返す関数定義
function formatDate(dt) {
	var y = dt.getFullYear();
	var m = ('0' + (dt.getMonth()+1)).slice(-2);
	var d = ('0' + dt.getDate()).slice(-2);
	return (y + '-' + m + '-' + d);
}

//MMDDで返す関数定義
function formatDay(dt) {
	var m = ('0' + (dt.getMonth()+1)).slice(-2);
	var d = ('0' + dt.getDate()).slice(-2);
	return (m + d);
}

(おまけ) 表示形式を「○年○月○日」にする

日付入力時の表示形式を「○年○月○日」にする方法。 (コメントでリクエストいただきました!)

datepicker実行時に、以下のオプションを入れればOK。

//Datepicker
$("#datepicker").datepicker({
	dateFormat: 'yy年mm月dd日'
});

例えば、一つ上のサンプル 土日祝と特定の日付を除き、○営業日以降を選択可能にするサンプル と組み合わせる場合

datepickerの箇所をこのようにしてください。

//Datepicker
$("#datepicker").datepicker({
	dateFormat: 'yy年mm月dd日',
	minDate: later, //○営業日後をminDateに設定
	beforeShowDay: function (date) {
		let holiday = JapaneseHolidays.isHoliday(date);
		//日曜(0)または土曜(6)または祝日または特定の日のとき
		if (date.getDay() == 0 || date.getDay() == 6 || holiday || off.indexOf(formatDay(date)) !== -1) {
			return [false, "ui-state-disabled"];
		}else{
			return [true, ""];
		}
	}
});

コメント

「できました!」などの報告もお待ちしております。

  • 匿名さん

    「土日祝と特定の日付を選ばせないサンプル」+「4営業日以降のみ選択可能」にするのはどうしたらいいでしょうか?

  • オーナー

    リクエストありがとうございます!

    早速作ってみたので、こちらで意図したものになっているかご確認ください!

  • 匿名さん

    無料でこのような記事を掲載してくださってありがとうございます。

    web関連の初心者にも分かりやすく解説していただいて感謝しかありません!

    土日祝と特定の日付を除き、○営業日以降を選択可能にするサンプルをコピペで実装させていただいたのですが、表示形式を【〇年〇月〇日】に変更するにはどうすればよいでしょうか?

    出来れば曜日の表示までできたら最高なのですが、もし可能であればご教示いただけますと幸いです。

  • オーナー

    リクエストありがとうございます!

    (おまけ) として追記いたしました。 こちらで意図したものになっているかご確認ください!

  • 匿名さん

    オーナー様、早速のご対応誠にありがとうございます。

    初心者ながらにdateFormatの追記は試していたのですが、できなかったのですが、原因は分かりました。

    (完全に解決はできておりません。)

    //Datepickerの$("#datepicker")を実際に付与したいclass名に置き換えていたので、//テキスト編集した際のアラート内の$("#datepicker")も同様にclass名に置き換えていたところ、カレンダーの選択可能な日を選択するとアラート"その日は選択できません。"と出てしまっておりました。

    //テキスト編集した際のアラート内の$("#datepicker")のみをそのままにすることで選択可能日は意図した通りに動作するのですが、テキスト編集は出来てしまいます。

    初心者過ぎてもっと勉強してからにしろ!といった内容なのかもしれませんが、本当にお時間があるときにでもご教示いただけますと幸いです。

  • オーナー

    想像ですが、2つの原因が考えられます。

    1つは
    選択可能な日を選択するとアラート"その日は選択できません。"と出てしまっておりました。
    という部分が気になります。

    datepicker()内の条件と、onChange()内の条件が異なっているのではないでしょうか?

    こちらの例のように、datepicker()内とonChange()内の2箇所に出てくるif文 if (date.getDay() == 0 || date.getDay() == 6 || holiday || off.indexOf(formatDay(date)) !== -1) は同じになる必要があります。

    date.getDay()formatDay(date)などの中身も同じ内容が入っているのか?ご確認ください。

    2つ目は、class使われてるということは、複数のinputタグを設置されていないでしょうか?

    複数のinputがある場合は、以下のようにeach文で回すほうが安全です。

    $(".datepicker").each(function(){
    	//Datepicker
    	$(this).datepicker({
    		(略)
    	});
    	//テキスト編集した際のアラート
    	$(this).on("change", function(){
    		(略)
    	});
    });

    または複数のinputで条件が異なる場合、classをしっかり分けて別の関数としたほうが、最初は分かり易いかと思います。

    //Datepicker
    $(".datepicker.type01").datepicker({
    	(略)
    });
    //テキスト編集した際のアラート
    $(".datepicker.type01").on("change", function(){
    	(略)
    });
    
    //Datepicker
    $(".datepicker.type02").datepicker({
    	(略)
    });
    //テキスト編集した際のアラート
    $(".datepicker.type02").on("change", function(){
    	(略)
    });

    これ以上は実際のソースを見てみないと何とも...

  • 匿名さん

    「特定の日付を選ばせない」を探しており稼働できたのはこちらでした。

    大変助かりました。感謝いたします。

  • オーナー

    ご報告ありがとうございます!

  • 匿名さん

    無料で公開していただいて大変感謝しております。

    たとえば

    現在の時間を取得して、午前中であれば、翌日の日付を選択することができるが、午後以降は翌々日からの日付を選択するといったことは可能でしょうか?

    お忙しいところ大変恐縮ですが、教えていただければ幸いです。

  • オーナー

    時間の判定をどこまで厳密にやるか?にもよりますが、ページを開いた時点での時刻の判定で良いのなら
    こちらのサンプルをベースに、2行目の「after」変数の定義部分を以下のようにすればいいと思います!

    //○営業日以降の設定
    let after = 0; //翌営業日にセット
    //現在の時間を取得
    const now = new Date();
    const hour24  = now.getHours();
    //時間を12時間表記で取得
    var hour12 = hour24 % 12;
    //午後なら
    if(hour12 >= 12){
    	after = 1; //翌々営業日にセット
    }

内容を確認の上、個人情報などは省いて掲載させていただきます。

お名前・メールアドレスも入力する

メールで返信がほしい場合に入力してください。

頂いた個人情報は開示しません。返信のためだけに利用いたします。

直接送信されます。確認の上、「送信」してください。

お役に立てましたら応援をお待ちしております!
頂いた応援は子育てに活用させていただきます。

OFUSEで応援を送る


または以下のボタンからなにか買って応援 (PR)

Amazon

楽天市場

Yahoo!ショッピング

Amazonのアソシエイトとして「けん」は適格販売により収入を得ています。

シェア

Twitterでシェア Facebookでシェア LINEでシェア はてなブックマークでシェア

お役に立てましたら応援をお待ちしております!
頂いた応援は子育てに活用させていただきます。

OFUSEで応援を送る