😊

jQuery UI Datepickerのカスタマイズ:date2の日付をdate1より前の日付しか選択できないようにする

2024/12/24に公開

フォームで2つの日付選択フィールドを扱う際、しばしば2つの日付間に依存関係を持たせたいケースがあります。例えば、2つ目の日付を1つ目の日付より前の日付しか選択できないようにしたい、といった要件です。

今回は、jQuery UI Datepickerを使って、このような依存関係を実装する方法をご紹介します。

実装したい機能

今回は以下のような機能を実装します:

  • 1つ目の日付フィールド(date1)を選択した後
  • 2つ目の日付フィールド(date2)では、date1より前の日付しか選択できない
  • すでにdate2に日付が入力されている場合、date1がその日付より前に変更されたら、date2をクリアする

実装コード

jQuery(function($) {
  // datepickerの既存のオプションを拡張
  $(".hasDatepicker").datepicker("option", {
    dateFormat: "yy年mm月dd日"
  });

  // 1つ目の日付選択時の処理
  $("#mw-client-terminate_day1").on('change', function() {
    var date1 = $(this).datepicker('getDate');

    if (date1) {
      // 2つ目の日付の選択可能最大値を更新
      $("#mw-client-terminate_day2").datepicker("option", "maxDate", date1);
      
      // 2つ目の日付が1つ目より後の場合はクリア
      var date2 = $("#mw-client-terminate_day2").datepicker('getDate');
      if (date2 && date2 > date1) {
        $("#mw-client-terminate_day2").val('');
      }
    }
  });

  // 2つ目の日付選択前の処理
  $("#mw-client-terminate_day2").datepicker("option", "beforeShow", function() {
    var date1 = $("#mw-client-terminate_day1").datepicker('getDate');
    
    if (date1) {
      return { maxDate: date1 };
    }
  });

  // オートコンプリートを無効化
  $('form .hasDatepicker').attr('autocomplete', 'off');
});

コードの解説

1. 基本設定

$(".hasDatepicker").datepicker("option", {
  dateFormat: "yy年mm月dd日"
});

既存のdatepickerに対して日付フォーマットを設定します。この例では「yyyy年mm月dd日」形式を指定しています。

2. 1つ目の日付選択時の処理

$("#mw-client-terminate_day1").on('change', function() {
  var date1 = $(this).datepicker('getDate');
  // ...
});

1つ目の日付が選択されたときの処理を定義します。getDate()メソッドで選択された日付をJavaScriptのDateオブジェクトとして取得します。

3. 2つ目の日付の制限設定

if (date1) {
  $("#mw-client-terminate_day2").datepicker("option", "maxDate", date1);
  // ...
}

2つ目の日付フィールドのmaxDateオプションを、1つ目で選択された日付に設定します。これにより、その日付より後の日付が選択できなくなります。

4. 既存の日付のクリア処理

var date2 = $("#mw-client-terminate_day2").datepicker('getDate');
if (date2 && date2 > date1) {
  $("#mw-client-terminate_day2").val('');
}

すでに2つ目のフィールドに日付が入力されていて、その日付が新しく選択された1つ目の日付より後の場合、2つ目の日付をクリアします。

5. 2つ目の日付選択前の処理

$("#mw-client-terminate_day2").datepicker("option", "beforeShow", function() {
  var date1 = $("#mw-client-terminate_day1").datepicker('getDate');
  if (date1) {
    return { maxDate: date1 };
  }
});

2つ目の日付選択カレンダーが表示される直前に、選択可能な最大日付を設定します。これにより、カレンダーUI上でも選択可能な日付が視覚的に制限されます。

実装時の注意点

  1. すでにdatepickerが初期化されている場合は、新規に初期化せず、datepicker("option", ...)で設定を追加します。
  2. 日付の比較は必ずDateオブジェクトに変換してから行います。
  3. オートコンプリートは無効化しておくことをお勧めします。

まとめ

jQuery UI Datepickerを使用して、2つの日付選択フィールド間に依存関係を設定する実装を紹介しました。このような実装は、予約システムや各種申込フォームなど、様々な場面で活用できます。

コードの中核となるのは、maxDateオプションの動的な設定と、changeイベントでの既存値のバリデーションです。これらを組み合わせることで、ユーザーフレンドリーな日付選択機能を実現できます。

Discussion