突然クライアントから、**「このカレンダーのフォーム手入力できるようにできる?」と聞かれ、
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
}
}