文系卒のWebエンジニアの成長と備忘録
エンジニア経験を生かして発信するメディアサイト

【JavaScript】生年月日のフォームを動的に作成する方法を解説!

javascript

こんにちはysです。普段サーバーサイドのWebエンジニアのとして自社サービスを開発している会社で働いています。

今回の記事では、以下のようなデモの画面を作成したいと思います。
基本的なJavaScriptの文法さえ知っていれば簡単に作成できます。

西暦は1950-2020までの範囲で作成し、月日はそれぞれにあった月と日が出るように設定します。
2月はうるう年のことも考慮して、29日までの設定をしていきます。
1月であれば31日、2月あれば29日、3月であれば31日….のような感じですね。

生年月日form

select要素にoption要素をfor文のループで作成して、それぞれの月と日を紐付けるだけで簡単に作成できます。

基本的な処理の流れ

  1. 1930-2020年までの要素を作成する
  2. 1-12月までの要素を作成する
  3. 月に紐付いた日にち分の要素を作成する
  4. 月が変更されたら、その月に紐づいた日にちに変更する

selectボックスのHTMLを作成していこう

programming html css
作成するselectボックスの数は『西暦』『月』『日』の3つ。
まずはひな形だけ作成します。

1

<div class="form-select-box">
</div>

まずは大枠だけ作成。
この中にselectタグを入れていきます。

2

<div class="form-select">
    <select class="birthday-year dropdown-toggle">
    <!-- 1930-2050まで -->
    </select>
</div>
    /

ここで指定するのは『西暦』

option要素を書いていないのでは、JavaScriptで動的に作成するからです。

最後の「 / 」はデザイン的に『2000 / 01 / 01』のようなデザインにするために記述しています。

3

<div class="form-select">
    <select class="birthday-month dropdown-toggle">
    <!-- 1-12まで -->
    </select>
</div>
    /

ここで指定するのは『月』。

1月から12月までのoption要素を後々JavaScriptで作成していきます。

4

<div class="form-select">
    <select class="birthday-day dropdown-toggle">
        <!-- 1-31まで -->
    </select>
</div>  

ここで指定するのは『日』。

1日から31日までのoption要素を後々JavaScriptで作成していきます。ただ上記でも書いた通り、日にちの数は月によって変わるのでここだけは動的に変わるように処理を書きます。

HTMLの全体像

    <div class="form-select-box">
        <div class="form-select">
            <select class="birthday-year dropdown-toggle">
                <!-- 1930-2050まで -->
            </select>
        </div>
            / 
        <div class="form-select">
            <select class="birthday-month dropdown-toggle">
                <!-- 1-12まで -->
            </select>
        </div>
            /
        <div class="form-select">
            <select class="birthday-day dropdown-toggle">
                <!-- 1-31まで -->
            </select>
        </div>            
    </div>

これでHTMLの全体像は完成です。ここからCSSで整えて最低限のデザインを作成します。

selectボックスのCSSを作成していこう

1

.form-select-box {
    display: flex;
    justify-content: space-between;
}

selectボックス全体を囲う大枠に当てるCSSです。全てのセレクトボックスをdisplayのflexを使用して横並びにします。

justify-contentをspace-betweenにする事で要素同士の感覚を等間隔にします。

2

.form-select {
    position: relative;
}

.form-select::before {
    position: absolute;
    content: "\f0d7";
    font-family: "Font Awesome 5 Free";
    font-weight: 900;
    top: 10px;
    right: 17px;
}

selectボックスを囲う親要素です。軽いデザインを整えて上げるためにCSSで整えます。

selectボックスとわかりやすいように「▼」マークをCSSで当てて上げるとユーザー的に分かりやすいので等記事ではその方法で書きます。

3

.dropdown-toggle {
    padding: 8px 23px 8px 14px;
    margin-left: 10px;
    margin-right: 10px;
    background-color: white;
    border: 1px solid #a5a5a5;
    border-radius: 4px;
    font-size: 14px;
}

