aboutsummaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorFelix Nagel <info@felixnagel.com>2015-09-27 18:35:35 +0200
committerFelix Nagel <info@felixnagel.com>2015-09-27 18:45:53 +0200
commitdcef45359418fe103beed0ada435da5080cc16ef (patch)
tree2df9615de068b35f4a6c40d7badb5dd028c24462 /ui
parentaf7d2009ce95cf1975bb840ba9d2da9b3fb7a52b (diff)
downloadjquery-ui-dcef45359418fe103beed0ada435da5080cc16ef.tar.gz
jquery-ui-dcef45359418fe103beed0ada435da5080cc16ef.zip
Calendar: Move custom date object to ui namespace
Diffstat (limited to 'ui')
-rw-r--r--ui/date.js237
-rw-r--r--ui/widgets/calendar.js4
2 files changed, 239 insertions, 2 deletions
diff --git a/ui/date.js b/ui/date.js
new file mode 100644
index 000000000..1d207a39f
--- /dev/null
+++ b/ui/date.js
@@ -0,0 +1,237 @@
+/*
+ * Calendar math built on jquery-global
+ *
+ * Based on Marc Grabanski's jQuery Date Plugin
+ * http://marcgrabanski.com/articles/jquery-date-plugin
+ */
+( function( factory ) {
+ if ( typeof define === "function" && define.amd ) {
+
+ // AMD. Register as an anonymous module.
+ define( [
+ "jquery", "./version" ], factory );
+ } else {
+
+ // Browser globals
+ factory( jQuery );
+ }
+}( function( $ ) {
+
+var weekdaysRev = {
+ "sun": 0,
+ "mon": 1,
+ "tue": 2,
+ "wed": 3,
+ "thu": 4,
+ "fri": 5,
+ "sat": 6
+ };
+
+$.ui.date = function( date, attributes ) {
+ if ( !( this instanceof $.ui.date ) ) {
+ return new $.ui.date( date, attributes );
+ }
+
+ this.setAttributes( attributes );
+
+ if ( typeof date === "string" && date.length ) {
+ this.dateObject = attributes.parse( date );
+ } else if ( $.type( date ) === "date" ) {
+ this.dateObject = date;
+ }
+
+ this.dateObject = this.dateObject || new Date();
+};
+
+$.extend( $.ui.date.prototype, {
+
+ setAttributes: function( attributes ) {
+ this.attributes = attributes;
+ this.firstDay = weekdaysRev[ this.attributes.firstDay ];
+ },
+
+ // TODO: Same as the underlying Date object's terminology, but still misleading.
+ // TODO: We can use .setTime() instead of new Date and rename to setTimestamp.
+ setTime: function( time ) {
+ this.dateObject = new Date( time );
+ return this;
+ },
+
+ setDay: function( day ) {
+ var date = this.dateObject;
+ // FIXME: Why not to use .setDate?
+ this.dateObject = new Date( date.getFullYear(), date.getMonth(), day, date.getHours(),
+ date.getMinutes(), date.getSeconds() );
+ return this;
+ },
+
+ setMonth: function( month ) {
+
+ // Overflow example: Month is October 31 (yeah Halloween) and month is changed to April with 30 days,
+ // the new date will me May 1. We will honor the month the user wants to set and if and overflow
+ // occurs, set to last day of month.
+ var date = this.dateObject,
+ days = date.getDate(), year = date.getFullYear();
+ if ( days > this.daysInMonth( year, month ) ) {
+
+ // Overflow
+ days = this.daysInMonth( year, month );
+ }
+ this.dateObject = new Date( year, month, days, date.getHours(),
+ date.getMinutes(), date.getSeconds() );
+ return this;
+ },
+
+ setYear: function( year ) {
+ var date = this.dateObject,
+ day = date.getDate(),
+ month = date.getMonth();
+
+ // Check if Leap, and February and day is 29th
+ if ( this.isLeapYear( year ) && month === 1 && day === 29 ) {
+
+ // set day to last day of February
+ day = this.daysInMonth( year, month );
+ }
+ this.dateObject = new Date( year, month, day, date.getHours(),
+ date.getMinutes(), date.getSeconds() );
+ return this;
+ },
+
+ setFullDate: function( year, month, day ) {
+ this.dateObject = new Date( year, month, day );
+ return this;
+ },
+
+ adjust: function( period, offset ) {
+ var date = this.dateObject,
+ day = period === "D" ? date.getDate() + offset : date.getDate(),
+ month = period === "M" ? date.getMonth() + offset : date.getMonth(),
+ year = period === "Y" ? date.getFullYear() + offset : date.getFullYear();
+
+ // If not day, update the day to the new month and year
+ if ( period !== "D" ) {
+ day = Math.max( 1, Math.min( day, this.daysInMonth( year, month ) ) );
+ }
+ this.dateObject = new Date( year, month, day, date.getHours(),
+ date.getMinutes(), date.getSeconds() );
+ return this;
+ },
+
+ daysInMonth: function( year, month ) {
+ var date = this.dateObject;
+ year = year || date.getFullYear();
+ month = month || date.getMonth();
+ return 32 - new Date( year, month, 32 ).getDate();
+ },
+
+ monthName: function() {
+ return this.attributes.formatMonth( this.dateObject );
+ },
+
+ day: function() {
+ return this.dateObject.getDate();
+ },
+
+ month: function() {
+ return this.dateObject.getMonth();
+ },
+
+ year: function() {
+ return this.dateObject.getFullYear();
+ },
+
+ isLeapYear: function( year ) {
+ year = year || this.dateObject.getFullYear();
+ return new Date( year, 1, 29 ).getMonth() === 1;
+ },
+
+ weekdays: function() {
+ var date,
+ firstDay = this.firstDay,
+ result = [];
+
+ // date = firstDay
+ date = new Date( this.dateObject.getTime() );
+ date.setDate( date.getDate() + firstDay - 1 - date.getDay() );
+
+ for ( var dow = 0; dow < 7; dow++ ) {
+ date.setTime( date.getTime() + 86400000 );
+ result.push({
+ shortname: this.attributes.formatWeekdayShort( date ),
+ fullname: this.attributes.formatWeekdayFull( date )
+ });
+ }
+
+ return result;
+ },
+
+ days: function() {
+ var result = [],
+ today = new $.ui.date( new Date(), this.attributes ),
+ date = this.dateObject,
+ firstDayOfMonth = new Date( this.year(), date.getMonth(), 1 ).getDay(),
+ leadDays = ( firstDayOfMonth - this.firstDay + 7 ) % 7,
+ rows = Math.ceil( ( leadDays + this.daysInMonth() ) / 7 ),
+ printDate = new Date( this.year(), date.getMonth(), 1 - leadDays );
+ for ( var row = 0; row < rows; row++ ) {
+ var week = result[ result.length ] = {
+ number: this.attributes.formatWeekOfYear( printDate ),
+ days: []
+ };
+ for ( var dayx = 0; dayx < 7; dayx++ ) {
+ var day = week.days[ week.days.length ] = {
+ lead: printDate.getMonth() !== date.getMonth(),
+ date: printDate.getDate(),
+ month: printDate.getMonth(),
+ year: printDate.getFullYear(),
+ timestamp: printDate.getTime(),
+ today: today.equal( printDate )
+ };
+ day.render = day.selectable = !day.lead;
+ if ( this.eachDay ) {
+ this.eachDay( day );
+ }
+
+ // TODO use adjust("D", 1)?
+ printDate.setDate( printDate.getDate() + 1 );
+ }
+ }
+ return result;
+ },
+
+ // specialized for multi-month template, could be used in general
+ months: function( add ) {
+ var clone,
+ result = [ this ];
+
+ for ( var i = 0; i < add; i++ ) {
+ clone = this.clone();
+ clone.adjust( "M", i + 1 );
+ result.push( clone );
+ }
+ result[ 0 ].first = true;
+ result[ result.length - 1 ].last = true;
+ return result;
+ },
+
+ clone: function() {
+ var date = this.dateObject;
+ return new $.ui.date( new Date( date.getTime() ), this.attributes );
+ },
+
+ equal: function( other ) {
+ var format = function( date ) {
+ return "" + date.getFullYear() + date.getMonth() + date.getDate();
+ };
+ return format( this.dateObject ) === format( other );
+ },
+
+ date: function() {
+ return this.dateObject;
+ }
+});
+
+return $.ui.date;
+
+} ) );
diff --git a/ui/widgets/calendar.js b/ui/widgets/calendar.js
index 25c1df001..63b09ede3 100644
--- a/ui/widgets/calendar.js
+++ b/ui/widgets/calendar.js
@@ -22,7 +22,7 @@
"globalize",
"globalize/date",
"globalize-locales",
- "date",
+ "../date",
"./button",
"../widget",
"../version",
@@ -78,7 +78,7 @@ return $.widget( "ui.calendar", {
this._setLocale( this.options.locale, this.options.dateFormat );
- this.date = new $.ui.calendarDate( this.options.value, this._calendarDateOptions );
+ this.date = new $.ui.date( this.options.value, this._calendarDateOptions );
this.viewDate = this.date.clone();
this.viewDate.eachDay = this.options.eachDay;