質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

1回答

6092閲覧

JavaScript プルダウンで動的に日付を選択したい

P_Beginner

総合スコア99

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2020/03/23 14:44

編集2020/03/23 15:13

プルダウンで存在する日付のみを選べるようにしたいです.
閏年も考慮します.

初期値はできれば現在年月日の方がいいのですが,とりあえず初期のリストの先頭(2020/01/01)にします.

そこで以下のように書いてみたのですが,選択した年月に対応した日が表示されません.
(例:2020年2月(年は変えずデフォルトの状態),期待する日の選択範囲:1〜29,実際の選択範囲:1〜28)

具体的にどのような条件でうまくいっていないかもわからず困っています.

HTML

1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="utf-8"> 5 <title>pulldown menu</title> 6</head> 7<body> 8<center> 9<body onLoad="selectInitialize();"> 10 <form name="dateform" method="post" action="./pathToProgramFile"> 11 <!--選択肢その1--> 12 <select id="selectId1" onChange="changeSelect1();"> 13 </select>年 14 <!--選択肢その2--> 15 <select id="selectId2" onChange="changeSelect2();"> 16 </select>月 17 <!--選択肢その3(選択肢その1の項目によって変化)--> 18 <select id="selectId3"> 19 </select>日 20 </form> 21 22 <script type = "text/javascript"> 23 var uruu=0; 24 25 // 年月日初期設定(現在年月日を初期値にする方が望ましい・・・) 26 function selectInitialize(){ 27 // 年の初期設定 28 var selectElement = document.getElementById("selectId1"); 29 for (var i = 2020; i >= 2015; i--) { 30 var option = document.createElement("option"); // <option></option> 要素の作成 31 option.value = i; // valueの設定 32 option.innerText = i; // 表示テキストの設定 33 selectElement.appendChild(option); // <option></option> 要素の追加 34 } 35 36 // 月の初期設定 37 var selectElement = document.getElementById("selectId2"); 38 for (var i = 1; i <= 12; i++) { 39 var option = document.createElement("option"); // <option></option> 要素の作成 40 option.value = i; // valueの設定 41 option.innerText = i; // 表示テキストの設定 42 selectElement.appendChild(option); // <option></option> 要素の追加 43 } 44 45 // 日の初期設定 46 var selectElement = document.getElementById("selectId3"); 47 var select1 = Number(document.dateform["selectId1"].value); 48 var select2 = Number(document.dateform["selectId2"].value); 49 ld = 0; 50 if ( select2 == 1 && select2 == 3 && select2 == 5 && select2 == 7 && select2 == 8 && select2 == 10 && select2 == 12 ){ 51 ld = 31; 52 } 53 if (select2 == 4 && select2 == 6 && select2 == 9 && select2 == 11){ 54 ld = 30; 55 } 56 if (select2 == 2){ 57 if( (select1 % 4 == 0 && select1 % 100 != 0) || select1 % 400 == 0){ 58 ld = 29; 59 } 60 else{ 61 ld = 28; 62 } 63 } 64 for (var i = 1; i <= 31; i++) { 65 var option = document.createElement("option"); // <option></option> 要素の作成 66 option.value = i; // valueの設定 67 option.innerText = i; // 表示テキストの設定 68 selectElement.appendChild(option); // <option></option> 要素の追加 69 } 70 } 71 72 // 年 の選択が変わった時 73 function changeSelect1() 74 { 75 var select1 = document.dateform["selectId1"].value; // プルダウン年取得 document.フォーム名["セレクトID"].value 76 select1 = Number(select1); 77 78 if ( (select1%4==0 && select1%100!=0) || select1%400==0 ){ 79 uruu = 1; 80 } 81 else{ 82 uruu = 0; 83 } 84 } 85 86 // 月 の選択が変わった時 87 function changeSelect2(){ 88 var select2 = document.dateform["selectId2"].value; // プルダウン月取得 document.フォーム名["セレクトID"].value 89 select2 = Number(select2); 90 91 if ( select2==1 && select2==3 && select2==5 && select2==7 && select2==8 && select2==10 && select2==12 ) { 92 var selectElement = document.getElementById("selectId3"); 93 while(selectElement.lastChild){ 94 selectElement.removeChild(selectElement.lastChild); 95 } 96 for (var i = 1; i <= 31; i++) { 97 var option = document.createElement("option"); // <option></option> 要素の作成 98 option.value = i; // valueの設定 99 option.innerText = i; // 表示テキストの設定 100 selectElement.appendChild(option); // <option></option> 要素の追加 101 } 102 } 103 if( select2==4 && select2==6 && select2==9 && select2==11 ){ 104 var selectElement = document.getElementById("selectId3"); 105 while (selectElement.lastChild) { 106 selectElement.removeChild(selectElement.lastChild); 107 } 108 for (var i = 1; i <= 30; i++) { 109 var option = document.createElement("option"); // <option></option> 要素の作成 110 option.value = i; // valueの設定 111 option.innerText = i; // 表示テキストの設定 112 selectElement.appendChild(option); // <option></option> 要素の追加 113 } 114 } 115 if(select2==2){ 116 if (uruu==1){ 117 var selectElement = document.getElementById("selectId3"); 118 while (selectElement.lastChild) { 119 selectElement.removeChild(selectElement.lastChild); 120 } 121 for (var i = 1; i <= 29; i++) { 122 var option = document.createElement("option"); // <option></option> 要素の作成 123 option.value = i; // valueの設定 124 option.innerText = i; // 表示テキストの設定 125 selectElement.appendChild(option); // <option></option> 要素の追加 126 } 127 } 128 else{ 129 var selectElement = document.getElementById("selectId3"); 130 while (selectElement.lastChild) { 131 selectElement.removeChild(selectElement.lastChild); 132 } 133 for (var i = 1; i <= 28; i++) { 134 var option = document.createElement("option"); // <option></option> 要素の作成 135 option.value = i; // valueの設定 136 option.innerText = i; // 表示テキストの設定 137 selectElement.appendChild(option); // <option></option> 要素の追加 138 } 139 } 140 } 141 } 142 143 144 </script> 145</center> 146</body> 147</html>

