LoginSignup
8
9

More than 3 years have passed since last update.

生年月日の入力セレクトボックスを動的に変化させる

Last updated at Posted at 2019-10-06

はじめに

ユーザー登録を行うとき、生年月日を入力してもらうためにセレクトボックスを
用いるとします。ここで、生年月日のセレクトボックスの中身にHTMLやhamlで
直接データを入れ込んでしまうと4/31や2/31などが選択できてしまいます。

なので、年と月の情報をもとに日のセレクトボックスの中身を動的に変化させてみます。
実装にはJavascriptを用います。
(JQueryが入っているのでJavascriptのみの場合と記述方式が異なります)

環境

Rails 5.2.2.1
Ruby 2.5.1
jquery-rails 4.3.5
haml-rails 2.0.1

完成したもの

app/views/入力フォームが書いてあるファイル
= f.select :birth_year,["--"], {},{class: "セレクトボックスを修飾するクラスを入れる", id:"select_birth_year"}
  %label
    
= f.select :birth_month, ["--"], {},{class: "セレクトボックスを修飾するクラスを入れる", id:"select_birth_month"}
  %label
    
= f.select :birth_day, ["--"], {},{class: "セレクトボックスを修飾するクラスを入れる", id:"select_birth_day"}
  %label
    
app/assets/javascripts/registration.js
$(document).on('turbolinks:load', function () {
  // ユーザーの誕生日の閏年を動的に変化させる
  // 誕生日の配列を宣言
  var birth_year = [];
  var birth_month = [];
  var months = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

  // 現在の年を取得する
  var date = new Date();
  var this_year = date.getFullYear();
  var oldest_year = 1900;

  // 誕生年月の配列を自動生成
  for (var i = this_year; i >= oldest_year; i--) {
    var year = { var: i, txt: String(i) };
    birth_year.push(year);
  }
  for (var i = 1; i <= 12; i++) {
    var month = { var: i, txt: String(i) };
    birth_month.push(month);
  }
  // hamlの年と月のセレクトボックスに配列内容を反映させる
  for (var i = 0; i < birth_year.length; i++) {
    $("<option>", {
      value: birth_year[i].var,
      text: birth_year[i].txt
    }).appendTo('#select_birth_year');
  }
  for (var i = 0; i < birth_month.length; i++) {
    $("<option>", {
      value: birth_month[i].var,
      text: birth_month[i].txt
    }).appendTo('#select_birth_month');
  }

  // 年、もしくは月のセレクトボックスの中身に変更があったら日の内容を変更する
  $('#select_birth_year, #select_birth_month').change(function () {
    // 日が入っているセレクトボックスの中身を空っぽにする
    $('#select_birth_day').empty();
    // 日が入るセレクトボックスにデフォルト値の'--'を入れる
    $("<option>", {
      text: '--'
    }).appendTo('#select_birth_day');
    // 2月の日にち、すなわちmonths[1]を28にセットし直す
    months[1] = 28;
    // 年と月に入力されている情報を取得する
    var year = $('#select_birth_year').val();
    var month = $("#select_birth_month").val();
    // yearとmonth共に数字が入力されている、すなわち共に'--'でないときに実行
    if (year != '--' && month != '--') {
      // monthに2月が選択されている時実行
      if (month == 2) {
        // yearが閏年の時、2月の日付が格納されているmonths[1]の値を29にする
        if (year % 4 == 0 && year % 100 == 0 && year % 400 == 0) {
          months[1] = 29;
        }
      }
      // 日を入れる配列を宣言し、閏年を考慮したデータを格納してhamlの日の
      // セレクトボックスに反映させる
      var birth_day = []
      for (var i = 1; i <= months[month - 1]; i++) {
        var day = { var: i, txt: String(i) };
        birth_day.push(day);
      }
      for (var i = 0; i < birth_day.length; i++) {
        $("<option>", {
          value: birth_day[i].var,
          text: birth_day[i].txt
        }).appendTo('#select_birth_day');
      };
    };
  });
});
8
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
9