week 型の <input> 要素は、年と、その年の ISO 8601 週番号 (つまり、第1週から第52又は53週) を簡単に入力することができる入力欄を生成します。

コントロールのユーザーインターフェイスは、ブラウザ―によってまちまちです。現時点ではブラウザー間の対応は限定的で、 Chrome/Opera と Microsoft Edge のみが対応しています。対応していないブラウザーでは、このコントロールは単純な <input type="text"> に格下げされます。

<input id="week" type="week">

Chrome/Opera では、 week コントロールは週と年の値を埋めるスロット、もっと視覚的に選択するためのポップアップカレンダーインターフェイス、コントロールの値を消去するための "X" ボタンを提供します。

Edge の week コントロールはもう少し凝っており、年と週を選ぶスライドするリールが開きます。

Value 年と週を表す DOMString、又は空欄。
イベント change 及び input
対応する共通属性 autocomplete, list, readonly, step
IDL 属性 value, valueAsDate, valueAsNumber, list
メソッド select(), stepDown(), stepUp()

入力欄に入力された年と週を表す DOMString です。次のように value 属性の中に値を含めることで、既定値を設定することができます。

<label for="week">どの週に始めたいですか。</label>
<input id="week" type="week" name="week" value="2017-W01">

一点気を付けなければならないことは、実際の value は常に yyyy-Www の書式であり、表示される書式はこれとは異なる可能性があるということです。例えば、上記の値をサーバーに送信すると、ブラウザーは Week 01, 2017 のように表示するかもしれませんが、送信される値は常に week=2017-W01 のようになります。

次のように、 JavaScript で HTMLInputElement.value プロパティを使用して値を取得したり設定したりすることもできます。

var weekControl = document.querySelector('input[type="week"]');
weekControl.value = '2017-W45';

week 入力欄の使用

week 入力欄は一見すると便利に見えます。簡単に週を選択するユーザーインターフェイスを提供し、ユーザーのロケールに関係なく、データ形式を正規化してサーバーに送信するからです。しかし、ブラウザーの対応が限られているため、 <input type="week"> には問題があります。

<input type="week"> の基本的な使い方と少し複雑な使い方を見てみてから、その後でブラウザーの対応の問題を緩和するアドバイスを提供しましょう (ブラウザーの対応の扱いを参照してください) 。

week の基本的な使用

もっとも単純な <input type=week> の使用方法は、次のように基本的な <input><label> 要素の組み合わせです。

<form>
  <label for="week">どの週から始めたいですか。</label>
  <input id="week" type="week" name="week">
</form>

入力欄の寸法の制御

<input type="week">size のような寸法に関する属性には対応していません。寸法を変更する必要がある場合は、 CSS を使用する必要があります。

step 属性の使用

step 属性を使用して、週の番号が増加又は減少するときに飛ばす番号を変更することができるはずですが、対応しているブラウザーでも何も動作していないようです。

検証

既定で、 <input type="week"> は入力された値の検証を行いません。ユーザーインターフェイスの実装は一般的に、妥当な年と週でないものの入力をさせず、これは便利ですが、それでも入力欄を空のままにすることができ、また選択できる週の範囲を制限したくなるかもしれません。

name="Setting_maximum_and_minimum_weeks">週の最大値と最小値の設定

min 及び max 属性を使用して、ユーザーが選択することができる有効な週を制限することができます。以下の例では、最小値を Week 01, 2017 に、最大値を Week 52, 2017 に設定しています。

<form>
  <label for="week">どの週から始めたいですか。</label>
  <input id="week" type="week" name="week"
         min="2017-W01" max="2017-W52">
  <span class="validity"></span>
</form>

上記の例の CSS です。 CSS の :valid 及び :invalid プロパティを使用して、現在の値が有効かどうかに基づいてスタイルを設定しています。アイコンは入力欄そのものではなく、入力欄の隣の <span> に置くようにしないと、 Chrome ではコントロールの内側にコンテンツを生成するので、正しく整形したり表示したりすることができません。

div {
  margin-bottom: 10px;
  position: relative;
}

input[type="number"] {
  width: 100px;
}

input + span {
  padding-right: 30px;
}

input:invalid+span:after {
  position: absolute;
  content: '✖';
  padding-left: 5px;
}

input:valid+span:after {
  position: absolute;
  content: '✓';
  padding-left: 5px;
}

この結果は、対応するブラウザーでは2017年の第1週から第52週の間が有効に見え、選択することができます。

週の値を必須にする

加えて、 required 属性を使用して、週の入力を必須にすることができます。結果として、対応するブラウザーでは週の入力欄が空欄の場合にエラーを表示します。

例を見てみましょう。週の最小値と最大値を設定し、かつフィールドを必須に設定しています。

<form>
  <div>
    <label for="week">どの週から始めたいですか。</label>
    <input id="week" type="week" name="week"
         min="2017-W01" max="2017-W52" required>
    <span class="validity"></span> 
  </div>
  <div>
      <input type="submit" value="Submit form">
  </div>
</form>

フォームに値を設定せずに送信しようとすると、ブラウザーはエラーを表示します。例を実行してみてください。

対応していないブラウザーを使用したときのスクリーンショットです。