参考

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

P_Beginner

2020/03/23 15:10

実行結果が期待通りではないと言うことです. ここで期待する動作とは,年月は選択する値が固定,日の選択範囲は選択されている年月によって動的に変わることを指します. 追記しておきます.
thyda.eiqau

2020/03/23 19:02

<input type="date"> では駄目なのですか? あるいは、 <input type="number"> で作って、入力後にフォーカスが外れたタイミングとかで検証して、不正な日付だったらバリデーションエラーっぽく表示するとか。 日付の指定に <select> を使うのはどうなんでしょう。たとえばユーザー登録の際の誕生日の入力フォームだとして、だいたい100歳くらいまで考慮しておけばカバーできるでしょうから最小値は1920、刑事責任能力が無い歳も避けるとして最大値は2006、この間をずらーっとスクロールさせるのって、あんまりじゃないですか?たとえばの話なのでなんとも言えないですが。
guest

回答1

0

ベストアンサー

難しく考えすぎだと思いますが……

日付の上限値は28か29か30か31かの4パターンですが、その4パターン分のfor文を個別に書く必要はなく、 for(let i=1; i<maxDate; i++) { ... } としておいて、 maxDate に28から31の適切な値を入れるようにしたほうが、全体のコード量が削減でき見通しがよくなります。

その maxDate も、複雑に分岐する必要はなくて、基本的には31で、必要 (= 小の月かどうか) に応じて30で上書きして、さらに必要 (= 2月かどうか) に応じて28か29で上書きすればよいです。

js

