flatpickrのonChangeで選択した日付を取得する
方法【動くデモ付き】

結論:onChangeに関数を渡すだけ

flatpickrで選択された日付をJS側で受け取るには、初期化オプションに onChange コールバックを渡します。inputchange イベントを別途監視する必要はありません。

<input type="text" id="datepicker" placeholder="日付を選択">
<div id="result"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/flatpickr/4.6.13/flatpickr.min.js"></script>
<script>
  flatpickr("#datepicker", {
    dateFormat: "Y-m-d",
    onChange: function(selectedDates, dateStr, instance) {
      document.getElementById("result").textContent = dateStr;
    }
  });
</script>

実際に動くデモです。日付を選ぶとすぐ下にonChangeが受け取った値が表示されます。

ここに選択結果が表示されます

onChangeが受け取る3つの引数

コールバックには selectedDatesdateStrinstance の3つが渡されます。どれを使うかは用途次第です。

selectedDates(配列)

選択された日付のDateオブジェクトが入った配列。単一選択なら要素数1、範囲選択なら開始日と終了日の2要素、まだ何も選ばれていなければ空配列になる。日付の計算処理をするならこちらを使う。

dateStr(文字列)

dateFormat オプションに従って整形済みの文字列。画面表示やそのまま送信する値として使うなら、こちらのほうが手間がない。

instance(オブジェクト)

flatpickrのインスタンス自体。instance.input で対象のinput要素を参照できるため、同じ関数を複数のinputで使い回すときに区別する用途で使う。

素のinputの change イベントとの一番の違いは発火のタイミングです。change イベントはinput要素からフォーカスが外れて初めて発火しますが、onChange はカレンダー上で日付をクリックした瞬間に発火します。キーボード入力で日付を直接書き換えるケースを除けば、onChange のほうが実際の選択操作に忠実です。

よくあるバリエーション・ハマりどころ

onChangeとonCloseの使い分け

単一選択では気にする場面が少ないですが、範囲選択(mode: "range")では onChangeonClose で確定タイミングが異なります。onChange は開始日をクリックした時点と終了日をクリックした時点の2回発火するのに対し、onClose はカレンダーが閉じたタイミングの1回だけ発火します。

flatpickr("#range-picker", {
  mode: "range",
  dateFormat: "Y-m-d",
  onChange: function(selectedDates, dateStr) {
    // 開始日選択時と終了日選択時の計2回呼ばれる
    console.log("changed:", dateStr);
  },
  onClose: function(selectedDates, dateStr) {
    // カレンダーを閉じたタイミングの1回だけ呼ばれる
    console.log("closed:", dateStr);
  }
});

「範囲が確定してから1回だけAPIを叩きたい」というような処理は、onChange ではなく onClose に書いたほうが二重実行を防げます。範囲選択自体の実装方法は「flatpickrで日付の範囲選択を実装する方法」でまとめています。

取得した値をフォーム送信用に変換する

dateStrdateFormat の書式そのままなので、画面表示用に Y年m月d日 のような日本語フォーマットを使っていると、サーバー側が期待する YYYY-MM-DD と食い違うことがあります。この場合は表示用と送信用でinputを分けるのが簡単です。

<input type="text" id="datepicker-display" placeholder="日付を選択">
<input type="hidden" id="datepicker-value" name="visit_date">

<script>
  flatpickr("#datepicker-display", {
    dateFormat: "Y年m月d日",
    onChange: function(selectedDates, dateStr, instance) {
      if (selectedDates[0]) {
        var iso = instance.formatDate(selectedDates[0], "Y-m-d");
        document.getElementById("datepicker-value").value = iso;
      }
    }
  });
</script>

instance.formatDate() を使うと、表示用とは別の書式で同じ日付を再フォーマットできます。altInput: true を使う手もありますが、hidden inputで送信値を分ける方法のほうが挙動を追いやすく、他のバリデーション処理とも組み合わせやすいです。

選択解除時にselectedDatesが空になる

クリアボタンなどで選択を解除できる設定にしている場合、onChangeselectedDates が空配列の状態でも呼ばれます。selectedDates[0] を無条件に参照するとエラーになるため、上のコード例のように存在チェックを入れておくと安全です。

ここに選択結果が表示されます

まとめ

flatpickrの値取得は onChange オプションに関数を渡すだけで完結し、selectedDatesdateStrinstance の3つの引数から必要な形式を選べば十分です。範囲選択で確定タイミングを1回に絞りたいときは onClose、送信用の値を別書式にしたいときは instance.formatDate() を使うと、余計な変換処理を書かずに済みます。日本語化については「flatpickrを日本語化する方法」も合わせて確認してください。

関連するUI事例

flatpickrを使った日付・時刻選択の実装例です。単一選択・範囲選択・時刻選択のパターンをまとめて確認できます。