Snow Monkey Forms に日付選択カレンダーを実装する方法

Snow Monkey Formsの技術記事
目次

完成イメージ

確認ボタンを押した時に、必須項目にエラーが出ても日付選択カレンダーが表示されるように調整しました。
その解決法も含めてご紹介します。

フォームの設定

Snow Monkey Forms の設定を画像で説明します。

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

日付を選択する部分

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

時間を選択する部分

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

日付選択カレンダーの導入

使用プラグインの選定について

最初に「air-datepicker」での実装を試みました。

↓参考記事(Snow Monkey Formsの実装方法も参考にしております🙇‍♀️)

Qiita
WordPressプラグイン「Snow Monkey Forms」に日付選択を実装する手順 - Qiita 「Snow Monkey Forms」はWordPressにメールフォームを実装するプラグインです。https://ja.wordpress.org/plugins/snow-monkey-for…

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

air-datepickerの日付選択カレンダーのイメージ

引用元:https://air-datepicker.com/examples

クライアントの要望により以下の理由で「pickadate.js」を採用しました。

  • 日時の項目を分けたい
  • 時間をプルダウンで選択できるようにしたい(プルダウン内の時間の間隔はあらかじめ指定する)

pickadate.jsの特徴

  1. 日付と時間の項目を分けて設定できる
  2. 時間をプルダウンで選択可能
    (時間の間隔はJavaScriptで指定できます。)
  3. カスタマイズが容易
    JavaScriptやCSSで簡単にカスタマイズが可能。CSSで曜日ごとの休業日などの色変更が可能。
  4. 日本語対応
    「2024年4月1日 日曜日」のように日本語フォーマットに対応。

注意点として、jQueryが必須です。

ビルドツールを使用する場合

ビルドツールを使用する場合、GitHubでnpmのダウンロード方法が紹介されています。

GitHub

GitHub
GitHub - amsul/pickadate.js: The mobile-friendly, responsive, and lightweight jQuery date & time inp... The mobile-friendly, responsive, and lightweight jQuery date & time input picker. - amsul/pickadate.js

ビルドツールを使用しない場合

ライブラリをダウンロードして使用する方法をご紹介します。

↓参考記事(pickadate.jsの選定の決め手になりました!🙇‍♀️)

Qiita
UIのイケているdatepickerライブラリpickadate.jsが最高だった(demo有) - Qiita datepickerって何がいい??昨年末からWebアプリケーションを作成していて、dateapickerの機能が必要になり、どのライブラリを使おうかと、色々と調べていたところ、pickad...

公式サイトからダウンロード

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

pickadate.js公式サイト

公式サイト

あわせて読みたい
pickadate.js The mobile-friendly, responsive, and lightweight jQuery date & time input picker.

必要なファイルをインストールする

ダウンロードしたZipファイルは、以下の画像のような構造になっています(version 3.6.3)

pickadate.jsのダウンロードファイル群

ここから、システムとして必要なファイルをコピーし、自分のプロジェクトフォルダに入れます。
(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つです。

  1. 送信ボタンを押すとpickadate.jsが消えてしまう(エラーが出た後にpickadate.jsが使えなくなる)ので、
    「送信ボタンを押した時にpickadate.jsを再初期化する」処理を追加。
  2. 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);

以下の画像が、出来上がりイメージです。

日付選択カレンダーをカスタムしたい時の参考サイト

公式サイトにカスタム方法が紹介されています。
是非ご参考にしてください!

日付のカスタマイズ

あわせて読みたい
Date picker – pickadate.js The mobile-friendly, responsive, and lightweight jQuery date & time input picker.

時間のカスタマイズ

あわせて読みたい
Time picker – pickadate.js The mobile-friendly, responsive, and lightweight jQuery date & time input picker.
Snow Monkey Formsの技術記事

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
目次