DatePicker 2 — Flatpickr ライブラリ版

フォーム 初級

このコンポーネントについて

人気ライブラリ Flatpickr を使った日付選択コンポーネントです。 カレンダーヘッダーの月部分がドロップダウン選択になっているため、1〜12月を一覧からすぐ選べます。 年は数字部分をクリックすると直接入力できるので、数年先・数年前へのジャンプもスムーズです。

バニラJS版と比べてコードが大幅に短くなり、CDNを1本追加するだけで動く手軽さが特徴です。 単一日付の選択(Pattern 1)と、1つの入力欄で開始日〜終了日を連続選択できる期間選択(Pattern 2)の2パターンを収録しています。 予約フォームの日程指定・ダッシュボードの期間絞り込みなど、日付入力が必要なあらゆる場面に応用できます。

📎 外部ライブラリを使わず、バニラJSだけでゼロから作った版は DatePicker 1 — 日付・期間選択 をご覧ください。 コードの仕組みを学びたい方・ライブラリ導入が難しい環境の方におすすめです。
  • 月のドロップダウン選択 — ヘッダーの月名がドロップダウンになり、1〜12月をワンクリックで選択できる(monthSelectorType: "dropdown" オプション)
  • 年のテキスト直接入力 — 年の数字部分をクリックすると入力フィールドに変わり、任意の年を直接入力できる
  • 日本語ロケール — 曜日・月名が日本語表示になり、週の開始が日曜日になる
  • 単一日付選択(Pattern 1) — クリックで1日を選択し、YYYY/MM/DD 形式で入力欄に反映
  • 期間選択(Pattern 2) — 開始日と終了日をクリックするだけで YYYY/MM/DD 〜 YYYY/MM/DD 形式で表示。mode: "range" 一行で実現
  • クリアボタン付き — ×ボタンで選択状態をワンクリックでリセット

実装のポイント・注意点

Flatpickr の monthSelectorType: "dropdown" を指定すると、月が <select> 要素になります。 デフォルト("static")では矢印ボタンのみで月を1か月ずつしか移動できないため、遠い月への移動が大変です。 このオプションを付けるだけで UX が大きく改善します。

日本語ロケールは Flatpickr 本体 JS とは別にロケールファイル(l10n/ja.min.js)を追加で読み込む必要があります。 読み込み順が重要で、必ず本体 JS より後に読み込んでください。 読み込み後は locale: "ja" を設定するだけで、曜日・月名の日本語化と週始まりを日曜にする設定が一括で適用されます。

期間選択mode: "range" を追加するだけで動作します。 1つ目のクリックで開始日、2つ目のクリックで終了日が確定し、入力欄には 2026/05/01 〜 2026/05/20 のように自動フォーマットされます。 区切り文字は rangeSeparator オプションで変更できます(デフォルトは " to "、今回は " 〜 " に設定)。

allowInput: false にすると入力欄がリードオンリーになり、テキスト直接入力によるバリデーション処理を省略できます。 テキスト入力も許可したい場合は allowInput: true に変更し、onClose コールバックでバリデーション処理を追加してください。

デモ

Pattern 1 — 単一日付選択

Pattern 2 — 期間選択

Powered by Flatpickr

サンプルソース

3つのファイルを同じフォルダに保存し、index.html をブラウザで開くとすぐに動作確認できます。
ファイル名:index.html / style.css / script.js — 保存時の文字コードは UTF-8 を指定してください(Shift-JISだと日本語が文字化けします)。
Flatpickr の CSS・JS はネット接続時に CDN から自動取得されます。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>DatePicker(Flatpickr)サンプル</title>
  <!-- Flatpickr CSS(CDN) -->
  <link rel="stylesheet"
    href="https://cdnjs.cloudflare.com/ajax/libs/flatpickr/4.6.13/flatpickr.min.css">
  <link rel="stylesheet" href="./style.css">
</head>
<body>