1let isLeapYear = false; 2 3// 年月日初期設定(現在年月日を初期値にする方が望ましい・・・) 4function selectInitialize() { 5 // 年の初期設定 6 const yearSelect = document.getElementById('selectId1'); 7 8 const now = new Date(); 9 const thisYear = now.getFullYear(); 10 11 // 月と日は上が若い数字なのに年だけ逆なのはさすがにキモい。上が若い数字になるように変更 12 for(let i = thisYear - 5; i <= thisYear; i++) { 13 const option = document.createElement('option'); 14 option.value = i; 15 option.innerText = i; 16 yearSelect.appendChild(option); 17 } 18 yearSelect.value = thisYear; // 今日の年にする 19 20 // 月の初期設定 21 const monthSelect = document.getElementById('selectId2'); 22 23 // 1月は0で表現するように合わせておいたほうが将来的に楽になる気がする 24 for (let i = 0; i <= 11; i++) { 25 const option = document.createElement('option'); 26 option.value = i; 27 option.innerText = i+1; 28 monthSelect.appendChild(option); 29 } 30 monthSelect.value = now.getMonth(); // 今日の月にする 31 32 // 日の初期設定 33 const dateSelect = document.getElementById('selectId3'); 34 // 要素の作成は changeSelect1(), changeSelect2() とやることは同じなので、 35 // そちらを呼び出すだけにする 36 changeSelect1(); // ← うるう年の判定 37 changeSelect2(); // ← 日付の <option> の生成 38 dateSelect.value = now.getDate(); // 今日の日にする 39} 40 41 42// 年 の選択が変わった時 43function changeSelect1() { 44 // うるう年ではない年、たとえば2019年で new Date('2019-02-29') として 45 // Dateのインスタンスを生成したとき、そのインスタンスが示す日付は自動的に 46 // 3月1日になって、 getMonth() の値が3月になる。 47 // つまり、「うるう年か?」 は、「(new Date(xxxx-02-29)).getMonth() が 3月か?」 48 // と言い換えることができる。 49 isLeapYear = (new Date(document.getElementById('selectId1').value + '-02-29')).getMonth() === 1; 50 51 // あらたに選択された年がうるう年ではなく、選択済みの月が2月の場合、 52 // 29日は成立しなくなる。もし29日が選択されている場合は強制的に28日に変更する 53 if( 54 !isLeapYear && 55 parseInt(document.getElementById('selectId2').value, 10) === 1 && 56 parseInt(document.getElementById('selectId3').value, 10) > 28 57 ) { 58 document.getElementById('selectId3').value = 28 59 } 60} 61 62// 月 の選択が変わった時 63function changeSelect2() { 64 // 日の <select> を再描画すると強制的に1日が選ばれるようになるので、 65 // 現時点での選択肢を保持しておき、再描画後にセットする 66 const selectedDate = parseInt(document.getElementById('selectId3').value, 10); 67 68 let maxDate = 31; 69 const selectedMonth = parseInt(document.getElementById('selectId2').value, 10); 70 if([1, 3, 5, 8, 10].indexOf(selectedMonth) !== -1) { 71 // 小の月は基本的に30日まで 72 maxDate = 30; 73 74 // 2月の場合のみ28日か29日になる 75 if(selectedMonth === 1) { 76 maxDate = isLeapYear ? 29 : 28; 77 } 78 } 79 80 const dateSelect = document.getElementById('selectId3'); 81 dateSelect.innerHTML = ''; 82 for(let i=1; i<=maxDate; i++) { 83 const option = document.createElement('option'); 84 option.value = i; 85 option.innerText = i; 86 dateSelect.appendChild(option); 87 } 88 dateSelect.value = selectedDate <= maxDate ? selectedDate : maxDate; 89}

Mar 24, 2020 10:51 AM : コメント追加、コードの不足を修正

投稿2020/03/23 19:55

編集2020/03/24 01:51
thyda.eiqau

総合スコア2982

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

P_Beginner

2020/03/24 11:44

回答ありがとうございました.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問