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

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

ただいまの
回答率

90.12%

JavaScriptで年/月のプルダウンを作成したい

解決済

回答 2

投稿

  • 評価
  • クリップ 1
  • VIEW 4,606

amaguri

score 217

参考デモサイト
コード

やりたいこと
2017/05
を基準にした、今月までの
年/月
がセットのプルダウンを作成したいです

参考サイトより

<script>
(function() {
  'use strict';

  /*
    今日の日付データを変数todayに格納
   */
  var optionLoop, this_day, this_month, this_year, today;
  today = new Date();
  this_year = today.getFullYear();
  this_month = today.getMonth() + 1;
  this_day = today.getDate();

  /*
    ループ処理(スタート数字、終了数字、表示id名、デフォルト数字)
   */
  optionLoop = function(start, end, id, this_day) {
    var i, opt;

    opt = null;
    for (i = start; i <= end ; i++) {
      if (i === this_day) {
        opt += "<option value='" + i + "' selected>" + i + "</option>";
      } else {
        opt += "<option value='" + i + "'>" + i + "</option>";
      }
    }
    return document.getElementById(id).innerHTML = opt;
  };


  /*
    関数設定(スタート数字[必須]、終了数字[必須]、表示id名[省略可能]、デフォルト数字[省略可能])
   */
  optionLoop(1950, this_year, 'id_year', this_year);
  optionLoop(1, 12, 'id_month', this_month);
  optionLoop(1, 31, 'id_day', this_day);
})();


この処理にて
optionLoopの年を1950から2017に変更すれば
選択できる月の変更は可能なのはわかるのですが
optionLoopの年と月を使い

年/月
が一つになった
プルダウンを作成したいのですがうまくいきません。

どうすれば実現可能でしょうか?

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • m.ts10806

    2017/08/31 13:07

    そもそも現状のつくりでは「今日の日(今日なら31日)」は選択状態になっても「今日の月(今日なら8月)」は選択状態にならないはずなのですが、それはそのままでいいのでしょうか?

    キャンセル

  • m.ts10806

    2017/08/31 13:10

    あ、8月8日とか年月同じ数字の場合は選択状態になりますね。

    キャンセル

  • m.ts10806

    2017/08/31 13:33

    すみません。引数がthis_dayとなっているための勘違いでした。引数の受け取り側は変数名変えた方がいいかもしれませんね・・・。

    キャンセル

回答 2

+3

例えばこんな感じでしょうか?

(function() {
  'use strict';
  var optionLoop, this_day, this_month, this_year, today;
  today = new Date();
  this_year = today.getFullYear();
  this_month = today.getMonth() + 1;
  this_day = today.getDate();
  optionLoop = function(start_year, end_year,start_month, end_month, id, this_day) {
    var i,j,v,opt,start_j,end_j;
    opt = "";
    for (i = start_year; i <= end_year ; i++) {
      start_j=(i == start_year)?start_month:1;
      end_j=(i <= end_year-1)?12:end_month;
      for (j = start_j; j <= end_j ; j++) {
        v=i+"/"+(100+j).toString().substr(-2);
        opt+="<option value=\""+v+"\">"+v+"</option>\n";
      }
    }
    document.getElementById(id).innerHTML = opt;
  };
  optionLoop(2015, this_year, 5, this_month, 'hoge', this_year);
})();

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

checkベストアンサー

+2

現在の作りは「指定した数字の範囲のoptionを作り指定したidのコントロールに対してhtmlを追加する」作りにしかなっていないので、そのままは使えません。
「日」のはそのまま使うとして「年/月」で作る関数を自作しなければなりません。
ただ、一部は利用できるので(日付取得部分とかループ部分とか)、流用しつつ「年/月optionを生成する関数」を作ります。
「年」は指定範囲なので今の仕組みは使いますが、「月」に関しては1~12と範囲は決まっています。
つまり「年の範囲を渡したらその年の範囲ループの中に1~12の固定範囲ループする処理を追加し、年/月を形作る」ですね。

サンプル:

  var optionYMCreate, this_day, this_month, this_year, today,this_ym;
  today = new Date();
  this_year = today.getFullYear();
  this_month = today.getMonth() + 1;
  this_ym = this_year +'/'+this_month; //今月

  //年月オプションを作る
  optionYMCreate = function(ystart,yend, id) { //年の範囲と対象のコントロールIDを受け取る
    var i, opt,m_i,ym,selected_option ;
    opt = null;
    for (i = ystart; i <= yend ; i++) { //年のループ
      for(m_i=1;m_i<=12;m_i++){ //月のループ
          ym = i +'/'+ m_i; //ループ内の年月
          selected_option = '';
          if (ym === this_ym) { //今年月と一致してたら選択済みとする
            selected_option = 'selected';
          }
           opt += '<option value="' + ym + '" '+selected_option+'>' + ym + '</option>';
      }
    }
    return document.getElementById(id).innerHTML = opt;
  };

  optionYMCreate(1950, this_year, 'year_month');

年/月の表示形式や0埋めが必要であれば都度調べて整形してください。

追記:
「今月を選択状態」の「今月」はグローバルに宣言されているので引数で渡していません。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/08/31 14:15

    回答ありがとうございます
    この場合
    <html lang="ja">
    <head>
    <meta charset="UTF-8">
    <title>年月日表示の練習</title>
    </head>
    <body>
    <select name="year" id="id_year">
    </select>
    <select name="month" id="id_month">
    </select>
    のセレクトはどのidを宣言するのでしょうか?

    キャンセル

  • 2017/08/31 14:25

    そのHTML構造では年と月のセレクトがそれぞれ独立してますよね。
    セレクトを1つにして好きなIDを宣言すると良いです。
    私が提示したソースのoptionYMCreate()の第3引数はその宣言したIDです。
    もとのamaguriさんが提示されたソースも引数に対象のIDを渡してますよね?根本の作りは変わっていませんよ。

    キャンセル

  • 2017/08/31 15:41

    ありがとうございます!!

    キャンセル

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

  • ただいまの回答率 90.12%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる