aboutsummaryrefslogtreecommitdiff
path: root/files/ja/web/html/element/input/week/index.md
blob: 6df29ade0c26c1230e926442b253596778c2978e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
---
title: <input type="week">
slug: Web/HTML/Element/input/week
tags:
  - 要素
  - フォーム
  - HTML
  - HTML Input Types
  - HTML フォーム
  - HTML input
  - Input
  - 入力要素
  - 入力型
  - 入力型s
  - リファレンス
  - Week
  - Weeks
translation_of: Web/HTML/Element/input/week
---
{{HTMLRef("Input_types")}}

<span class="seoSummary">{{HTMLElement("input")}} 要素の <strong>`week`</strong> 型は、年と、その年の [ISO 8601 週番号](https://en.wikipedia.org/wiki/ISO_8601#Week_dates) (つまり、第1週から第[52または53](https://en.wikipedia.org/wiki/ISO_8601#Week_dates)週) を簡単に入力することができる入力欄を生成します。</span>

{{EmbedInteractiveExample("pages/tabbed/input-week.html", "tabbed-shorter")}}

<div class="hidden">このデモのソースファイルは GitHub リポジトリに格納されています。デモプロジェクトに協力したい場合は、 [https://github.com/mdn/interactive-examples](https://github.com/mdn/interactive-examples) をクローンしてプルリクエストを送信してください。</div>

コントロールのユーザーインターフェイスは、ブラウザーによって様々です。現時点ではブラウザー間の対応は限定的で、 Chrome/Opera と Microsoft Edge のみが対応しています。対応していないブラウザーでは、このコントロールは単純な `[&lt;input type="text"&gt;](/ja/docs/Web/HTML/Element/input/text)` に格下げされます。

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

<img alt="" src="https://mdn.mozillademos.org/files/15409/week-control-chrome.png" style="display: block; height: 235px; margin: 0px auto; width: 320px;">

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

<img alt="" src="https://mdn.mozillademos.org/files/15411/week-control-edge.png" style="display: block; height: 391px; margin: 0px auto; width: 227px;">

<table class="properties">
 <tbody>
  <tr>
   <td><strong>{{anch("値")}}</strong></td>
   <td>年と週を表す {{domxref("DOMString")}}、または空欄</td>
  </tr>
  <tr>
   <td><strong>イベント</strong></td>
   <td>{{domxref("HTMLElement/change_event", "change")}} および {{domxref("HTMLElement/input_event", "input")}}</td>
  </tr>
  <tr>
   <td><strong>対応している共通属性</strong></td>
   <td>{{htmlattrxref("autocomplete", "input")}}, {{htmlattrxref("list", "input")}}, {{htmlattrxref("readonly", "input")}}, {{htmlattrxref("step", "input")}}</td>
  </tr>
  <tr>
   <td><strong>IDL 属性</strong></td>
   <td>`list`, `value`, `valueAsDate`, `valueAsNumber`</td>
  </tr>
  <tr>
   <td><strong>メソッド</strong></td>
   <td>{{domxref("HTMLInputElement.select", "select()")}}, {{domxref("HTMLInputElement.stepDown", "stepDown()")}}, {{domxref("HTMLInputElement.stepUp", "stepUp()")}}</td>
  </tr>
 </tbody>
</table>

## 値

{{domxref("DOMString")}} で、入力欄に入力された年と週を表します。この入力型で使われる日時値の形式は、 [HTML で使われる日付や時刻の形式](/ja/docs/Web/HTML/Date_and_time_formats)の[HTML で使われる日付や時刻の形式](/ja/docs/Web/HTML/Date_and_time_formats#Format_of_a_valid_week_string)で説明しています。

次のように {{htmlattrxref("value", "input")}} 属性に値を入れることで、既定値を設定することができます。

<pre class="brush: html notranslate">&lt;label for="week"&gt;どの週に始めたいですか。&lt;/label&gt;
&lt;input id="week" type="week" name="week" value="2017-W01"&gt;</pre>

{{EmbedLiveSample('Value', 600, 60)}}

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

次のように、 JavaScript から入力要素の {{domxref("HTMLInputElement.value", "value")}} プロパティを使用して、値を取得したり設定したりすることもできます。

<pre class="brush: js notranslate">var weekControl = document.querySelector('input[type="week"]');
weekControl.value = '2017-W45';</pre>

<h2 id="Additional_attributes" name="Additional_attributes">追加の属性</h2>

すべての {{HTMLElement("input")}} 型で共通する属性に加え、 `week` 型の入力欄は次の属性にも対応しています。

<table class="standard-table">
 <thead>
  <tr>
   <th scope="col">属性</th>
   <th scope="col">説明</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>`{{anch("max")}}`</td>
   <td>妥当な入力として受け付ける最も遅い年と週</td>
  </tr>
  <tr>
   <td>`{{anch("min")}}`</td>
   <td>妥当な入力として受け付ける最も早い年と週</td>
  </tr>
  <tr>
   <td>`{{anch("readonly")}}`</td>
   <td>論理属性で、存在する場合、入力欄の内容はユーザーが編集できないことを示す</td>
  </tr>
  <tr>
   <td>`{{anch("step")}}`</td>
   <td>ユーザーインターフェイスや制約検証に使用する刻み値 (許される値の間隔)</td>
  </tr>
 </tbody>
</table>

<h3 id="htmlattrdefmax">{{htmlattrdef("max")}}</h3>

受け付ける (時間的に) 最も遅い年と週番号で、上記の{{anch("値")}}の節で説明した文字列書式です。要素に入力された {{htmlattrxref("value", "input")}} がこれを超えた場合、要素は[制約検証](/ja/docs/Web/Guide/HTML/HTML5/Constraint_validation)に失敗します。 `max` 属性の値が妥当な週の文字列ではない場合、要素は最大値を持ちません。

この値は `min` 属性で指定されたものより後か、同じ年と週を指定する必要があります。

<h3 id="htmlattrdefmin">{{htmlattrdef("min")}}</h3>

受け付ける最も早い年と週です。要素の {{htmlattrxref("value", "input")}} がこれより小さいと、要素は[制約検証](/ja/docs/Web/Guide/HTML/HTML5/Constraint_validation)に失敗します。属性の値が妥当な週の文字列ではない場合、要素は最小値を持ちません。

この値は `max` 属性で指定されたものより前か、同じ年と週を指定する必要があります。

{{page("/ja/docs/Web/HTML/Element/input/text", "readonly", 0, 1, 2)}}

<h3 id="htmlattrdefstep">{{htmlattrdef("step")}}</h3>

{{page("/ja/docs/Web/HTML/Element/input/number", "step-include")}}

`week` 入力欄では、 `step` の値は週数で指定され、 604,800,000 が乗じられます (ミリ秒単位の数値であるため)。 `step` の既定値は 1 であり、1週を表します。既定の刻みの既定値は -259,200,000 で、これは1970年の最初の週 (`1970-W01`) です。

<em>現時点で、 `week` 入力欄で `step``any` の値が何を意味するかが不明確です。これは情報が決定次第、更新されるでしょう。</em>

<h2 id="Using_week_inputs" name="Using_week_inputs">week 入力欄の使用</h2>

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

`&lt;input type="week"&gt;` の基本的な使い方と少し複雑な使い方を見てみてから、その後でブラウザーの互換性の問題を緩和するアドバイスを提供しましょう ({{anch("Handling browser support", "ブラウザーの互換性の扱い")}}を参照してください)。

<h3 id="Basic_uses_of_week" name="Basic_uses_of_week">week の基本的な使用</h3>

もっとも単純な `&lt;input type=week&gt;` の使用方法は、次のように基本的な `&lt;input&gt;` と {{htmlelement("label")}} 要素の組み合わせです。

<pre class="brush: html notranslate">&lt;form&gt;
  &lt;label for="week"&gt;どの週から始めたいですか。&lt;/label&gt;
  &lt;input id="week" type="week" name="week"&gt;
&lt;/form&gt;</pre>

{{EmbedLiveSample('Basic_uses_of_week', 600, 40)}}

<h3 id="Controlling_input_size" name="Controlling_input_size">入力欄の寸法の制御</h3>

`&lt;input type="week"&gt;` は {{htmlattrxref("size", "input")}} のような寸法に関する属性には対応していません。寸法を変更する必要がある場合は、 [CSS](/ja/docs/Web/CSS) を使用する必要があります。

<h3 id="Using_the_step_attribute" name="Using_the_step_attribute">step 属性の使用</h3>

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

<h2 id="Validation" name="Validation">検証</h2>

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

<h3 id="Setting_maximum_and_minimum_weeks" name="Setting_maximum_and_minimum_weeks">週の最大値と最小値の設定</h3>

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

<pre class="brush: html notranslate">&lt;form&gt;
  &lt;label for="week"&gt;どの週から始めたいですか。&lt;/label&gt;
  &lt;input id="week" type="week" name="week"
         min="2017-W01" max="2017-W52"&gt;
  &lt;span class="validity"&gt;&lt;/span&gt;
&lt;/form&gt;</pre>

{{EmbedLiveSample('Setting_maximum_and_minimum_weeks', 600, 40)}}

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

<pre class="brush: css notranslate">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;
}</pre>

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

<h3 id="Making_week_values_required" name="Making_week_values_required">週の値を必須にする</h3>

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

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

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

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

{{EmbedLiveSample('Making_week_values_required', 600, 120)}}

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

<img alt="" src="https://mdn.mozillademos.org/files/15415/week-validation-chrome.png" style="display: block; height: 85px; margin: 0px auto; width: 473px;">

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

<h2 id="Handling_browser_support" name="Handling_browser_support">ブラウザーの対応の扱い</h2>

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

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

<img alt="" src="https://mdn.mozillademos.org/files/15413/week-chrome-android.png" style="display: block; margin: 0 auto;">

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

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

<ul>
 <li>`Week 1 2017`</li>
 <li>`Jan 2-8 2017`</li>
 <li>`2017-W01`</li>
 <li>etc.</li>
</ul>

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

<h2 id="Examples" name="Examples">例</h2>

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

{{EmbedLiveSample('Examples', 600, 140)}}

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

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

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

<div class="hidden">
<pre class="brush: css notranslate">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;
}</pre>
</div>

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

<pre class="brush: js notranslate">// 変数を定義
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');

try {
  test.type = 'week';
} catch (e) {
  console.log(e.description);
}

// もし文字列入力になるならば、 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 &lt;= 52; i++) {
    var option = document.createElement('option');
    option.textContent = (i &lt; 10) ? ("0" + i) : i;
    weekSelect.appendChild(option);
  }
}</pre>

