日時系のtypeのinput要素に対して、現在日時に基づく各typeに合った値を初期値として設定するスクリプトです。
対応するtypeはtime, date, datetime-local, month, week 及び text です。
初期値を設定したい要素のタグにdata-nowDateを追記することで初期値が設定されます。
<input type='date' data-nowDate>
既に有効な値がvalueに設定済みの要素に対してはdata-nowDateを指定しても無視します。
ブラウザが対応していない日時系のtypeの場合は該当のtypeで本来設定されるvalue値を設定、その他の無効なtypeの場合はtextとして扱います。
typeがtextの場合は、data-nowDateに書式テンプレート文字を指定できます。
####テンプレート文字一覧####
%Y% 西暦 4桁
%Y2% 西暦 下2桁
%M% 月 2桁
%Ms% 月 0埋め無し
%D% 日 2桁
%Ds% 日 0埋め無し
%h% 時 2桁
%hs% 時 0埋め無し
%m% 分 2桁
%ms% 分 0埋め無し
%s% 秒 2桁
%ss% 秒 0埋め無し
%MS% ミリ秒 3桁
%MSs% ミリ秒 0埋め無し
<input type='text' data-nowDate='%h%:%m%:%s%'>
###スクリプト###
'use strict';
{
window.addEventListener('DOMContentLoaded', function() {
const d = new Date();
d.setMinutes(d.getMinutes() - d.getTimezoneOffset());
const
isoLocal = d.toISOString(),
pos = {
time : [11, 16],
date : [ 0, 10],
month : [ 0, 7],
'datetime-local': [ 0, 16],
},
elements = document.querySelectorAll('input[data-nowdate]');
for(let i = 0; i < elements.length; i++) {
const e = elements[i];
if(e.value !== '') {
continue;
}
const
t = e.attributes.type !== undefined ?
e.attributes.type.value.toLowerCase() : 'text',
type = e.type === t ?
t : (Object.keys(pos).indexOf(t) >= 0) ? t : 'text';
if(Object.keys(pos).indexOf(type) >= 0) {
const r = pos[type];
e.value = isoLocal.slice(r[0], r[1]);
}
else if(type === 'week') {
const
d_ = new Date(Math.floor((+d + 2592e5) / 6048e5) * 6048e5),
y = d_.getUTCFullYear(),
w = 1 + Math.floor((d_ - new Date(y + '-01-01T00:00:00Z')) / 6048e5);
e.value = y + '-W' + ('0' + w).slice(-2);
}
else if(type === 'text') {
const p = isoLocal.match(/\d+/g);
if(e.dataset.nowdate.trim() === '') {
e.dataset.nowdate = '%Y%-%M%-%D% %h%:%m%:%s%';
}
e.value = e.dataset.nowdate
.replace(/%Y%/g, p[0]) // %Y% 西暦 4桁
.replace(/%Y2%/g, p[0].slice(-2)) // %Y2% 西暦 下2桁
.replace(/%M%/g, p[1]) // %M% 月 2桁
.replace(/%Ms%/g, +p[1]) // %Ms% 月 0埋め無し
.replace(/%D%/g, p[2]) // %D% 日 2桁
.replace(/%Ds%/g, +p[2]) // %Ds% 日 0埋め無し
.replace(/%h%/g, p[3]) // %h% 時 2桁
.replace(/%hs%/g, +p[3]) // %hs% 時 0埋め無し
.replace(/%m%/g, p[4]) // %m% 分 2桁
.replace(/%ms%/g, +p[4]) // %ms% 分 0埋め無し
.replace(/%s%/g, p[5]) // %s% 秒 2桁
.replace(/%ss%/g, +p[5]) // %ss% 秒 0埋め無し
.replace(/%MS%/g, p[6]) // %MS% ミリ秒 3桁
.replace(/%MSs%/g, +p[6]); // %MSs% ミリ秒 0埋め無し
}
}
});
}
###サンプル###
動作デモ
<!DOCTYPE html>
<html lang='ja'>
<head>
<meta name='viewport' content='width=device-width,initial-scale=1'>
<meta charset='utf-8'>
<title>日時系input要素に現在日時をデフォルト設定</title>
<script src='input_date_default_set.js'></script>
</head>
<body>
<!-- data-nowDateを追記で現在日時に基づく各typeに合った値を設定 -->
time<br>
<input type='time' data-nowDate><hr>
date<br>
<input type='date' data-nowDate><hr>
datetime-local<br>
<input type='datetime-local' data-nowDate><hr>
month<br>
<input type='month' data-nowDate><hr>
week<br>
<input type='week' data-nowDate><hr>
text<br>
<!-- type=textの場合に限り、data-nowDateに記入した書式テンプレートを反映 -->
<input type='text' data-nowDate='%Y%-%M%-%D% %h%:%m%:%s%.%MS%'><br>
 書式テンプレート<br> %Y%-%M%-%D% %h%:%m%:%s%.%MS%<hr>
<input type='text' data-nowDate='%Y2%-%Ms%-%Ds% %hs%:%ms%:%ss% %MSs%'><br>
 書式テンプレート<br> %Y2%-%Ms%-%Ds% %hs%:%ms%:%ss% %MSs%<hr>
<!-- 書式テンプレート無指定時は %Y%-%M%-%D% %h%:%m%:%s% として解釈 -->
<input type='text' data-nowDate><br>
 書式テンプレートなし<hr>
</body>
</html>
**type='week'**の要素については、私が確認できる範囲では2021年4月の時点でUIも表示されとくに問題なく使用できそうだったのはWindows/MacOS/Android版のChromeくらいでした。
非対応typeでもtextとして扱われるならまだいいのですが、iOS(14.4.2)/iPadOS(14.4.2)に至っては、typeはweekを保ったまま初期値も設定できるにも関わらず、要素をタップしても専用UIが表示されることもなく内容を変更することができない(通常のソフトウェアキーボードは表示されるが値を変更できない)状態だったので、やむなく使用する際には他のtype以上に注意が必要かな、と感じました。