重要: HTML のフォーム検証は、入力されたデータが正しい形式であることを保証するスクリプトの代用にはなりません。 HTML を調整して検証をくぐり抜けたり、完全に削除したりすることはとても簡単にできます。 HTML を完全にバイパスし、サーバーに直接データを送信することも可能です。サーバー側のコードが受信したデータの検証に失敗した場合、不適切な形式のデータ (または大きすぎるデータ、間違った種類のデータなど) が送信された場合に災害が発生するおそれがあります。

ブラウザーの対応の扱い

前述のように、現時点で week 入力欄を利用する上で一番の問題はブラウザーの対応です。デスクトップでは Safari と Firefox は対応しておらず、 IE の古いバージョンも対応していません。

Android や iOS のようなモバイルプラットフォームは、このような入力型が実に有効であり、タッチスクリーン環境で実に簡単に値を選択できる専用のユーザーインターフェイスコントロールを提供します。例えば、 Android 版 Chrome の week 選択は、次のようになっています。

対応していないブラウザーでは安全にテキスト入力欄に格下げされますが、これはユーザーインターフェイスの一貫性 (表示されるコントロールが異なること) とデータの扱いの二つの問題を生じます。

二つ目の問題はより深刻です。すでに述べたように、 week 入力欄では、実際の値が常に yyyy-Www の書式で正規化されます。ブラウザーが一般的なテキスト入力欄にフォールバックした場合、ユーザーが正しい書式で入力するよう案内することができません (そして、おそらく認識できません)。人間が週の値を書くには、次のように色々な方法があります。

  • Week 1 2017
  • Jan 2-8 2017
  • 2017-W01
  • etc.

ブラウザーに依存しない方法によってフォームで年と週を扱う最善の方法は、現時点では年と週を別々なコントロール (<select> 要素で入力するものが一般的です。以下の実装を見てください) にするか、 jQuery date picker のような JavaScript ライブラリを使用することです。

この例では、週を選択するユーザーインターフェイスの要素を2組生成します。ネイティブの <input type="week"> 入力欄と、 week 入力欄に対応しない古いブラウザーで年と週を選択するための、2つの <select> 要素です。

HTML は次のようになります。

<form>
  <div class="nativeWeekPicker">
    <label for="week">どの週から始めたいですか。</label>
    <input id="week" type="week" name="week"
           min="2017-W01" max="2018-W52" required>
    <span class="validity"></span>
  </div>
  <p class="fallbackLabel">どの週から始めたいですか。</p>
  <div class="fallbackWeekPicker">
    <div>
      <span>
        <label for="week">Week:</label>
        <select id="fallbackWeek" name="week">
        </select>
      </span>
      <span>
        <label for="year">Year:</label>
        <select id="year" name="year">
          <option value="2017" selected>2017</option>
          <option value="2018">2018</option>
        </select>
      </span>
    </div>
  </div>
</form>

週の値は以下の JavaScript のコードで動的に生成されます。

もう一つの面白い部分は、機能の検出コードです。ブラウザーが <input type="week"> に対応しているかどうかを検出するために、新たな <input> 要素を生成し、その typeweek に設定して、すぐに type に何が設定されたかをチェックします。 datetime-local 型に対応していないブラウザーでは、 week 型が text 型へフォールバックされます。 <input type="week"> に対応していない場合は、ネイティブの日時入力欄を非表示にしてフォールバック用の (<select>) による選択ユーザーインターフェイスを表示します。

// 変数を定義
var nativePicker = document.querySelector('.nativeWeekPicker');
var fallbackPicker = document.querySelector('.fallbackWeekPicker');
var fallbackLabel = document.querySelector('.fallbackLabel');

var yearSelect = document.querySelector('#year');
var weekSelect = document.querySelector('#fallbackWeek');

// 最初はフォールバックを非表示にする
fallbackPicker.style.display = 'none';
fallbackLabel.style.display = 'none';

// 新しい日付入力が文字列入力にフォールバックされるかどうか
var test = document.createElement('input');
test.type = 'week';
// もし文字列入力になるならば、 if() {} ブロックの中のコードを実行する
if(test.type === 'text') {
  // ネイティブの日付選択を隠してフォールバック版を表示
  nativePicker.style.display = 'none';
  fallbackPicker.style.display = 'block';
  fallbackLabel.style.display = 'block';

  // 週を動的に生成する
  populateWeeks();
}

function populateWeeks() {
  // 週の選択肢を52週で生成
  for(var i = 1; i <= 52; i++) {
    var option = document.createElement('option');
    option.textContent = (i < 10) ? ("0" + i) : i;
    weekSelect.appendChild(option);
  }
}

メモ: 53週ある年もあることを忘れないでください(年あたりの週数を参照)。商品のアプリを開発するときはこれを念頭に置いておく必要があります。

仕様書

仕様書 状態 備考
HTML Living Standard
<input type="week"> の定義
現行の標準  

ブラウザーの対応

We're converting our compatibility data into a machine-readable JSON format. This compatibility table still uses the old format, because we haven't yet converted the data it contains. Find out how you can help!

機能 Chrome Edge Firefox (Gecko) Internet Explorer Opera Safari
基本対応 20 12 未サポート[1] 未サポート 10.62 未サポート
機能 Android Chrome for Android Edge Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
基本対応 (有) (有) (有) (有) ? (有) (有)

[1] この機能はまだ実装されていません。 バグ 888320 及び TPE DOM/Date time input types を参照してださい。

関連情報

ドキュメントのタグと貢献者

このページの貢献者: mfuji09
最終更新者: mfuji09,