完成イメージ
確認ボタンを押した時に、必須項目にエラーが出ても日付選択カレンダーが表示されるように調整しました。
その解決法も含めてご紹介します。
フォームの設定
Snow Monkey Forms の設定を画像で説明します。

まずは、テキスト入力のセットを作成します。
このフォームは、来店予約を想定して設定します。
日付を選択する部分

- placeholder属性には、「クリックで日付を選択」などとクリックを促す文言を入れます。
- class属性には、「js-datepicker」などと日付選択用のクラス名を入れてください。
(クラス名は、好きに決めても大丈夫です。)
時間を選択する部分

- placeholder属性には、「クリックで時間を選択」などとクリックを促す文言を入れます。
- class属性には、「js-timepicker」などと日付選択用のクラス名を入れてください。
(クラス名は、好きに決めても大丈夫です。)
日付選択カレンダーの導入
使用プラグインの選定について
最初に「air-datepicker」での実装を試みました。
↓参考記事(Snow Monkey Formsの実装方法も参考にしております🙇♀️)

「air-datepicker」を使用して日付選択カレンダーを実装しましたが、時間選択がスライダーになっていました。

引用元:https://air-datepicker.com/examples
クライアントの要望により以下の理由で「pickadate.js」を採用しました。
- 日時の項目を分けたい
- 時間をプルダウンで選択できるようにしたい(プルダウン内の時間の間隔はあらかじめ指定する)
pickadate.jsの特徴
- 日付と時間の項目を分けて設定できる
- 時間をプルダウンで選択可能
(時間の間隔はJavaScriptで指定できます。) - カスタマイズが容易
JavaScriptやCSSで簡単にカスタマイズが可能。CSSで曜日ごとの休業日などの色変更が可能。 - 日本語対応
「2024年4月1日 日曜日」のように日本語フォーマットに対応。
注意点として、jQueryが必須です。
ビルドツールを使用する場合
ビルドツールを使用する場合、GitHubでnpmのダウンロード方法が紹介されています。
GitHub:
ビルドツールを使用しない場合
ライブラリをダウンロードして使用する方法をご紹介します。
↓参考記事(pickadate.jsの選定の決め手になりました!🙇♀️)

公式サイトからダウンロード
公式サイトのファーストビューに、ダウンロードボタンがあるのでクリックしてください。

公式サイト
必要なファイルをインストールする
ダウンロードしたZipファイルは、以下の画像のような構造になっています(version 3.6.3)

ここから、システムとして必要なファイルをコピーし、自分のプロジェクトフォルダに入れます。
(WordPressへの読み込ませ方は、下で解説します。)
最低限必要なファイルは、以下になります。
└── lib
└── compressed (圧縮された軽量ファイル)
├── legacy.js
├── picker.date.js (日付を選択する時に実装)
├── picker.js
├── picker.time.js (時間を選択する時に実装)
└── themes
├── default.css
├── default.date.css (日付を選択する時に実装)
└── default.time.css (時間を選択する時に実装)
上記だけでは英語で表示されます。
英語のフォーマットはこのような形になります。
(カレンダーの表示は、デフォルトのものです。)

日付を選択する場合

時間を選択する場合
もし、「曜日」や「下のボタンの英語部分」を日本語に変更したい場合は、翻訳ファイルも必要になります。
導入方法は下でご説明します。
日本語対応させる時は、翻訳ファイルもインストール
翻訳ファイルは、以下のフォルダに入っているものを使用します。

└── lib
└── compressed (圧縮された軽量ファイル)
└── translations
└── ja_JP.js
これを入れると、「曜日」や「下のボタンの英語部分」が日本語に変わります。
しかし、一番右下の「Close」は英語のままです。
これは、後のJavaScriptで細かくカスタマイズできますのでご安心ください!