<!-- Pattern 1: 単一日付選択 -->
<div class="dp-pattern">
  <p class="dp-pattern-label">Pattern 1 — 単一日付選択</p>
  <div class="dp-input-row">
    <input type="text" id="dp1-input" class="dp-input"
           placeholder="YYYY/MM/DD" readonly autocomplete="off">
    <button type="button" class="dp-icon-btn" id="dp1-toggle" aria-label="カレンダーを開く">
      <svg width="15" height="15" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true">
        <path d="M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5zM1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4H1z"/>
      </svg>
    </button>
    <button type="button" class="dp-clear-btn" id="dp1-clear" aria-label="クリア">×</button>
  </div>
  <button type="button" class="dp-confirm-btn" id="dp1-confirm">決定</button>
  <p class="dp-result" id="dp1-result"></p>
</div>

<!-- Pattern 2: 期間選択 -->
<div class="dp-pattern">
  <p class="dp-pattern-label">Pattern 2 — 期間選択</p>
  <div class="dp-input-row">
    <input type="text" id="dp2-input" class="dp-input dp-input--wide"
           placeholder="YYYY/MM/DD 〜 YYYY/MM/DD" readonly autocomplete="off">
    <button type="button" class="dp-icon-btn" id="dp2-toggle" aria-label="カレンダーを開く">
      <svg width="15" height="15" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true">
        <path d="M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5zM1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4H1z"/>
      </svg>
    </button>
    <button type="button" class="dp-clear-btn" id="dp2-clear" aria-label="クリア">×</button>
  </div>
  <button type="button" class="dp-confirm-btn" id="dp2-confirm">決定</button>
  <p class="dp-result" id="dp2-result"></p>
</div>

<!-- Flatpickr JS(本体 → 日本語ロケールの順で読み込む) -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/flatpickr/4.6.13/flatpickr.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/flatpickr/4.6.13/l10n/ja.min.js"></script>
<script src="./script.js"></script>
</body>
</html>
/* === DatePicker(Flatpickr)パターン集 ===
   --dp-accent の値を変えるだけで配色を一括変更できます */
:root {
  --dp-accent:  #2B7FE8; /* メインカラー(選択状態・ボタン等) */
  --dp-danger:  #E53E3E; /* エラー色 */
  --dp-text:    #1A2332; /* メインテキスト色 */
  --dp-border:  #D0D7E0; /* ボーダー色 */
  --dp-bg:      #F4F6F9; /* カード背景色 */
}

*, *::before, *::after { box-sizing: border-box; }
body {
  font-family: sans-serif;
  padding: 24px;
  max-width: 680px;
  margin: 0 auto;
  background: #fff;
  color: var(--dp-text);
}

