PR

Snow Monkey Formsに日付カレンダー「Flatpickr」を使う 応用編

Web作成

カレンダーのテーマを変える

現在公式で公表しているテーマは7つあります Flatpickr Theme

お好みのテーマをカレンダーに反映させる為に、cssファイルを読み込む必要があります。

このページではfunction.phpで読み込む方法を紹介します

Flatpickrのインストール で記入したcssの部分に追加します

https://npmcdn.com/flatpickr/dist/themes/テーマ.css
function custom_calendar_enqueue_scripts() {
    if ( is_page('picker') ) {
        wp_enqueue_style('flatpickr-style', 'https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css');

        //以下を追加        
        wp_enqueue_style('flatpickr-blue', 'https://npmcdn.com/flatpickr/dist/themes/material_blue.css');

    	  wp_enqueue_script('flatpickr-script', 'https://cdn.jsdelivr.net/npm/flatpickr');
    	  // 日本語ロケールの追加
        wp_enqueue_script('flatpickr-japanese', 'https://cdn.jsdelivr.net/npm/flatpickr/dist/l10n/ja.js');
        
    }
}
add_action('wp_enqueue_scripts', 'custom_calendar_enqueue_scripts');
PHP

「material_blue.css」の部分はお好みのテーマに変更してください
Flatpickrのテーマ

公式で公表しているテーマ一覧

「Dark」:dark.css
「Material Blue」:「material_blue.css」
「Material Green」:「material_green.css」
「Material Red」:「material_red.css」
「Material Orange」:「material_orange.css」
「Airbub」:「airbub.css」
「Confetti」:「confetti.css」

例)wp_enqueue_style('flatpickr-orange', 'https://npmcdn.com/flatpickr/dist/themes/material_orange.css');

などテーマに合わせて「flatpickr-orange」を変更してください。変更しなくても動きますが分かりやすくしたほうがいいでしょう

オリジナルテーマを使う

参考にしたいテーマ(css)を直接開き、新しいテキストなどにコピー&ペーストします
https://npmcdn.com/flatpickr/dist/themes/~~.css」をアドレスバーに直接入力することでcssファイルの中身が表示されます

表示したいテーマ下に「任意の名前.css」で保存。ここでは「original.css」とします

function.phpにてcssを読み込む

wp_enqueue_style('original_css', get_template_directory_uri() . '/original.css');
//wp_enqueue_script('original_css', get_stylesheet_directory_uri() . '/original.css'); //子テーマを使ってる場合はこちらを有効化
PHP

get_template_directory_uri :子テーマがない場合
get_stylesheet_directory_uri:子テーマがあり有効化している場合

どちらかを有効化してください

「wp_enqueue_style」と「wp_enqueue_script」を間違えないように

wp_enqueue_style: cssファイルを読み込む
wp_enqueue_script: jsファイルを読み込む

function custom_calendar_enqueue_scripts() {
    if ( is_page('picker') ) {
        wp_enqueue_style('flatpickr-style', 'https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css');

        //以下を追加        
        wp_enqueue_style('original_css', get_template_directory_uri () . '/original.css');
        //wp_enqueue_style('original_css', get_stylesheet_directory_uri() . '/original.css'); //子テーマはこちらを有効化

    	  wp_enqueue_script('flatpickr-script', 'https://cdn.jsdelivr.net/npm/flatpickr');
    	  // 日本語ロケールの追加
        wp_enqueue_script('flatpickr-japanese', 'https://cdn.jsdelivr.net/npm/flatpickr/dist/l10n/ja.js');
        
    }
}
add_action('wp_enqueue_scripts', 'custom_calendar_enqueue_scripts');
PHP

後は、「original.css」を好みに合わせて編集してください

デモページ カレンダーのテーマを変える

カレンダーの選択モード

Flatpickrには標準で選択モードが装備されています

選択モード

【sinble】 1日だけ選択可能(defualt)
【multiple】 複数の日付を選択可能
【range】 初日から終日まで選択可能

「picker_custom.js」にて「mode:’multiple’」などを追加

flatpickr('#js-datepicker', {
  locale     : 'ja',
  dateFormat : 'Y.m.d(D)', 
  mode: 'multiple' // 複数日の場合 他に「single」「range」
});
JavaScript

「single」だけの場合は、省略可能です
何らかの理由で切り替えたい時に「single」を使う感じです
※デモページでは表示例を確かめてもらうため「single」も使ってます

デモページ カレンダーの選択モード

カレンダーの土日に色を付ける

Flatpickrではデフォルトでは土日に色がついていません
そこで日本のカレンダー風に土日に色を付けます

テーマ下の「style.css」に以下を追加します

/* ===== 日曜日(赤) ===== */
.flatpickr-weekday:nth-child(7n + 1),
.flatpickr-day:not(.flatpickr-disabled):not(.prevMonthDay):not(.nextMonthDay):nth-child(7n + 1)
 {
    color: #f00;
}