<div class="note">
<strong>注</strong>: 53週ある年もあることを忘れないでください([年あたりの週数](https://en.wikipedia.org/wiki/ISO_week_date#Weeks_per_year)を参照)。商品のアプリを開発するときはこれを念頭に置いておく必要があります。
</div>

## 仕様書

<table class="standard-table">
 <thead>
  <tr>
   <th scope="col">仕様書</th>
   <th scope="col">状態</th>
   <th scope="col">備考</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>{{SpecName('HTML WHATWG', 'forms.html#week-state-(type=week)', '&lt;input type="week"&gt;')}}</td>
   <td>{{Spec2('HTML WHATWG')}}</td>
   <td></td>
  </tr>
 </tbody>
</table>

## ブラウザーの互換性

{{Compat("html.elements.input.input-week")}}

## 関連情報

<ul>
 <li>全般的な {{HTMLElement("input")}} およびその操作に使用する{{domxref("HTMLInputElement")}} インターフェイス</li>
 <li>[HTML で使用される日付と時刻の書式](/ja/docs/Web/HTML/Date_and_time_formats)</li>
 <li>`[&lt;input type="datetime-local"&gt;](/ja/docs/Web/HTML/Element/input/datetime-local)`, `[&lt;input type="date"&gt;](/ja/docs/Web/HTML/Element/input/date)`, `[&lt;input type="time"&gt;](/ja/docs/Web/HTML/Element/input/time)`, `[&lt;input type="month"&gt;](/ja/docs/Web/HTML/Element/input/month)`</li>
 <li>[CSS プロパティの互換性](/ja/docs/Learn/Forms/Property_compatibility_table_for_form_controls)</li>
</ul>