/* パターンカード */
.dp-pattern {
  margin-bottom: 20px;
  padding: 20px;
  background: var(--dp-bg);
  border-radius: 8px;
}
.dp-pattern:last-child { margin-bottom: 0; }
.dp-pattern-label {
  margin: 0 0 14px;
  font-size: 11px;
  font-weight: 700;
  color: var(--dp-accent);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* 入力行 */
.dp-input-row { display: flex; align-items: center; }

.dp-input {
  width: 140px;
  padding: 7px 10px;
  font-size: 14px;
  border: 1px solid var(--dp-border);
  border-radius: 4px 0 0 4px;
  outline: none;
  color: var(--dp-text);
  background: #fff;
  cursor: pointer;
  font-family: sans-serif;
}
/* 期間選択用に幅を広げる */
.dp-input--wide { width: 220px; }

.dp-icon-btn {
  display: flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; padding: 0;
  border: 1px solid var(--dp-border); border-left: none; border-radius: 0;
  background: #fff; color: #5A6A7A; cursor: pointer;
  transition: background 0.15s; flex-shrink: 0;
}
.dp-icon-btn:hover { background: var(--dp-bg); }

/* ×クリアボタン */
.dp-clear-btn {
  display: flex; align-items: center; justify-content: center;
  width: 28px; height: 34px; padding: 0;
  border: 1px solid var(--dp-border); border-left: none;
  border-radius: 0 4px 4px 0;
  background: #fff; color: #9AA5B4; cursor: pointer;
  font-size: 14px; line-height: 1; transition: color 0.15s; flex-shrink: 0;
}
.dp-clear-btn:hover { color: #5A6A7A; }

/* 決定ボタン */
.dp-confirm-btn {
  display: inline-block; margin-top: 14px; padding: 8px 24px;
  background: var(--dp-accent); color: #fff; border: none;
  border-radius: 6px; font-size: 14px; font-weight: 600;
  cursor: pointer; font-family: sans-serif; transition: opacity 0.15s;
}
.dp-confirm-btn:hover { opacity: 0.85; }

/* 結果表示 */
.dp-result { margin: 8px 0 0; font-size: 14px; min-height: 20px; }
.dp-result.has-value {
  padding: 10px 14px; background: #F0F7FF;
  border: 1px solid var(--dp-accent); border-radius: 6px;
  color: #1A5EA8; font-weight: 600;
}
.dp-result.is-error { color: var(--dp-danger); }

@media (max-width: 540px) {
  body { padding: 16px; }
  .dp-input { width: 110px; }
  .dp-input--wide { width: 180px; }
}
// Flatpickr 共通設定
var baseConfig = {
  locale: 'ja',                      // 日本語ロケール(l10n/ja.min.js 読み込み後に有効)
  dateFormat: 'Y/m/d',               // 表示フォーマット: YYYY/MM/DD
  monthSelectorType: 'dropdown',     // 月をドロップダウン選択に変更
  allowInput: false                  // テキスト直接入力を無効(カレンダーのみ)
};


// ===== Pattern 1: 単一日付選択 =====
var fp1 = flatpickr('#dp1-input', baseConfig);

// アイコンボタンでカレンダーを開く
document.getElementById('dp1-toggle').addEventListener('click', function() {
  fp1.open();
});

// ×ボタンで選択をリセット
document.getElementById('dp1-clear').addEventListener('click', function() {
  fp1.clear();
  clearResult('dp1-result');
});

// 決定ボタンで結果を表示
document.getElementById('dp1-confirm').addEventListener('click', function() {
  var result = document.getElementById('dp1-result');
  if (fp1.selectedDates.length === 0) {
    showError(result, '※ 日付を選択してください');
    return;
  }
  showValue(result, '選択日: ' + toJP(fp1.selectedDates[0]));
});


// ===== Pattern 2: 期間選択 =====
// baseConfig を Object.assign で拡張して期間選択モードに
var fp2 = flatpickr('#dp2-input', Object.assign({}, baseConfig, {
  mode: 'range',          // 期間選択モード
  rangeSeparator: ' 〜 '  // 開始日・終了日の区切り文字(デフォルトは " to ")
}));

// アイコンボタンでカレンダーを開く
document.getElementById('dp2-toggle').addEventListener('click', function() {
  fp2.open();
});

// ×ボタンで選択をリセット
document.getElementById('dp2-clear').addEventListener('click', function() {
  fp2.clear();
  clearResult('dp2-result');
});

// 決定ボタンで結果を表示
document.getElementById('dp2-confirm').addEventListener('click', function() {
  var result = document.getElementById('dp2-result');
  var dates = fp2.selectedDates;
  if (dates.length < 2) {
    showError(result, '※ 開始日と終了日の両方を選択してください');
    return;
  }
  showValue(result, '期間: ' + toJP(dates[0]) + ' 〜 ' + toJP(dates[1]));
});


// ===== ユーティリティ =====

// Date を「YYYY年M月D日」形式に変換
function toJP(d) {
  return d.getFullYear() + '年' + (d.getMonth() + 1) + '月' + d.getDate() + '日';
}

function showValue(el, text) {
  el.textContent = text;
  el.className = 'dp-result has-value';
}

function showError(el, text) {
  el.textContent = text;
  el.className = 'dp-result is-error';
}

function clearResult(id) {
  var el = document.getElementById(id);
  el.textContent = '';
  el.className = 'dp-result';
}

// リセット(デモリセットボタン用)
function resetDemo() {
  fp1.clear();
  fp2.clear();
  clearResult('dp1-result');
  clearResult('dp2-result');
}

AI用プロンプト

各パターンのプロンプトをコピーしてAIに渡すと、同様のコンポーネントを生成できます。

ChatGPTやClaudeにこのプロンプトを渡すと、同様のコンポーネントをゼロから生成・カスタマイズできます。ライブラリのバージョン変更や要件の追記をして使うのがおすすめです。

※ このプロンプトを使ってもデモとまったく同じ動作にならない場合があります。AIの解釈や生成タイミングによって差が出ることをご了承ください。

💡 jQuery・Vue・React など特定のライブラリで実装したい場合は、プロンプトの末尾に「〇〇を使って実装してください」と追記してください。

Pattern 1 — 単一日付選択

# DatePicker(Flatpickr・単一日付選択)作成依頼

## 概要
Flatpickr ライブラリを使って、月のドロップダウン選択・年のテキスト直接入力が可能な日付選択コンポーネントを実装してください。

## 要件
- テキスト入力欄にカレンダーアイコンボタン(SVG)を添えた見た目にする
- 入力欄クリック / アイコンボタンクリックで Flatpickr カレンダーを表示する
- カレンダーヘッダーの月部分をドロップダウン選択にする(monthSelectorType: "dropdown")
- 日本語ロケール(曜日・月名が日本語、週始まりが日曜)を適用する
- 日付フォーマットは YYYY/MM/DD にする(dateFormat: "Y/m/d")
- ×クリアボタンで選択状態をリセットできるようにする
- 「決定」ボタン押下で選択日を「選択日: YYYY年M月D日」形式で表示する
- 未選択で決定ボタンを押した場合はエラーメッセージを表示する

## 技術仕様
- HTML / CSS / JavaScript で実装
- 外部ライブラリ:Flatpickr 4.6.13(CDN)+ 日本語ロケール(l10n/ja.min.js)
- レスポンシブ対応:必要

## 動作詳細
- Flatpickr オプション: locale: "ja" / dateFormat: "Y/m/d" / monthSelectorType: "dropdown" / allowInput: false
- Flatpickr CSS: https://cdnjs.cloudflare.com/ajax/libs/flatpickr/4.6.13/flatpickr.min.css
- Flatpickr JS: https://cdnjs.cloudflare.com/ajax/libs/flatpickr/4.6.13/flatpickr.min.js
- 日本語ロケール(本体より後に読み込む): https://cdnjs.cloudflare.com/ajax/libs/flatpickr/4.6.13/l10n/ja.min.js

## 出力形式
HTML・CSS・JavaScriptを分けて出力してください。
各ファイルは単独でコピー&ペーストして使えるよう記述してください。

Pattern 2 — 期間選択

# DatePicker(Flatpickr・期間選択)作成依頼

## 概要
Flatpickr ライブラリを使って、1つの入力欄で開始日〜終了日を選択できる期間選択コンポーネントを実装してください。

## 要件
- テキスト入力欄にカレンダーアイコンボタン(SVG)を添えた見た目にする
- 入力欄クリック / アイコンボタンクリックで Flatpickr カレンダーを表示する
- カレンダーヘッダーの月部分をドロップダウン選択にする(monthSelectorType: "dropdown")
- 日本語ロケール(曜日・月名が日本語、週始まりが日曜)を適用する
- 日付フォーマットは YYYY/MM/DD にし、期間の区切り文字は「 〜 」にする(rangeSeparator: " 〜 ")
- 1クリック目で開始日、2クリック目で終了日を選択。ホバー中は選択予定期間をハイライト表示する
- ×クリアボタンで選択状態をリセットできるようにする
- 「決定」ボタン押下で選択期間を「期間: YYYY年M月D日 〜 YYYY年M月D日」形式で表示する
- 開始日・終了日の両方が選択されていない場合はエラーメッセージを表示する

## 技術仕様
- HTML / CSS / JavaScript で実装
- 外部ライブラリ:Flatpickr 4.6.13(CDN)+ 日本語ロケール(l10n/ja.min.js)
- レスポンシブ対応:必要

## 動作詳細
- Flatpickr オプション: locale: "ja" / dateFormat: "Y/m/d" / mode: "range" / rangeSeparator: " 〜 " / monthSelectorType: "dropdown" / allowInput: false
- Flatpickr CSS・JS・日本語ロケールの CDN URL は単一日付選択版と同じ

## 出力形式
HTML・CSS・JavaScriptを分けて出力してください。
各ファイルは単独でコピー&ペーストして使えるよう記述してください。