LoginSignup
1
1

More than 3 years have passed since last update.

datepickerのinputにキーボード入力で、/(スラッシュ)や -(ハイフン)でも入力可能にする(yyyymmddなども対応する)

Last updated at Posted at 2020-05-26

突然クライアントから、「このカレンダーのフォーム手入力できるようにできる?」と聞かれ、
readonly を外せばすむだろうと思って「問題ないですよ〜」と二つ返事したら、
「よかった、じゃあちゃちゃっとこれよろしく!」と言われて以下のリストが出てきた。

以下で入力できるようにお願いします。

  • yyyy/mm/dd
  • yyyy-mm-dd
  • yyyymmdd
  • mm/dd
  • mm-dd
  • mmdd

これ聞き方詐欺だ・・・。
まあいい、やるか。

と思ったら案外といろいろ忘れてしまっていたので、
次にまた聞き方詐欺に引っかかったときのために残しておこう(~o~)

<input type="text" class="datepicker" onblur="datepickerReplace(event)">
function datepickerReplace(e) {
  const _this = e.target                     // ターゲット
  const today = new Date()                   // 今日
  const currentYear = today.getFullYear()    // 今年の西暦
  const splitString = _this.value.split('')  // 入力値を分割

  // 記号の有無を確認 Boolean
  // スラッシュかハイフンがあったらtrueを返す
  const hasSymbol = splitString.some(string => string === '/' || string === '-')

  // / を - に変換した文字列を作成
  // 1文字ずつ評価してスラッシュがきたらハイフンを返すそれ以外、はそのまま返す
  // join() で全てを連結する
  const replaceString = splitString.map(string => string === '/' ? '-' : string).join('')

  if (splitString.length === 10) {
    // yyyy-mm-dd yyyy/mm/dd の場合
    // 連結された値が無効な日付だったら今日の日付を返す、有効な場合は連結された値を返す
    _this.value = new Date(replaceString).toString() === "Invalid Date" ? today : replaceString
  } else if (splitString.length === 8 && !hasSymbol) {
    // yyyymmdd の場合
    // 文字列の最初から4文字を年として、次の2文字を月、最後の2文字を日として定義する
    const year = replaceString.slice(0, 4);
    const month = replaceString.slice(4, 6);
    const day = replaceString.slice(6);
    // 3つをハイフンでつないで連結
    const ymd = `${year}-${month}-${day}`
    _this.value = new Date(ymd).toString() === "Invalid Date" ? today : ymd
  } else if (splitString.length >= 3 && splitString.length <= 5 && hasSymbol) {
    // m-d mm-ddの場合
    const spritMonthDay = replaceString.split('-')
    const monthDayArr = spritMonthDay.map(num => `0${num}`.slice(-2))
    const ymd = `${currentYear}-${monthDayArr.join('-')}`
    _this.value = new Date(ymd).toString() === "Invalid Date" ? today : ymd
  } else if (splitString.length === 4 && !hasSymbol) {
    // mmdd
    const month = replaceString.slice(0, 2);
    const day = replaceString.slice(2);
    const ymd = `${currentYear}-${month}-${day}`
    _this.value = new Date(ymd).toString() === "Invalid Date" ? today : ymd
  } else {
    // その他
    _this.value = today
  }
}
1
1
2

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
1
1