WordPressのテーマファイルに設定する
上で説明したファイルを、WordPressのテーマに設定していきます。
functions.php
条件分岐で、フォームのページにのみJavaScriptを読み込ませています。
ディレクトリ構造は、ご自分のプロジェクトに合わせてください。
function register_script() {
if ( is_page( 'contact' ) ) {
wp_enqueue_script( 'picker01', esc_url( get_template_directory_uri() ) . '/dist/js/assets/picker.js', array( 'jquery' ), '1.0.0', true );
wp_enqueue_script( 'picker02', esc_url( get_template_directory_uri() ) . '/dist/js/assets/picker.date.js', array( 'jquery' ), '1.0.0', true );
wp_enqueue_script( 'picker03', esc_url( get_template_directory_uri() ) . '/dist/js/assets/picker.time.js', array( 'jquery' ), '1.0.0', true );
wp_enqueue_script( 'picker04', esc_url( get_template_directory_uri() ) . '/dist/js/assets/legacy.js', array( 'jquery' ), '1.0.0', true );
wp_enqueue_script( 'picker05', esc_url( get_template_directory_uri() ) . '/dist/js/assets/ja_JP.js', array( 'jquery' ), '1.0.0', true );
wp_enqueue_script( 'contact', esc_url( get_template_directory_uri() ) . '/dist/js/contact.js', array( 'jquery' ), '1.0.0', true );
}
}
add_action( 'wp_enqueue_scripts', 'register_script' );
CSS(SCSS)
head
タグ内にlink
タグで読み込ませても使えます。
私は管理しやすいように、SCSSで次のように使いました。
//フォームのページのSCSS--------
// pickadate.jsのデフォルトcss
@use "./default.css";
@use "./default-date.css";
@use "./default-time.css";
// カスタム用のcss
@use "./picadate-custom";
カスタム用のCSSは次のようにしました。
.js-datepicker,
.js-timepicker {
cursor: pointer; //カーソルをポインターにする
}
//日付ピッカー==================
.picker__table {
th,
td {
text-align: center;
}
//曜日----------
.picker__weekday {
&:first-of-type {
//日曜日を赤に
color: #ff1616;
}
&:last-of-type {
//土曜日を青に
color: #1649ff;
}
}
//日付----------
tbody {
tr {
td {
&:first-of-type {
//日曜日を赤に
.picker__day {
&.picker__day--infocus {
&:not(.picker__day--disabled) {
color: #ff1616;
}
}
}
}
&:last-of-type {
//土曜日を青に
.picker__day {
&.picker__day--infocus {
&:not(.picker__day--disabled) {
color: #1649ff;
}
}
}
}
}
}
}
}
JavaScript
ポイントはこの2つです。
- 送信ボタンを押すとpickadate.jsが消えてしまう(エラーが出た後にpickadate.jsが使えなくなる)ので、
「送信ボタンを押した時にpickadate.jsを再初期化する」処理を追加。 - pickadate.jsの初期化、オプション設定
「日付、時間のフォーマット」や「ボタンの表記」はここで変更できます。
// 【Snow Monkey Formsの日付選択にpickadate.jsを適用する】
// 参考サイト:
// https://qiita.com/webbingstudio@github/items/e4642cec98e67e5a33e1
// https://qiita.com/Yuta_Fujiwara/items/e80fb931af623bd8e73e
// ●pickadate.jsオプション
// 日程:https://amsul.ca/pickadate.js/date/
// 時間:https://amsul.ca/pickadate.js/time/
jQuery.noConflict();
(function ($) {
// ①送信ボタンを押すとpickadate.jsが消えてしまうので、「送信ボタンを押した時にpickadate.jsを再初期化する」処理を追加。
// MutationObserverを用いてDOM(Document Object Model)の変更を監視する=========
// 関数を設定
function setupMutationObserver() {
// MutationObserverのインスタンス作成
// `MutationObserver`クラスのコントラスタを呼び出し、コールバック関数を引数に取る
const observer = new MutationObserver(function (mutations) {
//コールバック関数を設定。DOMの変更(ミューテーション)を検出すると呼び出される
mutations.forEach(function (mutation) {
if (
// ミューテーションのタイプがattribute(属性)で、かつ変更された属性が`data-invalid`であるかを確認
mutation.type === "attributes" &&
mutation.attributeName === "data-invalid"
) {
//ミューテーションが発生した要素(mutation.target)を取得
const target = mutation.target;
if (target.getAttribute("data-invalid") === "1") {
// data-invalidが1に設定された場合(エラーが出た時)、datepickerを再初期化
reinitializeDatepicker();
}
}
});
});
// inputに設定しているクラスを監視する設定
const config = { attributes: true, attributeFilter: ["data-invalid"] };
// 監視設定を行う関数
const observeElements = (selector) => {
const elements = document.querySelectorAll(selector);
elements.forEach((element) => observer.observe(element, config));
};
// すべての.js-datepicker要素と.js-timepicker要素に対して監視を設定
observeElements(".js-datepicker");
observeElements(".js-timepicker");
}
// ②pickadate.jsの初期化、オプション設定==================
function reinitializeDatepicker() {
//日程表示-------
$(".js-datepicker").pickadate({
// ここにdatepickerの設定を指定
firstDay: 0, //カレンダーを日曜日始まりにする
disable: [3, 4], //火曜日、水曜日を無効(休日)にする
min: 2, //明後日移行(今日移行の場合は、min:true)
format: "yyyy年mm月dd日", //この形式でテキストボックスに表示されます
//下のボタンの表示を変更する
today: "本日",
clear: "キャンセル",
close: "閉じる",
});
//時間表示-------
$(".js-timepicker").pickatime({
// ここにtimepickerの設定を指定
format: "HH:i", //24時間表記
interval: 60, //表示間隔
min: [10, 0], //10時00分から
max: [18, 0], //18時00分まで
});
}
// ページが読み込まれた時に実行
document.addEventListener("DOMContentLoaded", function () {
reinitializeDatepicker();
setupMutationObserver();
});
//フォームの送信が完了すると、「Snow Monkey Forms」で「smf.submit」イベントが発行される。
//このイベントが発行された後に datepicker を再初期化する処理を追加。
document.addEventListener("smf.submit", function (event) {
// ここにdatepickerの再初期化処理を書く
reinitializeDatepicker();
});
})(jQuery);
以下の画像が、出来上がりイメージです。


日付選択カレンダーをカスタムしたい時の参考サイト
公式サイトにカスタム方法が紹介されています。
是非ご参考にしてください!
日付のカスタマイズ
時間のカスタマイズ