TypeScript & AngularJS で日付選択フォーム作成
2015.07.17
この記事は最終更新日から1年以上が経過しています。
どうもです。
いやぁ。
暑いですねー。全く。
なんとなく、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>
getDayListでscheduleYearと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
[gist id=cf4e87cece86806d0d0a]
参考になればとー。
ではでは。