3
2

More than 3 years have passed since last update.

Javascriptで日付の連動更新をする

Last updated at Posted at 2020-07-10

命題

JavaScriptを使って、二つ(以上)ある<input type="date">の一方が更新されたとき、もう片方を同じ値にしたい。
ブラウザはChrome 83を使用。

想定される使用例

検索期間を2組の<input type="date">で表し、例えば検索終了日を変更した際に、検索開始日より過去の日付だったら開始日を終了日と同じにする。

HTMLサンプル
<div>
  検索期間: <input id="DateSince" name="DateSince" type="date" value="2020-07-10"><input id="DateUntil" name="DateUntil" type="date" value="2020-07-10">←こちらを変更すると左側の日付も変わります。
</div>

具体的には上記のコードで、DateUntilを2020-7-09に変更した場合、DateSinceも2020-7-09に書き換わるようにする。

実際の実装では逆の処理(DateSinceをDateUntilより未来にした場合、DateUntilをDateSinceと同じ値にする)も必要だが、説明簡略化のために省く。

具体的な方法

イベント自体の作成は簡単。

DateUntil「変更」時に発生させるJSイベント
function dateUntilChanged(e) {
  const dateSince = document.getElementById("DateSince");
  const value = e.target.value;
  if (dateSince.value < value) {
    dateSince.value = value;
  }
}

問題はこのイベントをどのタイミングで発火させるかである。

ダメな例: changeイベントを使う

変更されたのなら素直にchangeイベントを使えばいいじゃん、とついつい考えてしまいがちだが、それは残念ながら間違い。

changeイベントを使用したJS
document.getElementById("DateUntil").addEventListener("change", dateUntilChanged);

こうすると(少なくともChromeでは)DateUntilが打鍵されるたびにイベントが発火するので、「2020」とキーボード入力する際に2→0→2→0と入力するためにDateSinceが0002年になってしまう(当然、日付の変更条件は満たされなくなるので、0002年のまま変更されない)。

この動作は正直言って好ましくない。イベントをいちいち発火するコストも問題だ。

よりよい例: blur(フォーカスアウト)イベントを使う

入力されるたびにイベントを発生させるのではなく、Dateの入力が完了した後、Tabキーや<input type="date">の外部をクリックすると起こるようなイベントがあればいい。
そこで登場するのがblurイベントだ。

blurといきなり言われても分かりづらいので(個人的にはブリットポップのバンドを思い出す)説明すると、ある要素からフォーカスが外れた際に(別のところをクリックするなど)発生するイベントのこと。
要はblur(ぼやけるの意)がfocusの対義語だから、フォーカスアウトするイベントをそう呼んでいるらしい。

blurイベントを使用した例
// 前掲例のchangeをblurに変えただけ
document.getElementById("DateUntil").addEventListener("blur", dateUntilChanged);

Chromeでは、デートピッカーを抜け出しただけではblurイベントが発生しないので注意!
(<input type="date">の年の部分が選択されているため)
ほかの箇所をクリックした時点でblurが発火するので、実用上はそこまで問題ではない。
私が使った場面は<form>で検索期間を指定して「検索」ボタン押下というシナリオだったので、この問題は無視できた。

おさらい(CodePen)

See the Pen Javascriptで日付の連動更新をする by Nagayama Toshiaki (@NagayamaToshiaki) on CodePen.

参考文献

holstetoさんの回答(英語)
javascript - HTML5 <input type=“date”> - onChange Event - Stack Overflow

<input type="date">が変更された際に発生するイベントについてまとめられています。
この回答に出会わなければこの記事を書けませんでした。

追記

Firefox 78でも同様の挙動が確認できたので、一部取り消し線を入れました。

3
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2