/* ===== 土曜日(青) ===== */
.flatpickr-weekday:nth-child(7n),
.flatpickr-day:not(.flatpickr-disabled):not(.prevMonthDay):not(.nextMonthDay):nth-child(7n) {
    color: #00f;
}
CSS

「color:#f00」「color:#00f」の部分はお好みに合わせて編集してください

「今日」の部分も色を変更する場合は

/* ===== 今日 ===== */
.flatpickr-day.today,
.flatpickr-day.today:hover{
    border-color:#0fb6bc;
    color:#25bdcf;
}
CSS

デモページ カレンダーの土日に色を付ける

選択できる日を指定する

予約受付などで、選択できる日を3日後や、1週間後などにしたい場合などの指定もできます

「picker_custom.js」にて「minDate = new Date().fp_incr(-3);」などを追加

flatpickr('#js-datepicker', {
  locale     : 'ja',
  dateFormat : 'Y.m.d(D)', 
  minDate : new Date().fp_incr(-3) //3日後から選択可能
});
JavaScript

minDate : new Date().fp_incr(-3) //3日前から選択可能
minDate : ‘today’ //今日から選択可能
minDate : new Date().fp_incr(4) //4日後から選択可能
minDate : new Date().fp_incr(-30) //30日前から選択可能

〇日後まで選択可能にする

flatpickr('#js-datepicker', {
  locale     : 'ja',
  dateFormat : 'Y.m.d(D)', 
  minDate : 'today',
  maxDate : new Date().fp_incr(30) //30日後まで選択可能
});
JavaScript

上記は「今日から30日後まで」選択可能にした例です

「minDate」「maxDate」の部分はご自身のサイトに合わせて変更してください

デモページ 選択できる日を指定する

祝日と日曜日を選択不可にする

会社などで休みの為、祝日と日曜日を選択不可にするする方法です

Flatapickrでは標準では祝日データはありません。
そこで外部APIを使って祝日データを読み込みます

/********************************************************************
 * 祝日データ
 ********************************************************************/

let holidays = {};

// 祝日データ取得
async function loadHolidays() {
    const year = new Date().getFullYear();

    try {
        const res = await fetch(
            `https://holidays-jp.github.io/api/v1/${year}/date.json`
        );
        holidays = await res.json();
    } catch (e) {
        console.error(e);
    }
}

/********************************************************************
 * 共通処理
 ********************************************************************/

// YYYY-MM-DDへ変換
function formatDate(date) {
    return flatpickr.formatDate(date, "Y-m-d");
}

// 選択不可判定
function isDisabledDate(date) {

    // 日曜日
    if (date.getDay() === 0) {
        return true;
    }

    // 祝日
    return Object.prototype.hasOwnProperty.call(
        holidays,
        formatDate(date)
    );
}

/********************************************************************
 * Flatpickr
 ********************************************************************/

// Flatpickr初期化
function initDatepicker() {

    flatpickr("#js-datepicker", {
        locale: "ja",
        dateFormat: "Y.m.d",

        disable: [ isDisabledDate ]
    });
}

/********************************************************************
 * 初期化
 ********************************************************************/

document.addEventListener("DOMContentLoaded", async () => {

    await loadHolidays();
    initDatepicker();

});
JavaScript

disableの部分が選択不可にするオプションになります

if(date.getDay() === 0)  (0:日曜日、1:月曜日、2:火曜日、3:水曜日、4:木曜日、5:金曜日、6:土曜日)

日曜日以外を選択不可にしたい場合は上の数字を参考にしてください

「return holidays~~」 祝日を選択不可にする。不要なら削除可

祝日も赤色にする

「onDayCreate」を使って祝日のクラスを追加します

/********************************************************************
 * 祝日データ
 ********************************************************************/

let holidays = {};

// 祝日データ取得
async function loadHolidays() {
    const year = new Date().getFullYear();

    try {
        const res = await fetch(
            `https://holidays-jp.github.io/api/v1/${year}/date.json`
        );
        holidays = await res.json();
    } catch (e) {
        console.error(e);
    }
}

/********************************************************************
 * 共通処理
 ********************************************************************/

// YYYY-MM-DDへ変換
function formatDate(date) {
    return flatpickr.formatDate(date, "Y-m-d");;
}

//選択不可判定
function isDisabledDate(date) {

    // 日曜日
    if (date.getDay() === 0) {
        return true;
    }

    // 祝日
    return Object.prototype.hasOwnProperty.call(
        holidays,
        formatDate(date)
    );
}

// 祝日スタイル設定
function decorateHoliday(dayElem) {

    const key = formatDate(dayElem.dateObj);

    if (holidays[key]) {
        dayElem.classList.add("is-holiday");
    }
}

