このサイトは、只今WEB業界で活躍中のデザイナー、プログラマーの方々の情報を集めたweb統合情報サイトです。

web帳

記事詳細

2015.07.17

TypeScript & AngularJS で日付選択フォーム作成

どうもです。

いやぁ。

暑いですねー。全く。

なんとなく、AngularJSの事書きたくなったので書きます。

まぁ、特別すごい事ではないのですが、何か参考になればと。

で、今回はこういった年月日の選択フォームに関して

htmlで言うと、select要素を用いて実装するのですが、

<select id="year" name="year">
    <option value="0">2015</option>
    <option value="1">2016</option>
    <option value="2">2017</option>
</select>

こんな感じですかね。

ま、AngularJS使っていると、こんなべた書きはせず、ng-options等を用いて実装します。

詳しくはこちらなど参考にしていただければと。

http://js.studio-kingdom.com/angularjs/ng_directive/select

で、ng-options用いたhtmlは

<select id="year" ng-options="y for y in yearList" ng-model="scheduleYear"></select>

こんな感じですかね。

yearListは[“2015″,”2016″,”2017”]といった年号の配列となっております。

この形で行くと、Javscript側は、

$scope.yearList = ["2015","2016","2017"]; 

といった感じで$scope.yearListを定義します。

すると、

こんな感じにできちゃうわけですね。いやー便利。

ですが、こんなベタ書きしていますと、(こんなベタ書きしないのですが)

「来年手書きで修正?」「数増やす時は?」と、色々と手動感たっぷりになり、JavaScript使っている意味ないですね。

JavaScriptは日付オブジェクトである、Dateオブジェクトが用意されていますので、こちらを使っていきましょう。

var now = new Date();

now.getFullYear();

now.getMonth() + 1;

now.getDate();

といった形で、現在の年月日を取得できます。

といったわけで、こういう日時を選択するフォームの作成を行いましょう。

日時選択フォーム作成

注意点としましては、日にちが変動するところですかね。

結論を言ってしまうと、以下のように year(年)、month(月)の値を引数として実行すれば、日にちが何日あるか取得できます。

function getDay(year, month) {
    return new Date(year, month, 0).getDate();
}

これをhtmlの方にFunctionとして登録すれば、年月を変更すれば連動して日にちも取得できます。

といったところでhtmlの方は、こんな感じで

<select id="year" ng-options="y for y in yearList" ng-model="scheduleYear"></select>
<label for="year">年</label>
<select id="month" ng-options="m for m in monthList" ng-model="scheduleMonth"></select>
<label for="month">月</label>
<select id="day" ng-options="d for d in getDayList(scheduleYear, scheduleMonth)" ng-model="scheduleDay"></select>
<label for="day">日</label>

getDayListscheduleYearとscheduleMonthを引数にする事によって日付を取得してきます。

ここから、TypeScriptで記述していきます。

日時選択フォーム作成:TypeScripe

まずmoduleはScheduleとして作成。

class ScheduleModelを作成しています。

module Schedule {
    class ScheduleModel {
        constructor() {}
    }
}

constructor(){}はScheduleModelを生成の際、呼び出され初期化が行えます。

まず、今の年数から何年表示させたいかを、ADD_SELECT_YEAR_NUMの定数とし定義。

private ADD_SELECT_YEAR_NUM: number = 3;
private select_year_list: string[] = [];
private select_month_list: string[] = [];

年と月を格納するリストも定義。

年リストをsetする、setアクセサを作成しています。

public setYearList() {
    var year = new Date().getFullYear(),
    i;
    for(i = 0; i < this.ADD_SELECT_YEAR_NUM; i++) {
        this.select_year_list.push(String(year + i));
    }
}

月リストをsetする、setアクセサを作成しています。

月は固定で1〜12月なので以下のような感じで。

public setMonthList() {
    var i: number;
    for(i = 1; i < 13; i++) {
        this.select_month_list.push(String(i));
    }
}

続いて、年、月を取得するgetアクセサの作成

public getYearList(): string[] {
    return this.select_year_list;
}
public getMonthList(): string[] {
    return this.select_month_list;
}

なんてないですね。

では、今の年、月はそのリストから何番目なのかを取得するgetアクセサを作成。

public getInitYearNum(): number {
    var year = new Date().getFullYear();
        return this.select_year_list.indexOf(String(year));
}
public getInitMonthNum(): number {
    var month = new Date().getMonth() + 1;
    return this.select_month_list.indexOf(String(month));
}

これで、とりあえず、年、月のリストは完成しましたね。

class ScheduleModel生成時にこれらを実行したいので、

constructor(
) {
    this.setYearList();
}

こんな感じで、setYearList()には、this.setMonthList();を追記します。

scope

年のリストと、月のリストのscopeの作成して、

$scope.yearList = model.getYearList();
$scope.monthList = model.getMonthList();

ng-modelの方に、今現在の年、月を代入。

$scope.scheduleYear = $scope.yearList[model.getInitYearNum()];
$scope.scheduleMonth = $scope.monthList[model.getInitMonthNum()];

で、選択された状態になります。

それらを、getDayListで引数としますので、scope側はこんな感じで。

$scope.getDayList = (year: string, month: string): string[] => {
    return model.getDayList(parseInt(year, 10), parseInt(month, 10));
};

modelの方で、yearとmonthを元に日付を返すように処理しています。

public getDayList(year: number, month: number) {
    var dayLength = new Date(year, month, 0).getDate(),
    dayList: string[] = [],
    i;
    for(i = 0; i < dayLength; i++) {
        dayList.push(String(1 + i));
    }
    return dayList;
}

初期の日付を返すgetアクセサも作成。

public getInitDay(): string {
    var nowDate = new Date(),
    dayList = this.getDayList(nowDate.getFullYear(), nowDate.getMonth() + 1),
    initNumber = dayList.indexOf(String(nowDate.getDate()));
    return dayList[initNumber];
}

scopeにgetInitDayを代入すれば完成ですね。

$scope.scheduleDay = model.getInitDay();

年、月を変更すると、日付も連動。

と、今回のソースはgistに記載しております。

https://gist.github.com/webcyou/cf4e87cece86806d0d0a

参考になればとー。

ではでは。

  • RSSを登録する

  • follow us in feedly

Graphical FrontEnd Engineer
- Daisuke Takayama

MAD CITY 北九州市で生まれ育つ。20代はバンド活動に明け暮れ、ふと「webデザイナーになりたい。」と思い、デジタルハリウッド福岡校入学。卒業後、数々の賞を受賞、web業界をざわつかせる。
現在、港区六本木で活動中。

WEBデザイナーの、WEBデザイナーによる、WEBデザイナーの為のサイト。「みんなで書こう!」と仲間を募ってみたが、結局書くのは自分だけとなってしまいました。日々のメモを綴っていきます。