最後にselectボックス自身にCSSを当てます。特に深いものはないですね。

強いて言うならborder要素はお好みのものを当てておくと、自分のサイトにあったものが作成できると思います。

CSSの全体像

.form-select-box {
    display: flex;
    justify-content: space-between;
}
.form-select {
    position: relative;
}

.form-select::before {
    position: absolute;
    content: "\f0d7";
    font-family: "Font Awesome 5 Free";
    font-weight: 900;
    top: 10px;
    right: 17px;
}

.dropdown-toggle {
    padding: 8px 23px 8px 14px;
    margin-left: 10px;
    margin-right: 10px;
    background-color: white;
    border: 1px solid #a5a5a5;
    border-radius: 4px;
    font-size: 14px;
}

これで準備が出来ました。あとはJavaScriptでoption要素を作成していく処理を書いていきます。

JavaScriptでSelectボックスを動的に作成していこう

js
基本的な処理の流れは上記で書いた通りです。
まずはそれぞれのselectボックスの要素を取得します。

var userBirthdayYear = document.querySelector('.birthday-year');
var userBirthdayMonth = document.querySelector('.birthday-month');
var userBirthdayDay = document.querySelector('.birthday-day');

次にselectボックスの中にoption要素を動的に生成していきます。
3つのselectボックスのoption要素を作成する必要があるのですが、処理が被るためoption要素を作成する処理はメソッド化します。

ここの引数には以下の値が入ります。
el select要素が入ります
val optionに当て込む値(西暦や月)が入ります

/**
 * selectボックスのoption要素を生成する
 * @param int el element
 * @param int val value
 */
function createElementsForOptions(el, val) {
    var op = document.createElement('option');
    op.value = val;
    op.text = val;
    el.appendChild(op);
}

西暦のoption要素を作成する

ループの始まりと終わりは適当に決めています。1930年代から生成していますがここはお好みです。終わりは2020年にしていますが現在の西暦で合わせる方が良です。

現在の西暦だけ取得する処理を入れて、そこをループの終わりにすると品質が上がりますね。

// 1930年代から2050年代までoption要素を生成
for(var i = 1930; i <= 2020; i++) {
    createElementsForOptions(userBirthdayYear, i);
}

月のoption要素を作成する

月は1月〜12月までの固定ループで問題ないです。

// 1月から12月までのoption要素を生成
for(var j = 1; j <= 12; j++) {
    createElementsForOptions(userBirthdayMonth, j);
}

日付のoption要素を作成する

日付は動的に値が変わる可能性があるので少し複雑ですが、デフォルトでは31まで作成します。というのも、デフォルトでは1月が選択された状態なので、31日まで最大でループを回します。

// 1日から31日までのoption要素を生成
// ※デフォルトでは1月が選択されているで31
for(var k = 1; k <= 31; k++ ) {
    createElementsForOptions(userBirthdayDay, k);
}

月が変わる度に、その月に紐付く日にちを出力しよう

月が変わる度にその月に基づく日を出力する処理は、月の値が変わる度に呼び出されるのでメソッド化します。
ここの引数には以下の値が入ります。
el 月のselect要素が入ります

ここで月に紐付く日にちを連想配列で設定します。
そうする事で、月(1月など)を連想配列のkeyとして、その月に紐付いた日の数を出力することが出来ます。

returnの配列要素を返していますが、配列なので要素が0から始まります。
そのためindex要素を+1にして返すと適応の処理になります。

    /**
    * 月が変わったら日のoption要素の値を変える
    *
    * @param int el userBirthdayMonth
    */
function createDaysForOptions(el) {
    var index = el.selectedIndex;
    const mouth = {
        1 : 31, 2 : 29, 3 : 31, 4 : 30,
        5 : 31, 6 : 30, 7 : 31, 8 : 31, 
        9 : 30, 10 : 31, 11 : 30, 12 : 31,
    }

    // 要素がずれるので+1をする
    return mouth[index + 1];
}

そして日付が変わったタイミングで上記のメソッドを呼び出します。要素が変わったタイミングなのでchangeイベントを使用します。

