LoginSignup
1
0

生年月日入力フォームに「西暦と和暦」を表示するよう実装した話

Posted at

はじめに

自分の生まれた年は西暦で分かると思いますが、自分の親や親せきの人の生年月日は西暦だけだと分からないですよね。

そこで西暦と和暦を両方表示させてユーザーが選びやすいように、実務で実装を行ったため、備忘録として残します。

使用技術

HTML, Javascript, Laravel

実装コード

HTML

<dl>
    <dt>
        <label>生年月日(西暦)<span>必須</span></label>
    </dt>
    <dd>
        <select id="birth_date_year" class="form-control{{ $errors->has('birth_date_year') ? ' is-invalid' : '' }}" name="birth_date_year"></select>
        <select name="birth_date_month" id="birth_date_month" class="form-control{{ $errors->has('birth_date_month') ? ' is-invalid' : '' }}"></select><span class="subscript"></span>
        <select name="birth_date_day" id="birth_date_day" class="form-control{{ $errors->has('birth_date_day') ? ' is-invalid' : '' }}"></select><span class="subscript"></span>
    </dd>
</dl>

Javascript

    const select = document.getElementById('birth_date_year');
    const select_m = document.getElementById('birth_date_month');
    const select_d = document.getElementById('birth_date_day');
    const now = new Date();
    let now_year = now.getFullYear();
    now_year = now_year - 120;
    let thisMonthDay = 31;

    const createYearOption = () => {
        for(let i = 0; i < 122; i++) {
            let option = document.createElement("option");
            option.text = convertYearToJapaneseEra(now_year);
            if(i == 56){
                option.text = '未選択';
                option.value = '';
                option.selected = true;
            }
            else{
                option.value = now_year;
            }
            select.appendChild(option);
            if(i !== 56){
                now_year = now_year + 1;
            }
        }
    }

    const createMonthOption = () => {
        for(let i = 0; i < 12; i++){
            let option2 = document.createElement("option");
            option2.text = i + 1;
            option2.value = i + 1;
            select_m.appendChild(option2);
        }
    }

    const createDayOption = (startNum, endNum) => {
        for(let i = startNum; i < endNum; i++){
            let option3 = document.createElement("option");
            option3.text = i + 1;
            option3.value = i + 1;
            select_d.appendChild(option3);
        }
    }

    function convertYearToJapaneseEra(year) {
        let formatter = new Intl.DateTimeFormat('ja-JP-u-ca-japanese', {year: 'numeric',});
        let era0 = formatter.format(new Date(year, 0, 1));
        let era1 = formatter.format(new Date(year, 11, 31));
        if (era1.endsWith('元年') && era0 !== era1) {
            return year + '' + '(' + era1 + ')';
        }
        else{
            return year + '' + '(' + era0 + ')';
        }
    }

    window.addEventListener('load', () => {
        createYearOption();
        createMonthOption();
        createDayOption(0,thisMonthDay);
        setOldValue();
    });

    select.addEventListener('change',() => {
        const selected_year = select.value;
        const selected_month = select_m.value;

        const month_days = [0,31,28,31,30,31,30,31,31,30,31,30,31];
        thisMonthDay = month_days[selected_month];
        if(selected_month == 2 && isLeapYear(selected_year)){
            thisMonthDay = 29;
        }

        select_d.innerHTML = '';
        createDayOption(0,thisMonthDay);
    })

    select_m.addEventListener('change',() => {
        const selected_year = select.value;
        const selected_month = select_m.value;
        const selected_day = select_d.value;

        const month_days = [0,31,28,31,30,31,30,31,31,30,31,30,31];
        thisMonthDay = month_days[selected_month];
        if(selected_month == 2 && isLeapYear(selected_year)){
            thisMonthDay = 29;
        }

        select_d.innerHTML = '';
        createDayOption(0,thisMonthDay);
    })

    function isLeapYear(year){
        if( (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0) {
            return true;
        } else{
            return false;
        }
    }

1
0
3

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
1
0