baserCMS メールフォームのカレンダーフィールドでDatepickerを使う場合のあれこれ

- 2024/3/6 に更新
以下のようなオプションの記述例を追記。・曜日を指定して選択不可(例:土日選択不可、第1、第3金曜日選択不可など)
・祝日を選択不可
・不定休日を指定して選択不可
テーマファイル「bc_sample」を利用してサイト制作を行なっている場合、メールフォームなどのユーザー画面側でDatepickerのUIを表示付きの日付入力欄を設置するのに必要なjs やcssは、以下のように既にレイアウトファイルで読み込み済みです。
<?php $this->BcBaser->css([
'jquery-ui/jquery-ui-1.11.4'
]) ?>
<?php $this->BcBaser->js([
'jquery-1.11.3.min',
'jquery-ui-1.11.4.min',
'i18n/ui.datepicker-ja'
]) ?>
そのため、特に何もしなくても、以下のbaserCMS管理画面のフィールド一覧からカレンダータイプのフィールドを作成するだけで簡単にDatepickerのUIを表示付きの日付入力欄が作成できます。
ところが、マーケット等にアップされているその他ほとんどのテーマは、上述したjs、cssは適用されていないため、baserCMS管理画面のフィールド一覧からカレンダータイプのフィールドを選択しただけでは、ユーザー画面側にDatepickerを表示することはできません。
表示させるためには、「bc-sample」と同様にthemeフォルダ内に上記のjs やcssを格納し、レイアウトファイルで呼び出すか、あるいは、Mailフォルダ内のメールフォーム用のレイアウトファイル(具体的には、theme/利用テーマ/Mail/default/index.phpおよびconfirm.php)に次の例のようなコードを記述して直接コアファイル内の該当ファイルを呼び出す必要があります。
なお、jQuery本体は、ほとんどのテーマのレイアウトファイルで既に読み込まれているので、特に記載していませんが、必要な場合は、他のjsファイルを読み込む前に最初に読み込みます。
<link rel="stylesheet" type="text/css" href="/css/admin/jquery-ui/jquery-ui.min.css"/>
<script type="text/javascript" src="/js/admin/vendors/jquery-ui-1.11.4.min.js"></script>
<script type="text/javascript" src="/js/admin/vendors/i18n/ui.datepicker-ja.js"></script>
表示日付を制御
さて、カレンダータイプのフィールドの使い道としてよくあるのが、予約フォームっぽい使い方。その場合、できれば過去の日付はDatepickerで選択させたくないし、inputフィールドに過去の日付を直接入力されないようにもしたいところ。 例えば、以下のようにDatepickerのオプションを記述することで対応できます。 記載した例は、それ以外にも、使い出のありそうなオプションもあわせて記載してみました。
- 3日後から選択可能
- 3ヶ月先まで選択可能
- 曜日を指定して選択不可(土日選択不可、第1、第3金曜日選択不可など)
- inputフィールドへのキーボード入力の禁止
など。
<link rel="stylesheet" type="text/css" href="/css/admin/jquery-ui/jquery-ui.min.css"/>
<script type="text/javascript" src="/js/admin/vendors/jquery-ui-1.11.4.min.js"></script>
<script type="text/javascript" src="/js/admin/vendors/i18n/ui.datepicker-ja.js"></script>
<script>
jQuery(function($){
$('#MailMessageDate').datepicker({
// 3日後から選択可能
minDate: '+3d',
// 3ヶ月先まで選択可能
maxDate: '+3m',
// 曜日を指定して選択不可
beforeShowDay: function(date) {
if(date.getDay() == 0 || date.getDay() == 6) return [false, 'ui-state-disabled']; // 土日選択不可
if(date.getDay() == 5 && $.inArray(Math.floor((date.getDate()-1)/7),[0, 2])>-1) return [false, 'ui-state-disabled']; // 第1、第3金曜日選択不可
return [true, ''];
}
});
// inputにフォーカス時、変更不可
$('#MailMessageDate').focusin(function(e) {
$(this).attr('readOnly', 'true');
})
.focusout(function(e) {
$(this).removeAttr('readOnly');
});
});
</script>
また、複数のカレンダーフィールドを一括して記載する場合は、たとえば以下のように記述。
先の例に追加して、以下のオプションもあわせて記載してみました。
- 祝日を選択不可
- 不定休日を指定して選択不可
祝日を追加するために「japanese-holidays-js 」のライブラリを利用させていただきました。
GitHubのソースをDLして、lib内の japanese-holidays.min.js をjsフォルダ内の格納して呼び出しても良いかと思いますが、ひとまず、以下のように japanese-holidays.min.js のCDN読み込み用スクリプトを追記します。
<script src="https://cdn.jsdelivr.net/gh/osamutake/japanese-holidays-js@v1.0.10/lib/japanese-holidays.min.js"></script>
<link rel="stylesheet" type="text/css" href="/css/admin/jquery-ui/jquery-ui.min.css"/>
<script type="text/javascript" src="/js/admin/vendors/jquery-ui-1.11.4.min.js"></script>
<script type="text/javascript" src="/js/admin/vendors/i18n/ui.datepicker-ja.js"></script>
<script src="https://cdn.jsdelivr.net/gh/osamutake/japanese-holidays-js@v1.0.10/lib/japanese-holidays.min.js"></script>
<script>
jQuery(function($){
$('#MailMessageDate, #MailMessageDate2').each(function(){
$(this).datepicker({
//3日後から選択可能
minDate: '+3d',
//3ヶ月先まで選択可能
maxDate: '+3m',
//曜日等を指定して選択不可
beforeShowDay: function(date) {
let holiday = JapaneseHolidays.isHoliday(date);
if(holiday) return [false,'ui-state-disabled', holiday]; //祝日を選択不可
let irregularHolidays = [
"2024/05/15",
"2024/06/15"
];
let dateFormat='yy/mm/dd';
let irregularHoliday = $.datepicker.formatDate(dateFormat, date);
if($.inArray(irregularHoliday,irregularHolidays)>-1) return [false,'ui-state-disabled','不定休日']; //年月日を指定して選択不可
if(date.getDay() == 0 || date.getDay() == 6) return [false, 'ui-state-disabled','定休日']; // 土曜、日曜を指定して選択不可
if(date.getDay() == 5 && $.inArray(Math.floor((date.getDate()-1)/7),[0, 2])>-1) return [false, 'ui-state-disabled','定休日']; // 第1、第3金曜日を指定して選択不可
return [true, ''];
}
});
});
// inputにフォーカス時、変更不可
$('#MailMessageDate, #MailMessageDate2').each(function(){
$(this).focusin(function(e) {
$(this).attr('readOnly', 'true');
})
.focusout(function(e) {
$(this).removeAttr('readOnly');
});
});
});
</script>