/********************************************************************
 * Flatpickr
 ********************************************************************/

// Flatpickr初期化
function initDatepicker() {

    flatpickr("#js-datepicker", {
        locale: "ja",
        dateFormat: "Y.m.d",

        disable: [ isDisabledDate ],

        onDayCreate(_, __, ___, dayElem) {
            decorateHoliday(dayElem);
        }
    });
}

/********************************************************************
 * 初期化
 ********************************************************************/

document.addEventListener("DOMContentLoaded", async () => {

    await loadHolidays();
    initDatepicker();

});
JavaScript

style.cssに以下を追加する

.is-holiday {
    color: #f00 !important;
}
CSS

「is-holiday」の部分は任意のクラス名に変更可能です。 ※jsとcssのクラス名は必ず合わせてください

選択不可の日を薄色にする

/* 日曜日を薄色にする */
.flatpickr-day.flatpickr-disabled:nth-child(7n + 1) {
    color:#f00;
    opacity:0.4;
}

/* 祝日を薄色にする */
.is-holiday {
    color: #f00;
    opacity:0.4;
}
CSS

上記は例です。「opacity」を使わず「color」で薄色を選択してもいいです

デモページ 祝日と日曜日を選択不可にする

リセットボタンを追加する

一度選択した日付や時間をクリアするためのボタンを追加します

「onReady」を使ってリセットボタンを追加します

flatpickr("#js-datepicker", {
    locale: "ja",
    dateFormat: "Y.m.d(D)",

    onReady(selectedDates, dateStr, instance) {

        if (instance.calendarContainer.querySelector(".flatpickr-footer")) {
            return;
        }

        const footer = document.createElement("div");
        footer.className = "flatpickr-footer";

        const resetBtn = document.createElement("button");
        resetBtn.type = "button";
        resetBtn.textContent = "リセット";

        resetBtn.addEventListener("click", () => {
            instance.clear();
            instance.close();
        });

        footer.appendChild(resetBtn);
        instance.calendarContainer.appendChild(footer);
    }
});
JavaScript

カレンダーの下部に独立したフッターとしてリセットボタンを配置できます

style.cssに以下を追加

.flatpickr-footer {
    border-top: 1px solid #ddd;
    padding: 8px;
}

.flatpickr-footer button {
    width: 100%;
    padding: 8px;
}
CSS

カレンダー+時間の場合

時間オプションを追加し、「dateFormat」を書き換えます

flatpickr("#js-datepicker", {
    locale: "ja",
    enableTime:true,     //カレンダー内に時間を有効化
    time_24hr:true,      //24時間表示
    minuteIncrement:10, // 10分刻みの場合。15分刻みの場合は15
    dateFormat: "Y.m.d(D)H:i",

    onReady(selectedDates, dateStr, instance) {

        if (instance.calendarContainer.querySelector(".flatpickr-footer")) {
            return;
        }

        const footer = document.createElement("div");
        footer.className = "flatpickr-footer";

        const resetBtn = document.createElement("button");
        resetBtn.type = "button";
        resetBtn.textContent = "リセット";

        resetBtn.addEventListener("click", () => {
            instance.clear();
            instance.close();
        });

        footer.appendChild(resetBtn);
        instance.calendarContainer.appendChild(footer);
    }
});
JavaScript

カレンダー+時間(別)の場合

上記のカレンダー+時間一体とは違って、時間を別にした場合です

/* 日付用 */
flatpickr("#js-datepicker", {
    locale: "ja",
    dateFormat: "Y.m.d",

    onReady(selectedDates, dateStr, instance) {
        addResetButton(instance, "日付リセット");
    }
});

/* 時間用 */
flatpickr("#js-timepicker", {
    locale: "ja",
    enableTime: true,
    noCalendar: true,
    dateFormat: "H:i",

    onReady(selectedDates, dateStr, instance) {
        addResetButton(instance, "時間リセット");
    }
});

/* 共通関数 */
function addResetButton(instance, text = "リセット") {

    // 二重追加防止
    if (instance.calendarContainer.querySelector(".flatpickr-reset")) {
        return;
    }

    const footer = document.createElement("div");
    footer.className = "flatpickr-footer";

    const button = document.createElement("button");
    button.type = "button";
    button.className = "flatpickr-reset";
    button.textContent = text;

    button.addEventListener("click", () => {
        instance.clear();
        instance.close();
    });

    footer.appendChild(button);
    instance.calendarContainer.appendChild(footer);
}
JavaScript

style.cssに以下を追加、若しくは書き換えます

.flatpickr-footer{
    border-top:1px solid #ddd;
    padding:8px;
}

.flatpickr-reset{
    width:100%;
    padding:8px;
    border:1px solid #ccc;
    background:#f7f7f7;
    cursor:pointer;
    border-radius:4px;
}