月が変わったら、その月に基づく日付でoption要素を作成する処理をループで回し生成します。ただこの時点ではoption要素がどんどん追加されるだけになるので古いoption要素は削除しないといけません。

removeDaysElementsForOptions();というメソッドを作成して前回のループで作成されたoption要素を削除します。

// 日付の数は月によって変わるので動的に変えるようにする
userBirthdayMonth.addEventListener('change', () => {
    var days = createDaysForOptions(userBirthdayMonth);

    // 前回までで生成されたoptionを消去
    removeDaysElementsForOptions();
    // 月に応じた月の日付けoption要素を生成
    for(var l = 1; l <= days; l++ ) {
        createElementsForOptions(userBirthdayDay, l);
    }
});

古いoption要素を削除しよう

innerHTML要素を空にすることfでoption要素を消し去ります。これで全ての処理が完了です。

function removeDaysElementsForOptions() {
    var birthday = document.getElementsByClassName('user-birthday-day');
    return birthday[0].innerHTML = '';
}

JavaScript全体像

var userBirthdayYear = document.querySelector('.user-birthday-year');
var userBirthdayMonth = document.querySelector('.user-birthday-month');
var userBirthdayDay = document.querySelector('.user-birthday-day');

// 1930年代から2050年代までoption要素を生成
for(var i = 1930; i <= 2050; i++) {
    createElementsForOptions(userBirthdayYear, i);
}

// 1月から12月までのoption要素を生成
for(var j = 1; j <= 12; j++ ) {
    createElementsForOptions(userBirthdayMonth, j);
}

// 1日から31日までのoption要素を生成
// ※デフォルトでは1月が選択されているで31
for(var k = 1; k <= 31; k++ ) { createElementsForOptions(userBirthdayDay, k); } // 日付の数は月によって変わるので動的に変えるようにする userBirthdayMonth.addEventListener('change', () => {
    var days = createDaysForOptions(userBirthdayMonth);

    // 前回までで生成されたoptionを消去
    removeDaysElementsForOptions();
    // 月に応じた月の日付けoption要素を生成
    for(var l = 1; l <= days; l++ ) {
        createElementsForOptions(userBirthdayDay, l);
    }
});
    /**
     * 月が変わったら日のoption要素の値を変える
     *
     * @param int el userBirthdayMonth
     */
    function createDaysForOptions(el) {
        var indexKey = el.selectedIndex;
        const mouth = {
            1 : 31, 2 : 29, 3 : 31, 4 : 30,
            5 : 31, 6 : 30, 7 : 31, 8 : 31, 
            9 : 30, 10 : 31, 11 : 30, 12 : 31,
        }

        // 要素がずれるので+1をする
        return mouth[indexKey + 1];
    }

    /**
     * selectボックスのoption要素を生成する
     * @param int el element
     * @param int val value
     */
    function createElementsForOptions(el, val) {
        var op = document.createElement('option');
        op.value = val;
        op.text = val;
        el.appendChild(op);
    }
    
    function removeDaysElementsForOptions() {
        var birthday = document.getElementsByClassName('user-birthday-day');
        return birthday[0].innerHTML = '';
    }

これで完了です!
プログラミングの初心者向けですので気軽に自分の開発したサービスなどに組み込めると思います。

JavaScriptをもっとマスターしたいあなたに

「上記のようなJavaScriptで動的に何かしたいけど、やり方がわからない」などプログラミングの勉強方法に迷っている方向け!

Udemyのオンライン学習講座が大変参考になります。動画が単価制なので一度購入してしまえば、いつでもどこでも見放題です。30日間の返金保証も付いているので「自分に合わなかったなあ」という方でも安心です。

上記の解説は以下で詳細に行なっています。是非。

人気記事【独学者おすすめ】プログラミング学習動画サービス3選

人気記事プログラミング実務未経験者が自社開発エンジニアになるための方法

人気記事エンジニアを目指しているなら使用すべき5つの転職サイト

\記事のシェアをお願いします!/