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

web帳

記事詳細

2015.07.17

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

どうもです。

いやぁ。

暑いですねー。全く。

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

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

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

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

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

こんな感じですかね。

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

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

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

で、ng-options用いたhtmlは

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

こんな感じですかね。

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

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

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

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

すると、

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

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

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

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

[code]var now = new Date();[/code]

[code]now.getFullYear();[/code]

[code]now.getMonth() + 1;[/code]

[code]now.getDate();[/code]

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

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

日時選択フォーム作成

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

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

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

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

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

[code]
<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>[/code]

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

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

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

まずmoduleはScheduleとして作成。

class ScheduleModelを作成しています。

[code]module Schedule {
class ScheduleModel {
constructor() {}
}
}[/code]

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

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

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

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

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

[code]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));
}
}[/code]

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

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

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

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

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

なんてないですね。

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

[code]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));
}[/code]

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

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

[code]constructor(
) {
this.setYearList();
}[/code]

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

scope

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

[code]$scope.yearList = model.getYearList();
$scope.monthList = model.getMonthList();[/code]

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

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

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

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

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

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

[code]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;
}[/code]

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

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

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

[code]$scope.scheduleDay = model.getInitDay();[/code]

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

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

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

[gist id=cf4e87cece86806d0d0a]

参考になればとー。

ではでは。

  • RSSを登録する

  • follow us in feedly

Graphical FrontEnd Engineer
- Daisuke Takayama

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

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