.flatpickr-reset:hover{
    background:#eee;
}
CSS

デモページ リセットボタンを追加する

まとめた例

上記で紹介した【選択できる日を指定する】【祝日と日曜日を選択不可にする】【リセットボタンを追加する】をまとめた例です

JavaScript
/********************************************************************
 * 祝日データ
 ********************************************************************/

let holidays = {};

// 祝日データ取得
async function loadHolidays() {
    const year = new Date().getFullYear();

    try {
        const res = await fetch(
            `https://holidays-jp.github.io/api/v1/${year}/date.json`
        );
        holidays = await res.json();
    } catch (e) {
        console.error(e);
    }
}

/********************************************************************
 * 共通処理
 ********************************************************************/

// YYYY-MM-DDへ変換
function formatDate(date) {
    return flatpickr.formatDate(date, "Y-m-d");
}

//選択不可判定
function isDisabledDate(date) {

    // 日曜日
    if (date.getDay() === 0) {
        return true;
    }

    // 祝日
    return Object.prototype.hasOwnProperty.call(
        holidays,
        formatDate(date)
    );
}

// 祝日スタイル設定
function decorateHoliday(dayElem) {

    const key = formatDate(dayElem.dateObj);

    if (holidays[key]) {
        dayElem.classList.add("is-holiday");
    }
}

// リセットボタン
function addResetButton(instance, text = "リセット") {

    // 二重追加防止
    if (instance.calendarContainer.querySelector(".flatpickr-reset")) {
        return;
    }

    const footer = document.createElement("div");
    footer.className = "flatpickr-footer";

    const button = document.createElement("button");
    button.type = "button";
    button.className = "flatpickr-reset";
    button.textContent = text;

    button.addEventListener("click", () => {
        instance.clear();
        instance.close();
    });

    footer.appendChild(button);
    instance.calendarContainer.appendChild(footer);
}
/********************************************************************
 * Flatpickr
 ********************************************************************/

// Flatpickr初期化
function initDatepicker() {
    // 日付用
    flatpickr("#js-datepicker", {
        locale: "ja",
        dateFormat: "Y.m.d",
        minDate : new Date().fp_incr(-3), //3日前から選択可能
        maxDate : new Date().fp_incr(30), //30日後まで選択可能

        disable: [ isDisabledDate ], //選択不可

        onDayCreate(_, __, ___, dayElem) {
            decorateHoliday(dayElem); //祝日用にクラスを追加
        },

        onReady(selectedDates, dateStr, instance) {
            addResetButton(instance, "日付リセット"); //リセットボタン追加
        }
    });


   // 時間用
    flatpickr("#js-timepicker", {
        locale: "ja",
        enableTime: true,
        noCalendar: true,
        dateFormat: "H:i",
        minuteIncrement: 15,

        onReady(selectedDates, dateStr, instance) {
            addResetButton(instance, "時間リセット"); //リセットボタン追加
        }
    });
}

/******************************************************************************
 * 初期化
 ******************************************************************************/

document.addEventListener("DOMContentLoaded", async () => {

    await loadHolidays();
    initDatepicker();

});
JavaScript
CSS
/* ===== 日曜日(赤) ===== */
.flatpickr-weekday:nth-child(7n + 1),
.flatpickr-day:not(.flatpickr-disabled):not(.prevMonthDay):not(.nextMonthDay):nth-child(7n + 1)
 {
    color: #f00;
}

/* ===== 土曜日(青) ===== */
.flatpickr-weekday:nth-child(7n),
.flatpickr-day:not(.flatpickr-disabled):not(.prevMonthDay):not(.nextMonthDay):nth-child(7n) {
    color: #00f;
}

/* ===== 今日 ===== */
.flatpickr-day.today,
.flatpickr-day.today:hover{
    border-color:#0fb6bc;
    color:#25bdcf;
}

/* ===== 祝日 ===== */
.is-holiday {
    color: #f00 !important;
    opacity:0.4; /* 祝日を薄色にする場合 */
}

/* ==== 日曜日を薄色にする ==== */
.flatpickr-day.flatpickr-disabled:nth-child(7n + 1) {
    color:#f00;
    opacity:0.4;
}


/* ==== リセットボタンを追加 ==== */
.flatpickr-footer {
    border-top: 1px solid #ddd;
    padding: 8px;
}

/* ==== リセットボタンの装飾 ==== */
.flatpickr-reset{
    width:100%;
    padding:8px;
    border:1px solid #ccc;
    background:#f7f7f7;
    cursor:pointer;
    border-radius:4px;
}

.flatpickr-reset:hover{
    background:#eee;
}
CSS

日曜日と祝日の 【 opacity:0.4; 】 の部分は選択不可にした時に、視覚的に分かりやすく薄色にする場合です
不要なら削除してもいいです

デモページ まとめた例

コメント

タイトルとURLをコピーしました