From 6e9f576ea0853a9f8f3d9383ec092c394c9342d1 Mon Sep 17 00:00:00 2001 From: Alex Tironati Date: Fri, 1 Feb 2013 17:07:01 -0500 Subject: [PATCH 1/4] changes to allow past date selection, plus various other improvements and clean up --- javascripts/calendeer.js | 242 +++++++++++++++++++------------- javascripts/day.js | 6 - javascripts/jquery.calendeer.js | 74 ++++++++++ javascripts/month.js | 12 +- javascripts/utils.js | 36 ++++- stylesheets/calendeer.css | 40 +++++- 6 files changed, 296 insertions(+), 114 deletions(-) create mode 100644 javascripts/jquery.calendeer.js diff --git a/javascripts/calendeer.js b/javascripts/calendeer.js index 4c707d3..9738b25 100644 --- a/javascripts/calendeer.js +++ b/javascripts/calendeer.js @@ -27,7 +27,6 @@ $(function(){ date = rightNow; this.el = $( "
", {"class": "calendeers"} ); this.show( date ); - this.toggleFocused( "start" ); this.setupHandlers(); this.handleOptions( this.options ); var noon = new Date(); @@ -38,6 +37,7 @@ $(function(){ this.setTime("start", noon, false ); this.setTime("end", noon, false ); this.preload(); + this.toggleFocused( "start", false ); }, get: function( type ) { if ( Utils.isDate( this.dates[type] ) && @@ -47,7 +47,11 @@ $(function(){ return; }, set: function( type, date ) { - if ( Utils.isDate(date) && this.validateDate(date, type) ) { + if ( Utils.isDate(date) ) { + this.setDate(type, date); + if ( this.options.timeSupport ) { this.setTime(type, date); } + } else if( typeof date === "number") { + date = new Date( date ); this.setDate(type, date); if ( this.options.timeSupport ) { this.setTime(type, date); } } @@ -92,9 +96,25 @@ $(function(){ self.setDate( self.focused, date ); } ); + + var that = this; + this.el.on( "mouseenter", function( event ) { + var clazzes = that.el.attr("class"); + + if (clazzes.indexOf( "start-focus" ) !== -1) { + $( that.options.startInput ).addClass( "calendeer-focused-input-start" ); + } else { + $( that.options.endInput ).addClass( "calendeer-focused-input-end" ); + } + } ); + this.el.on( "mouseleave", function( event ) { + $( that.options.startInput ).removeClass( "calendeer-focused-input-start" ); + $( that.options.endInput ).removeClass( "calendeer-focused-input-end" ); + } ); + this.el.on( "mouseenter", ".calendeer-day", function( event ) { var data = $( this ).data( "calendeer" ); - if ( ! data.isPast() ) data.el.addClass( "hovered" ); + data.el.addClass( "hovered" ); } ); this.el.on( "mouseleave", ".calendeer-day", function( event ) { $( this ).data( "calendeer" ).el.removeClass( "hovered" ); @@ -109,10 +129,9 @@ $(function(){ var $input, existingDate; if ( this.options.startInput ) { $input = $( this.options.startInput ); - existingDate = Date.parse( $input.val() ); - if (! isNaN(existingDate) ) { - existingDate = new Date( existingDate ); - this.set( "start", existingDate ); + existingDate = Date.create( $input.val() ); + if ( existingDate.isValid() ) { + this.set( "start", Date.parse(existingDate) ); } } if ( this.options.endInput ) { @@ -141,10 +160,10 @@ $(function(){ date = new Date( isValid ); } + isValid = isValid && Utils.validateDateIsInAcceptableRange( date ); + if ( isValid ) { data.scope.setDate( data.type, Utils.trimDate(date), true ); - } else { - data.scope.clearDates( data.type, true ); } }, inputTimeHandler: function( event ) { @@ -181,6 +200,7 @@ $(function(){ $input.val( date ); } } ); + $input.on( "keyup.calendeer." + type, { type: type, scope: this }, this.inputTimeHandler ); $input.on( "focus.calendeer." + type, { type: type, scope: this }, $.proxy( function(e) { this.toggleTimeFocused(e.data.type); @@ -204,7 +224,7 @@ $(function(){ $input.on( "keyup.calendeer." + type, { type: type, scope: this }, this.inputHandler ); $input.on( "focus.calendeer." + type, { type: type, scope: this }, $.proxy( function(e) { - this.toggleFocused(e.data.type); + this.toggleFocused(e.data.type, false ); this.show( e.data.type ); }, this ) ); }, @@ -237,49 +257,118 @@ $(function(){ } }, getCalendar: function( date ) { - var diff; - if ( ! App.Utils.isDate(date) && typeof date === "number" ) { - diff = date; - date = App.Utils.addMonth( rightNow, diff ); - } else { - diff = App.Utils.monthDiff( rightNow, date ); + var hashKey = ""; + if ( ! Utils.isDate(date) && typeof date === "number" ) { + date = Utils.addMonth( rightNow, date ); + hashKey = Utils.generateMonthHashKey( date ); + } else if( typeof date === "string" ) { + hashKey = date; } - if ( diff >= 0 && - (this.options.maxCalendars === 0 || diff < this.options.maxCalendars) ) { - if ( this.Calendars[diff] ) { - return this.Calendars[ diff ]; - } else { - var calendar = this.Calendars[ diff ] = new App.Calendar(date); - calendar.attach.apply( calendar, this.attachmentPoint(diff) ); - return calendar; - } + + var hashEntry = this.Calendars[ hashKey ]; + + // check if element exists in hash already, otherwise + // create it in the key value store + if ( hashEntry ) { + return hashEntry; + } else { + // create and insert into hash + hashYear = parseInt( hashKey.substring(0, 4), 10); + hashMonth = parseInt( hashKey.substring(4) , 10); + var calendar = this.Calendars[ hashKey ] = new App.Calendar(hashMonth, hashYear); + // insert into DOM + calendar.attach.apply(calendar, this.attachmentPoint( calendar.dateObject )); + return calendar; } throw new Error( "get fail" ); }, - attachmentPoint: function( diff ) { + attachmentPoint: function( date ) { var attachment; - while( diff-- && attachment === undefined ) { - attachment = this.Calendars[diff]; + + + var firstDOMMonth = this.el.children(":first"); + + // if no DOM element exists, we can just attach as child of calendeers div + if ( firstDOMMonth.length === 0 ){ + return [ this.el , "prepend" ]; } - if ( attachment === undefined ) { - return [ this.el ]; - } else { - return [ attachment.el, true ]; + + // if this month is before the first DOM element, insert before that element + var dateComparison = Utils.dateComparator( + date, firstDOMMonth.data('calendeer').dateObject + ); + if (dateComparison < 0) { + return [ this.el, "prepend" ]; + } else if ( dateComparison === 0) { + // don't attach; this is handled by Calendar.attach + return undefined; + } + + var lastDOMMonth = this.el.children(":last"); + + dateComparison = Utils.dateComparator( + date, lastDOMMonth.data('calendeer').dateObject + ); + if ( dateComparison === 0) { + // this is a special case, because the element we are trying to place, + // when it is created, is placed at the end of the month elements. So + // if the elements are for the same month, we actually want to use the + // one before this element because it is the actual last month in the DOM + lastDOMMonth = lastDOMMonth.prev(); + } + + // if this month is after the last DOM element, insert after that element + dateComparison = Utils.dateComparator( + date, lastDOMMonth.data('calendeer').dateObject + ); + if (dateComparison > 0) { + return [ this.el , "append" ]; + } else if ( dateComparison === 0 ) { + // don't attach; this is handled by Calendar.attach + return undefined; + } + + // otherwise, find most recent month before the current month, + // and use that as an attachment point + while( attachment === undefined ) { + var currKey = Utils.hashKeyByMonthDiff( date, -1 ); + date = Utils.addMonth( date, -1 ); + attachment = this.Calendars[ currKey ] } + + return [ attachment.el, "sibling" ]; }, - toggleFocused: function( focused ) { + toggleFocused: function( focused, addHighlighting ) { if ( focused !== "start" && focused !== "end" ) { focused = this.focused === "start" ? "end" : "start"; } if ( focused === "end" ) { - $( this.options.endInput ).addClass( "calendeer-focused-input" ); $( this.options.startInput ).removeClass( "calendeer-focused-input" ); + $( this.options.endInput ).addClass( "calendeer-focused-input" ); + + if ( addHighlighting ) { + $( this.options.startInput ).removeClass( "calendeer-focused-input-start" ); + $( this.options.endInput ).addClass( "calendeer-focused-input-end" ); + } else { + $( this.options.startInput ).removeClass( "calendeer-focused-input-start" ); + $( this.options.endInput ).removeClass( "calendeer-focused-input-end" ); + } + this.focused = "end"; this.el.addClass( "end-focus" ); this.el.removeClass( "start-focus" ); } else { - $( this.options.startInput ).addClass( "calendeer-focused-input" ); - $( this.options.endInput ).removeClass( "calendeer-focused-input" ); + $( this.options.startInput ).addClass( "calendeer-focused-input" ); + $( this.options.endInput ).removeClass( "calendeer-focused-input" ); + + if ( addHighlighting ) { + $( this.options.endInput ).removeClass( "calendeer-focused-input-end" ); + $( this.options.startInput ).addClass( "calendeer-focused-input-start" ); + } else { + $( this.options.endInput ).removeClass( "calendeer-focused-input-end" ); + $( this.options.startInput ).removeClass( "calendeer-focused-input-start" ); + } + this.focused = "start"; this.el.addClass( "start-focus" ); this.el.removeClass( "end-focus" ); @@ -321,34 +410,20 @@ $(function(){ return this; } } - if ( App.Utils.isDate(date) ) { - var diff = App.Utils.monthDiff( rightNow, date ); - if ( diff < 0 || (this.options.maxCalendars !== 0 && diff >= this.options.maxCalendars) ) { - return this; - } else { - if ( diff < index ) { - index = diff; - } else { - if ( this.options.maxCalendars ) { - if ( this.options.numberOfCalendars > this.options.maxCalendars - diff ) { - index = this.options.numberOfCalendars - this.options.maxCalendars + diff; - } - } - } - } + if ( Utils.isDate(date) ) { this.hide(); var numCalendars = -1, showIndex; this.visibleIndexes = []; while( ++numCalendars < this.options.numberOfCalendars ) { - showIndex = diff - index + numCalendars; + showIndex = Utils.hashKeyByMonthDiff( date, numCalendars - index ); this.visibleIndexes.push( showIndex ); calendar = this.getCalendar( showIndex ); calendar.show(); - calendar.togglePreviousButton( numCalendars === 0 && - showIndex !== 0 ); + calendar.togglePreviousButton( + numCalendars === 0 + ); calendar.toggleNextButton( - numCalendars === this.options.numberOfCalendars - 1 && - showIndex !== this.options.maxCalendars - 1 + numCalendars === this.options.numberOfCalendars - 1 ); } this.drawState( this.dates.start, this.dates.end ); @@ -368,23 +443,6 @@ $(function(){ } return this; }, - clearDates: function( type, fromHandler ) { - if ( typeof type === "string" && this.dates[type] !== undefined ) { - type = type.toLowerCase(); - this.dates[type] = null; - if ( type !== "start" && type !== "end" ) { - delete this.dates[type]; - } else { - this.el.removeClass( type + "-date" ); - this.emitEvent( "setDate", [type, null, fromHandler] ); - this.drawState( this.dates.start, this.dates.end ); - } - } else { - this.dates.start = null; - this.dates.end = null; - this.drawState( this.dates.start, this.dates.end ); - } - }, clearTimes: function( type, fromHandler ) { if ( typeof type === "string" && this.dates[type] !== undefined ) { type = type.toLowerCase(); @@ -401,38 +459,20 @@ $(function(){ this.drawState( this.dates.start, this.dates.end ); } }, - validateDate: function( date, type ) { - var dateConditions = Utils.isDate( date ), - futureConditions = ( this.options.maxCalendars !== 0 ? - Utils.monthDiff( this.dates.today, date ) < this.options.maxCalendars : - true ), - pastConditions = Utils.dateTimeComparator( date, this.dates.today ) + 1; - - return !! ( dateConditions && - futureConditions && - pastConditions ); - }, setDate: function( type, date, fromHandler ) { if ( typeof type !== "string" || ( ! Utils.isDate(date) && date != undefined ) ) { throw new Error( "setDate invalid arguments" ); } type = type.toLowerCase(); - if ( ! this.validateDate( date, type ) ) return this; this.dates[ type ] = date; this.el.addClass( type + "-date" ); if ( type === "start" ) { - if ( this.dates.end && Utils.dateComparator(date,this.dates.end)===1 ) { - this.clearDates( "end" ); - } if ( Utils.isDate(date) && ! this.isVisible(date) ) { this.show( date, 0 ); } this.drawState( this.dates.start, this.dates.end ); } else if ( type === "end" ) { - if ( this.dates.start && Utils.dateComparator(date,this.dates.start)===-1 ) { - this.clearDates( "start" ); - } if ( Utils.isDate(date) && ! this.isVisible(date) ) { this.show( date, this.options.numberOfCalendars - 1 ); } @@ -444,7 +484,7 @@ $(function(){ this.emitEvent( "setDateTime", [type, Utils.toISO(dateTime), dateTime] ); } if ( ! fromHandler ) { - this.toggleFocused(); + this.toggleFocused( undefined, true ); } return this; }, @@ -454,7 +494,6 @@ $(function(){ throw new Error( "setTime invalid arguments" ); } type = type.toLowerCase(); - // if ( ! this.validateDate( date, type ) ) return this; this.times[ type ] = date; this.el.addClass( type + "-time" ); this.emitEvent( "setTime", [type, date, fromHandler] ); @@ -472,7 +511,9 @@ $(function(){ if ( isNaN(steps) ) { steps = 1; } - this.show( this.getCalendar( this.visibleIndexes[0] + steps ).dateObject, 0 ); + var thisDate = this.Calendars[ this.visibleIndexes[0] ].dateObject; + var nextMonthHashKey = Utils.hashKeyByMonthDiff( thisDate, steps ); + this.show( this.getCalendar( nextMonthHashKey ).dateObject, 0 ); }, nextPage: function() { this.next( this.options.numberOfCalendars ); @@ -483,14 +524,20 @@ $(function(){ steps = 1; } var last = this.visibleIndexes.length - 1; - this.show( this.getCalendar( this.visibleIndexes[ last ] - steps ).dateObject, last ); + var thisDate = this.Calendars[ this.visibleIndexes[last] ].dateObject; + var prevMonthHashKey = Utils.hashKeyByMonthDiff( thisDate, -steps ); + this.show( this.getCalendar( prevMonthHashKey ).dateObject, last ); }, previousPage: function() { this.previous( this.options.numberOfCalendars ); }, isVisible: function( date ) { - var diff = Utils.monthDiff( rightNow, date ); - return !!( ~$.inArray(diff, this.visibleIndexes) ); + // if date is a date object, must convert it to a hash key + if ( Utils.isDate(date) ) { + date = Utils.generateMonthHashKey( date ); + } + // otherwise just use the given hash key, assuming it is a string + return !!( ~$.inArray(date, this.visibleIndexes) ); }, callOnVisibles: function() { if ( ! arguments.length ) { @@ -523,7 +570,6 @@ $(function(){ endInput: null, eventDelegate: null, numberOfCalendars: 2, - maxCalendars: 0, timeSupport: true, useSugar: typeof (new Date()).isValid === "function" }; diff --git a/javascripts/day.js b/javascripts/day.js index 295f7d5..1860770 100644 --- a/javascripts/day.js +++ b/javascripts/day.js @@ -56,9 +56,6 @@ $(function(){ "data-date": day, "data": { "calendeer": this } } ); - if ( self.isPast() ) { - self.el.addClass( confs.classes.past ); - } if ( self.isToday() ) { self.el.addClass( confs.classes.today ); } @@ -70,9 +67,6 @@ $(function(){ isToday: function() { return this.props.today; }, _setState: function( startDate, endDate ) { var flag; - if ( this.isPast() ) { - return this; - } if ( Utils.isDate(startDate) || Utils.isDate(endDate) ) { flag = Utils.rangeComparator( this.dateObject, startDate, endDate ); diff --git a/javascripts/jquery.calendeer.js b/javascripts/jquery.calendeer.js new file mode 100644 index 0000000..64eb1cf --- /dev/null +++ b/javascripts/jquery.calendeer.js @@ -0,0 +1,74 @@ +$(function() { + + $.fn.calendeerWidget = function( options ){ + return this.each( function(){ + var opts = $.extend( {}, options ); + init( "calendeer_start_input", "calendeer_end_input" ); + } ); + }; + + var init = function( startClass, endClass ){ + var $startInput = $("." + startClass), + $endInput = $("." + endClass), + $startTimeInput, + $endTimeInput, + startName = $startInput.attr( "name" ), + endName = $endInput.attr( "name" ), + $startHidden = $( '' ).attr( { + name: startName, + id: startClass + } ), + $endHidden = $( '' ).attr( { + name: endName, + id: endClass + } ); + + $startInput.attr( "class", startClass + "_calendeer" ).removeAttr( "name" ); + $endInput.attr( "class", endClass + "_calendeer" ).removeAttr( "name" ); + $startTimeInput = $startInput.clone().attr( "class", startClass + "_time_calendeer" ); + $endTimeInput = $endInput.clone().attr( "class", endClass + "_time_calendeer" ); + + $startInput.after( $startTimeInput ).after( $startHidden ); + $endInput.after( $endTimeInput ).after( $endHidden ); + + // pass inputs to Calendeer object + var calendeer = new App.Calendeer( { + startInput: $startInput, + startTimeInput: $startTimeInput, + endInput: $endInput, + endTimeInput: $endTimeInput + } ); + + // update the hidden input's time representation on every setDateTime call + $(document).bind( "setDateTime", function( e, type, isoDate, dateObject ) { + if ( type === "start" ) { + $startHidden.val( isoDate ); + } else if ( type === "end" ) { + $endHidden.val( isoDate ); + } + } ); + + calendeer.el.insertAfter( $endTimeInput ); + calendeer.clearEventQueue(); + + // hide Calendeer unless one of the four inputs is selected + $(document).delegate(':input', 'focus', function() { + var ae = document.activeElement; + var focusedClasses = ae.className; + var inputClasses = [ startClass + "_calendeer", + endClass + "_calendeer", + startClass + "_time_calendeer", + endClass + "_time_calendeer" ]; + var showCalendeer = false; + + $.each( inputClasses, function( i, cl ) { + showCalendeer = showCalendeer || ( focusedClasses.indexOf( cl ) !== -1 ); + }); + + showCalendeer ? calendeer.el.slideDown() : calendeer.el.slideUp(); + }); + + calendeer.el.hide(); + } + +}); diff --git a/javascripts/month.js b/javascripts/month.js index 1a43f24..dd9ec65 100644 --- a/javascripts/month.js +++ b/javascripts/month.js @@ -45,11 +45,11 @@ $(function(){ } else if ( typeof month === "string" && ~$.inArray(month.toLowerCase(), months) ) { this.month = $.inArray(month.toLowerCase(), months); } else { - throw new CalendarError( "Invalid month in constructor" ); + throw new CalendarError( "Invalid month in constructor" + month); } this.name = this._names.en[ this.month ]; this.daysInMonth = (function(){ - month = self.month === 11 ? 0 : self.month + 1; + month = (self.month + 1) % 11; year = self.month === 11 ? self.year + 1 : self.year; return ( new Date( year, month, 0 ) ).getDate(); })(); @@ -144,14 +144,16 @@ $(function(){ $(".calendeers").append( e.calendeer ); }, - attach: function( $el, sibling ) { + attach: function( $el, type ) { if ( ! this.el ) { return this; } - if ( sibling ) { + if ( type === "sibling" ) { this.el.insertAfter( $el ); - } else { + } else if ( type === "prepend" ) { this.el.prependTo( $el ); + } else if ( type === "append" ) { + this.el.appendTo( $el ); } return this; }, diff --git a/javascripts/utils.js b/javascripts/utils.js index 7686e94..16763ed 100644 --- a/javascripts/utils.js +++ b/javascripts/utils.js @@ -54,6 +54,7 @@ if ( isNaN(months) ) { throw new UtilsError( "addMonth requires an integer" ); } + // TODO: try to remove this if if ( ! this.isDate(date) ) { date = this.rightNow; } @@ -77,6 +78,19 @@ isDate: function( date ) { return typeof date === "object" && date instanceof Date; }, + validateDateIsInAcceptableRange: function( date ) { + minDate = new Date( 1806, 5, 30); // Andrew Jackson kills a man in a duel after the man had accused Jackson's wife of bigamy + maxDate = new Date( 2220, 1, 1); // Date that 'mind uploading' is perfected and used extenisvely in global rewilding efforts + + compareOne = (Utils.dateComparator( date, minDate ) >= 0); + compareTwo = (Utils.dateComparator( date, minDate ) >= 0); + + if (compareOne && compareTwo) { + return true; + } else { + return false; + } + }, dateTimeComparator: function( firstDate, secondDate ) { if ( ! this.isDate(firstDate) || ! this.isDate(secondDate) ) { throw new DayError( "Date comparator failed -- invalid date object" ); @@ -143,6 +157,26 @@ } return dateArray; }, + convertToStringHashKey: function ( year, month ) { + var zeroPadMonth = "0" + month.toString(); + var zeroPadMonth = zeroPadMonth.substring(zeroPadMonth.length - 2); + return (year.toString() + zeroPadMonth); + }, + hashKeyByMonthDiff: function( date, monthDiff ) { + return Utils.generateMonthHashKey( + Utils.addMonth( date, monthDiff ) + ); + }, + generateMonthHashKey: function( date ) { + if (Utils.isDate( date )) { + var year = date.getFullYear(); + var month = date.getMonth(); + } else { + var year = date[ "year" ]; + var month = date[ "month" ]; + } + return Utils.convertToStringHashKey(year, month); + }, toUTCArray: function( date, params ) { var dateArray = [ date.getUTCFullYear(), @@ -171,4 +205,4 @@ window.App = window.App || {}; window.App.Utils = Utils; -})(); +})(); \ No newline at end of file diff --git a/stylesheets/calendeer.css b/stylesheets/calendeer.css index f932b23..e94f8fc 100644 --- a/stylesheets/calendeer.css +++ b/stylesheets/calendeer.css @@ -4,6 +4,8 @@ text-align: center; overflow: hidden; width: 410px; + margin-left: 180px; + margin-top: 15px; } .calendeer { @@ -77,21 +79,21 @@ .calendeer-day.start-date, .calendeers.start-focus .calendeer-day.hovered, .calendeers.start-focus.end-date .after-date.hovered { - background-color: #e39937; + background-color: #3bd521; color: white; } .calendeer-day.end-date, .calendeers.end-focus .calendeer-day.hovered, .calendeers.end-focus.start-date .before-date.hovered { - background-color: #3bd521; + background-color: #e39937; color: white; } .calendeer-day.start-end-date, .calendeers.start-focus .calendeer-day.end-date.hovered, .calendeers.end-focus .calendeer-day.start-date.hovered { - background: url(../images/start-end-date.gif) 50% 50% no-repeat; + background: url(data:image/gif;base64,R0lGODdhFwAQAIQBAOKZN+OZN+CaN9edNeGaN96bNtycNtGgNb6mMsijM8WkM7OqMZ6xLqKwL6avL4+3LJC3LIG8Kni/KWzEJ1nKJVPMJF7JJlLNJEnQI0PSIkrQIz7UITvVIeOZN+OZN+OZNywAAAAAFwAQAAAFUyAnjmRpUoqpqg4grDBXHUHwxiYE1AGBk5oEr+b7cSKCIfGXQSh5ANzE8ITCNovqMKqyDLRbFWMHtpIutHJ49CCrzRjhWxmVFOZPQAPA7/v/gAQhADs=) 50% 50% no-repeat; color: white; } @@ -104,4 +106,34 @@ .calendeers.start-focus.end-date .after-date { background-color: #dedede; color: gray; -} \ No newline at end of file +} + +.calendeer_start_input_calendeer { + min-width: auto !important; + width: 150px !important; + margin-right: 5px; +} + +.calendeer_end_input_calendeer { + min-width: auto !important; + width: 150px !important; + margin-right: 5px; +} + +.calendeer_start_input_time_calendeer { + min-width: auto !important; + width: 150px !important; +} + +.calendeer_end_input_time_calendeer { + min-width: auto !important; + width: 150px !important; +} + +.calendeer-focused-input-start { + border: 1px solid #3bd521 !important; +} + +.calendeer-focused-input-end { + border: 1px solid #e39937 !important; +} From 379c64aa00e47b669a2bfad47d0f3fa24235c4e3 Mon Sep 17 00:00:00 2001 From: Alex Tironati Date: Tue, 5 Feb 2013 16:27:59 -0500 Subject: [PATCH 2/4] switch to using Utils.pad, fix jingings --- javascripts/utils.js | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/javascripts/utils.js b/javascripts/utils.js index 16763ed..96fe293 100644 --- a/javascripts/utils.js +++ b/javascripts/utils.js @@ -157,11 +157,6 @@ } return dateArray; }, - convertToStringHashKey: function ( year, month ) { - var zeroPadMonth = "0" + month.toString(); - var zeroPadMonth = zeroPadMonth.substring(zeroPadMonth.length - 2); - return (year.toString() + zeroPadMonth); - }, hashKeyByMonthDiff: function( date, monthDiff ) { return Utils.generateMonthHashKey( Utils.addMonth( date, monthDiff ) @@ -172,10 +167,10 @@ var year = date.getFullYear(); var month = date.getMonth(); } else { - var year = date[ "year" ]; - var month = date[ "month" ]; + var year = date.year; + var month = date.month; } - return Utils.convertToStringHashKey(year, month); + return (year.toString() + Utils.pad( month, 2, 0)).toString(); }, toUTCArray: function( date, params ) { var dateArray = [ From 6e7663ce0553af566828ee5d4ef2634505fee597 Mon Sep 17 00:00:00 2001 From: Alex Tironati Date: Wed, 6 Feb 2013 16:38:32 -0500 Subject: [PATCH 3/4] use Utils.pad, change attachment fucntions to use better syntax, add in calendeer.js --- javascripts/application.js | 412 +++++++++++++++++++++---------------- javascripts/calendeer.js | 43 ++-- javascripts/month.js | 14 +- 3 files changed, 265 insertions(+), 204 deletions(-) diff --git a/javascripts/application.js b/javascripts/application.js index d34bb4c..fb0fb3a 100644 --- a/javascripts/application.js +++ b/javascripts/application.js @@ -164,6 +164,7 @@ do{e=a.indexOf(c.charAt(l++));g=a.indexOf(c.charAt(l++));i=a.indexOf(c.charAt(l+ if ( isNaN(months) ) { throw new UtilsError( "addMonth requires an integer" ); } + // TODO: try to remove this if if ( ! this.isDate(date) ) { date = this.rightNow; } @@ -187,6 +188,19 @@ do{e=a.indexOf(c.charAt(l++));g=a.indexOf(c.charAt(l++));i=a.indexOf(c.charAt(l+ isDate: function( date ) { return typeof date === "object" && date instanceof Date; }, + validateDateIsInAcceptableRange: function( date ) { + minDate = new Date( 1806, 5, 30); // Andrew Jackson kills a man in a duel after the man had accused Jackson's wife of bigamy + maxDate = new Date( 2220, 1, 1); // Date that 'mind uploading' is perfected and used extenisvely in global rewilding efforts + + compareOne = (Utils.dateComparator( date, minDate ) >= 0); + compareTwo = (Utils.dateComparator( date, minDate ) >= 0); + + if (compareOne && compareTwo) { + return true; + } else { + return false; + } + }, dateTimeComparator: function( firstDate, secondDate ) { if ( ! this.isDate(firstDate) || ! this.isDate(secondDate) ) { throw new DayError( "Date comparator failed -- invalid date object" ); @@ -253,6 +267,21 @@ do{e=a.indexOf(c.charAt(l++));g=a.indexOf(c.charAt(l++));i=a.indexOf(c.charAt(l+ } return dateArray; }, + hashKeyByMonthDiff: function( date, monthDiff ) { + return Utils.generateMonthHashKey( + Utils.addMonth( date, monthDiff ) + ); + }, + generateMonthHashKey: function( date ) { + if (Utils.isDate( date )) { + var year = date.getFullYear(); + var month = date.getMonth(); + } else { + var year = date.year; + var month = date.month; + } + return (year.toString() + Utils.pad( month, 2, 0)).toString(); + }, toUTCArray: function( date, params ) { var dateArray = [ date.getUTCFullYear(), @@ -281,8 +310,7 @@ do{e=a.indexOf(c.charAt(l++));g=a.indexOf(c.charAt(l++));i=a.indexOf(c.charAt(l+ window.App = window.App || {}; window.App.Utils = Utils; -})(); -$(function(){ +})();$(function(){ var confs = { prefix: "calendeer", classes: { @@ -329,11 +357,11 @@ $(function(){ } else if ( typeof month === "string" && ~$.inArray(month.toLowerCase(), months) ) { this.month = $.inArray(month.toLowerCase(), months); } else { - throw new CalendarError( "Invalid month in constructor" ); + throw new CalendarError( "Invalid month in constructor" + month); } this.name = this._names.en[ this.month ]; this.daysInMonth = (function(){ - month = self.month === 11 ? 0 : self.month + 1; + month = (self.month + 1) % 11; year = self.month === 11 ? self.year + 1 : self.year; return ( new Date( year, month, 0 ) ).getDate(); })(); @@ -426,16 +454,18 @@ $(function(){ this.el = e.calendeer; $(".calendeers").append( e.calendeer ); - }, - attach: function( $el, sibling ) { + attach: function( $el, type ) { if ( ! this.el ) { return this; } - if ( sibling ) { - this.el.insertAfter( $el ); - } else { - this.el.prependTo( $el ); + var conditions = { + sibling: this.el.insertAfter, + prepend: this.el.prependTo, + append: this.el.appendTo + }; + if (conditions[type]) { + conditions[type].call( this.el, $el); } return this; }, @@ -535,9 +565,6 @@ $(function(){ "data-date": day, "data": { "calendeer": this } } ); - if ( self.isPast() ) { - self.el.addClass( confs.classes.past ); - } if ( self.isToday() ) { self.el.addClass( confs.classes.today ); } @@ -549,9 +576,6 @@ $(function(){ isToday: function() { return this.props.today; }, _setState: function( startDate, endDate ) { var flag; - if ( this.isPast() ) { - return this; - } if ( Utils.isDate(startDate) || Utils.isDate(endDate) ) { flag = Utils.rangeComparator( this.dateObject, startDate, endDate ); @@ -608,7 +632,6 @@ $(function(){ date = rightNow; this.el = $( "
", {"class": "calendeers"} ); this.show( date ); - this.toggleFocused( "start" ); this.setupHandlers(); this.handleOptions( this.options ); var noon = new Date(); @@ -618,6 +641,9 @@ $(function(){ noon.setMilliseconds(0); this.setTime("start", noon, false ); this.setTime("end", noon, false ); + this.preload(); + this.toggleFocused( "start" ); + this.removeInputHighlighting(); }, get: function( type ) { if ( Utils.isDate( this.dates[type] ) && @@ -626,7 +652,16 @@ $(function(){ } return; }, - set: function( type, date ) {}, + set: function( type, date ) { + if ( Utils.isDate(date) ) { + this.setDate(type, date); + if ( this.options.timeSupport ) { this.setTime(type, date); } + } else if( typeof date === "number") { + date = new Date( date ); + this.setDate(type, date); + if ( this.options.timeSupport ) { this.setTime(type, date); } + } + }, handleOptions: function( options ) { var self = this, actions = { @@ -667,9 +702,25 @@ $(function(){ self.setDate( self.focused, date ); } ); + + var that = this; + this.el.on( "mouseenter", function( event ) { + var clazzes = that.el.attr("class"); + + if (clazzes.indexOf( "start-focus" ) !== -1) { + $( that.options.startInput ).addClass( "calendeer-focused-input-start" ); + } else { + $( that.options.endInput ).addClass( "calendeer-focused-input-end" ); + } + } ); + this.el.on( "mouseleave", function( event ) { + $( that.options.startInput ).removeClass( "calendeer-focused-input-start" ); + $( that.options.endInput ).removeClass( "calendeer-focused-input-end" ); + } ); + this.el.on( "mouseenter", ".calendeer-day", function( event ) { var data = $( this ).data( "calendeer" ); - if ( ! data.isPast() ) data.el.addClass( "hovered" ); + data.el.addClass( "hovered" ); } ); this.el.on( "mouseleave", ".calendeer-day", function( event ) { $( this ).data( "calendeer" ).el.removeClass( "hovered" ); @@ -680,6 +731,24 @@ $(function(){ e.preventDefault(); } ); }, + preload: function() { + var $input, existingDate; + if ( this.options.startInput ) { + $input = $( this.options.startInput ); + existingDate = Date.create( $input.val() ); + if ( existingDate.isValid() ) { + this.set( "start", Date.parse(existingDate) ); + } + } + if ( this.options.endInput ) { + $input = $( this.options.endInput ); + existingDate = Date.parse( $input.val() ); + if (! isNaN(existingDate) ) { + existingDate = new Date( existingDate ); + this.set( "end", existingDate ); + } + } + }, inputHandler: function( event ) { var date, isValid, data = event.data, @@ -697,10 +766,10 @@ $(function(){ date = new Date( isValid ); } + isValid = isValid && Utils.validateDateIsInAcceptableRange( date ); + if ( isValid ) { data.scope.setDate( data.type, Utils.trimDate(date), true ); - } else { - data.scope.clearDates( data.type, true ); } }, inputTimeHandler: function( event ) { @@ -737,6 +806,7 @@ $(function(){ $input.val( date ); } } ); + $input.on( "keyup.calendeer." + type, { type: type, scope: this }, this.inputTimeHandler ); $input.on( "focus.calendeer." + type, { type: type, scope: this }, $.proxy( function(e) { this.toggleTimeFocused(e.data.type); @@ -752,67 +822,143 @@ $(function(){ this.el.bind( "setDate", { type: type }, function( e, type, date, suppress ) { if ( type === e.data.type && ! suppress ) { if ( useSugar && Utils.isDate(date) && date.isValid() ) { - date = date.short(); + date = date.format( "{Month} {date}, {year}" ); } $input.val( date ); } } ); + $input.on( "keyup.calendeer." + type, { type: type, scope: this }, this.inputHandler ); $input.on( "focus.calendeer." + type, { type: type, scope: this }, $.proxy( function(e) { - this.toggleFocused(e.data.type); + this.toggleFocused( e.data.type ); this.show( e.data.type ); }, this ) ); }, attach: function( $el ) { if ( this.el ) { this.el.appendTo( $el ); + this.clearEventQueue(); } return this; }, - getCalendar: function( date ) { - var diff; - if ( ! App.Utils.isDate(date) && typeof date === "number" ) { - diff = date; - date = App.Utils.addMonth( rightNow, diff ); + clearEventQueue: function() { + if ( this._eventQueue ) { + var currentEvent; + while ( currentEvent = this._eventQueue.shift() ) { + this.emitEvent( currentEvent[0], currentEvent[1] ); + } + delete this._eventQueue; + } + return this; + }, + emitEvent: function( eventType, args ) { + if ( this.el.parent().length ) { + this.emitEvent = function( _eventType, _args ) { + this.el.trigger( _eventType, _args ); + }; + this.emitEvent( eventType, args ); } else { - diff = App.Utils.monthDiff( rightNow, date ); + this._eventQueue = this._eventQueue || []; + this._eventQueue.push( [eventType, args] ); } - if ( diff >= 0 && - (this.options.maxCalendars === 0 || diff < this.options.maxCalendars) ) { - if ( this.Calendars[diff] ) { - return this.Calendars[ diff ]; - } else { - var calendar = this.Calendars[ diff ] = new App.Calendar(date); - calendar.attach.apply( calendar, this.attachmentPoint(diff) ); - return calendar; - } + }, + getCalendar: function( date ) { + var hashKey = ""; + if ( ! Utils.isDate(date) && typeof date === "number" ) { + date = Utils.addMonth( rightNow, date ); + hashKey = Utils.generateMonthHashKey( date ); + } else if( typeof date === "string" ) { + hashKey = date; + } + + var hashEntry = this.Calendars[ hashKey ]; + + // check if element exists in hash already, otherwise + // create it in the key value store + if ( hashEntry ) { + return hashEntry; + } else { + // create and insert into hash + hashYear = parseInt( hashKey.substring(0, 4), 10); + hashMonth = parseInt( hashKey.substring(4) , 10); + var calendar = this.Calendars[ hashKey ] = new App.Calendar(hashMonth, hashYear); + // insert into DOM + calendar.attach.apply(calendar, this.attachmentPoint( calendar.dateObject )); + return calendar; } throw new Error( "get fail" ); }, - attachmentPoint: function( diff ) { + attachmentPoint: function( date ) { var attachment; - while( diff-- && attachment === undefined ) { - attachment = this.Calendars[diff]; + + + var firstDOMMonth = this.el.children(":first"); + + // if no DOM element exists, we can just attach as child of calendeers div + if ( firstDOMMonth.length === 0 ){ + return [ this.el , "prepend" ]; } - if ( attachment === undefined ) { - return [ this.el ]; - } else { - return [ attachment.el, true ]; + + // if this month is before the first DOM element, insert before that element + var dateComparison = Utils.dateComparator( + date, firstDOMMonth.data('calendeer').dateObject + ); + if (dateComparison < 0) { + return [ this.el, "prepend" ]; + } else if ( dateComparison === 0) { + // don't attach; this is handled by Calendar.attach + return undefined; } + + var lastDOMMonth = this.el.children(":last"); + + dateComparison = Utils.dateComparator( + date, lastDOMMonth.data('calendeer').dateObject + ); + if ( dateComparison === 0) { + // this is a special case, because the element we are trying to place, + // when it is created, is placed at the end of the month elements. So + // if the elements are for the same month, we actually want to use the + // one before this element because it is the actual last month in the DOM + lastDOMMonth = lastDOMMonth.prev(); + } + + // if this month is after the last DOM element, insert after that element + dateComparison = Utils.dateComparator( + date, lastDOMMonth.data('calendeer').dateObject + ); + if (dateComparison > 0) { + return [ this.el , "append" ]; + } else if ( dateComparison === 0 ) { + // don't attach; this is handled by Calendar.attach + return undefined; + } + + // otherwise, find most recent month before the current month, + // and use that as an attachment point + while( attachment === undefined ) { + var currKey = Utils.hashKeyByMonthDiff( date, -1 ); + date = Utils.addMonth( date, -1 ); + attachment = this.Calendars[ currKey ] + } + + return [ attachment.el, "sibling" ]; }, toggleFocused: function( focused ) { if ( focused !== "start" && focused !== "end" ) { focused = this.focused === "start" ? "end" : "start"; } if ( focused === "end" ) { - $( this.options.endInput ).addClass( "calendeer-focused-input" ); $( this.options.startInput ).removeClass( "calendeer-focused-input" ); + $( this.options.endInput ).addClass( "calendeer-focused-input" ); + this.focused = "end"; this.el.addClass( "end-focus" ); this.el.removeClass( "start-focus" ); } else { - $( this.options.startInput ).addClass( "calendeer-focused-input" ); - $( this.options.endInput ).removeClass( "calendeer-focused-input" ); + $( this.options.startInput ).addClass( "calendeer-focused-input" ); + $( this.options.endInput ).removeClass( "calendeer-focused-input" ); + this.focused = "start"; this.el.addClass( "start-focus" ); this.el.removeClass( "end-focus" ); @@ -836,6 +982,23 @@ $(function(){ this.el.removeClass( "end-time-focus" ); } }, + toggleInputHighlighting: function( focused ) { + if ( focused !== "start" && focused !== "end" ) { + focused = this.focused === "start" ? "end" : "start"; + } + var notFocused = focused === "start" ? "end" : "start"; + + $( this.options[ focused + "Input" ] ).addClass( + "calendeer-focused-input-" + focused + ); + $( this.options[ notFocused + "Input" ] ).removeClass( + "calendeer-focused-input-" + notFocused + ); + }, + removeInputHighlighting: function() { + $( this.options.startInput ).removeClass( "calendeer-focused-input-start" ); + $( this.options.endInput ).removeClass( "calendeer-focused-input-end" ); + }, show: function( date, index ) { if ( typeof index !== "number" || index < 0 || @@ -854,34 +1017,20 @@ $(function(){ return this; } } - if ( App.Utils.isDate(date) ) { - var diff = App.Utils.monthDiff( rightNow, date ); - if ( diff < 0 || (this.options.maxCalendars !== 0 && diff >= this.options.maxCalendars) ) { - return this; - } else { - if ( diff < index ) { - index = diff; - } else { - if ( this.options.maxCalendars ) { - if ( this.options.numberOfCalendars > this.options.maxCalendars - diff ) { - index = this.options.numberOfCalendars - this.options.maxCalendars + diff; - } - } - } - } + if ( Utils.isDate(date) ) { this.hide(); var numCalendars = -1, showIndex; this.visibleIndexes = []; while( ++numCalendars < this.options.numberOfCalendars ) { - showIndex = diff - index + numCalendars; + showIndex = Utils.hashKeyByMonthDiff( date, numCalendars - index ); this.visibleIndexes.push( showIndex ); calendar = this.getCalendar( showIndex ); calendar.show(); - calendar.togglePreviousButton( numCalendars === 0 && - showIndex !== 0 ); + calendar.togglePreviousButton( + numCalendars === 0 + ); calendar.toggleNextButton( - numCalendars === this.options.numberOfCalendars - 1 && - showIndex !== this.options.maxCalendars - 1 + numCalendars === this.options.numberOfCalendars - 1 ); } this.drawState( this.dates.start, this.dates.end ); @@ -901,23 +1050,6 @@ $(function(){ } return this; }, - clearDates: function( type, fromHandler ) { - if ( typeof type === "string" && this.dates[type] !== undefined ) { - type = type.toLowerCase(); - this.dates[type] = null; - if ( type !== "start" && type !== "end" ) { - delete this.dates[type]; - } else { - this.el.removeClass( type + "-date" ); - this.el.trigger( "setDate", [type, null, fromHandler] ); - this.drawState( this.dates.start, this.dates.end ); - } - } else { - this.dates.start = null; - this.dates.end = null; - this.drawState( this.dates.start, this.dates.end ); - } - }, clearTimes: function( type, fromHandler ) { if ( typeof type === "string" && this.dates[type] !== undefined ) { type = type.toLowerCase(); @@ -926,7 +1058,7 @@ $(function(){ delete this.times[type]; } else { this.el.removeClass( type + "-time" ); - this.el.trigger( "setTime", [type, rightNow, fromHandler] ); + this.emitEvent( "setTime", [type, rightNow, fromHandler] ); } } else { this.dates.start = null; @@ -934,49 +1066,32 @@ $(function(){ this.drawState( this.dates.start, this.dates.end ); } }, - validateDate: function( date, type ) { - var dateConditions = Utils.isDate( date ), - futureConditions = ( this.options.maxCalendars !== 0 ? - Utils.monthDiff( this.dates.today, date ) < this.options.maxCalendars : - true ), - pastConditions = Utils.dateTimeComparator( date, this.dates.today ) + 1; - - return !! ( dateConditions && - futureConditions && - pastConditions ); - }, setDate: function( type, date, fromHandler ) { if ( typeof type !== "string" || ( ! Utils.isDate(date) && date != undefined ) ) { throw new Error( "setDate invalid arguments" ); } type = type.toLowerCase(); - if ( ! this.validateDate( date, type ) ) return this; this.dates[ type ] = date; this.el.addClass( type + "-date" ); if ( type === "start" ) { - if ( this.dates.end && Utils.dateComparator(date,this.dates.end)===1 ) { - this.clearDates( "end" ); - } if ( Utils.isDate(date) && ! this.isVisible(date) ) { this.show( date, 0 ); } this.drawState( this.dates.start, this.dates.end ); } else if ( type === "end" ) { - if ( this.dates.start && Utils.dateComparator(date,this.dates.start)===-1 ) { - this.clearDates( "start" ); - } if ( Utils.isDate(date) && ! this.isVisible(date) ) { this.show( date, this.options.numberOfCalendars - 1 ); } this.drawState( this.dates.start, this.dates.end ); } - this.el.trigger( "setDate", [type, date, fromHandler] ); + this.emitEvent( "setDate", [type, date, fromHandler] ); var dateTime = this.get( type ); if ( dateTime != undefined ) { - this.el.trigger( "setDateTime", [type, Utils.toISO(dateTime), dateTime] ); + this.emitEvent( "setDateTime", [type, Utils.toISO(dateTime), dateTime] ); } if ( ! fromHandler ) { + this.toggleInputHighlighting(); this.toggleFocused(); } return this; @@ -987,13 +1102,12 @@ $(function(){ throw new Error( "setTime invalid arguments" ); } type = type.toLowerCase(); - // if ( ! this.validateDate( date, type ) ) return this; this.times[ type ] = date; this.el.addClass( type + "-time" ); - this.el.trigger( "setTime", [type, date, fromHandler] ); + this.emitEvent( "setTime", [type, date, fromHandler] ); var dateTime = this.get( type ); if ( dateTime != undefined ) { - this.el.trigger( "setDateTime", [type, Utils.toISO(dateTime), dateTime] ); + this.emitEvent( "setDateTime", [type, Utils.toISO(dateTime), dateTime] ); } if ( ! fromHandler ) { this.toggleTimeFocused(); @@ -1005,7 +1119,9 @@ $(function(){ if ( isNaN(steps) ) { steps = 1; } - this.show( this.getCalendar( this.visibleIndexes[0] + steps ).dateObject, 0 ); + var thisDate = this.Calendars[ this.visibleIndexes[0] ].dateObject; + var nextMonthHashKey = Utils.hashKeyByMonthDiff( thisDate, steps ); + this.show( this.getCalendar( nextMonthHashKey ).dateObject, 0 ); }, nextPage: function() { this.next( this.options.numberOfCalendars ); @@ -1016,14 +1132,20 @@ $(function(){ steps = 1; } var last = this.visibleIndexes.length - 1; - this.show( this.getCalendar( this.visibleIndexes[ last ] - steps ).dateObject, last ); + var thisDate = this.Calendars[ this.visibleIndexes[last] ].dateObject; + var prevMonthHashKey = Utils.hashKeyByMonthDiff( thisDate, -steps ); + this.show( this.getCalendar( prevMonthHashKey ).dateObject, last ); }, previousPage: function() { this.previous( this.options.numberOfCalendars ); }, isVisible: function( date ) { - var diff = Utils.monthDiff( rightNow, date ); - return !!( ~$.inArray(diff, this.visibleIndexes) ); + // if date is a date object, must convert it to a hash key + if ( Utils.isDate(date) ) { + date = Utils.generateMonthHashKey( date ); + } + // otherwise just use the given hash key, assuming it is a string + return !!( ~$.inArray(date, this.visibleIndexes) ); }, callOnVisibles: function() { if ( ! arguments.length ) { @@ -1056,7 +1178,6 @@ $(function(){ endInput: null, eventDelegate: null, numberOfCalendars: 2, - maxCalendars: 0, timeSupport: true, useSugar: typeof (new Date()).isValid === "function" }; @@ -1064,66 +1185,3 @@ $(function(){ window.App = window.App || {}; window.App.Calendeer = Calendeer; }); -$(function(){ - - var init = function( startID, endID ) { - var $startInput = $("#" + startID), - $endInput = $("#" + endID), - $startTimeInput, - $endTimeInput, - startName = $startInput.attr( "name" ), - endName = $endInput.attr( "name" ), - $startHidden = $( '' ).attr( { - name: startName, - id: startID - } ), - $endHidden = $( '' ).attr( { - name: endName, - id: endID - } ); - - $startInput.attr( "id", startID + "_calendeer" ).removeAttr( "name" ); - $endInput.attr( "id", endID + "_calendeer" ).removeAttr( "name" ); - $startTimeInput = $startInput.clone().attr( "id", startID + "_time_calendeer" ); - $endTimeInput = $endInput.clone().attr( "id", endID + "_time_calendeer" ); - - $startInput.after( $startTimeInput ).after( $startHidden ); - $endInput.after( $endTimeInput ).after( $endHidden ); - - var calendeer = new App.Calendeer( { - startInput: $startInput, - startTimeInput: $startTimeInput, - endInput: $endInput, - endTimeInput: $endTimeInput - } ); - - $(document).bind( "setDateTime", function( e, type, isoDate, dateObject ) { - if ( type === "start" ) { - $startHidden.val( isoDate ); - } else if ( type === "end" ) { - $endHidden.val( isoDate ); - } - } ); - - return function() { - calendeer.el.insertAfter( $endTimeInput ); - }; - - }; - - var callback = function() {}; - if ( $('#offerStartDate_ID').length ) { - // Page 1 - callback = init( "offerStartDate_ID", "offerEndDate_ID" ); - } else if ( $('#startAdvTargetDate_ID').length ) { - // Page 3 - callback = init( "startAdvTargetDate_ID", "endAdvTargetDate_ID" ); - } - - $( "", { - href: "//paypal-moonwalk.s3.amazonaws.com/stylesheets/calendeer.css", - rel: "stylesheet", - type: "text/css" - } ).appendTo( $("head") ).bind( "load", callback ); - -}); \ No newline at end of file diff --git a/javascripts/calendeer.js b/javascripts/calendeer.js index 9738b25..2c0718a 100644 --- a/javascripts/calendeer.js +++ b/javascripts/calendeer.js @@ -37,7 +37,8 @@ $(function(){ this.setTime("start", noon, false ); this.setTime("end", noon, false ); this.preload(); - this.toggleFocused( "start", false ); + this.toggleFocused( "start" ); + this.removeInputHighlighting(); }, get: function( type ) { if ( Utils.isDate( this.dates[type] ) && @@ -224,7 +225,7 @@ $(function(){ $input.on( "keyup.calendeer." + type, { type: type, scope: this }, this.inputHandler ); $input.on( "focus.calendeer." + type, { type: type, scope: this }, $.proxy( function(e) { - this.toggleFocused(e.data.type, false ); + this.toggleFocused( e.data.type ); this.show( e.data.type ); }, this ) ); }, @@ -338,7 +339,7 @@ $(function(){ return [ attachment.el, "sibling" ]; }, - toggleFocused: function( focused, addHighlighting ) { + toggleFocused: function( focused ) { if ( focused !== "start" && focused !== "end" ) { focused = this.focused === "start" ? "end" : "start"; } @@ -346,14 +347,6 @@ $(function(){ $( this.options.startInput ).removeClass( "calendeer-focused-input" ); $( this.options.endInput ).addClass( "calendeer-focused-input" ); - if ( addHighlighting ) { - $( this.options.startInput ).removeClass( "calendeer-focused-input-start" ); - $( this.options.endInput ).addClass( "calendeer-focused-input-end" ); - } else { - $( this.options.startInput ).removeClass( "calendeer-focused-input-start" ); - $( this.options.endInput ).removeClass( "calendeer-focused-input-end" ); - } - this.focused = "end"; this.el.addClass( "end-focus" ); this.el.removeClass( "start-focus" ); @@ -361,14 +354,6 @@ $(function(){ $( this.options.startInput ).addClass( "calendeer-focused-input" ); $( this.options.endInput ).removeClass( "calendeer-focused-input" ); - if ( addHighlighting ) { - $( this.options.endInput ).removeClass( "calendeer-focused-input-end" ); - $( this.options.startInput ).addClass( "calendeer-focused-input-start" ); - } else { - $( this.options.endInput ).removeClass( "calendeer-focused-input-end" ); - $( this.options.startInput ).removeClass( "calendeer-focused-input-start" ); - } - this.focused = "start"; this.el.addClass( "start-focus" ); this.el.removeClass( "end-focus" ); @@ -392,6 +377,23 @@ $(function(){ this.el.removeClass( "end-time-focus" ); } }, + toggleInputHighlighting: function( focused ) { + if ( focused !== "start" && focused !== "end" ) { + focused = this.focused === "start" ? "end" : "start"; + } + var notFocused = focused === "start" ? "end" : "start"; + + $( this.options[ focused + "Input" ] ).addClass( + "calendeer-focused-input-" + focused + ); + $( this.options[ notFocused + "Input" ] ).removeClass( + "calendeer-focused-input-" + notFocused + ); + }, + removeInputHighlighting: function() { + $( this.options.startInput ).removeClass( "calendeer-focused-input-start" ); + $( this.options.endInput ).removeClass( "calendeer-focused-input-end" ); + }, show: function( date, index ) { if ( typeof index !== "number" || index < 0 || @@ -484,7 +486,8 @@ $(function(){ this.emitEvent( "setDateTime", [type, Utils.toISO(dateTime), dateTime] ); } if ( ! fromHandler ) { - this.toggleFocused( undefined, true ); + this.toggleInputHighlighting(); + this.toggleFocused(); } return this; }, diff --git a/javascripts/month.js b/javascripts/month.js index dd9ec65..59cb6b9 100644 --- a/javascripts/month.js +++ b/javascripts/month.js @@ -142,18 +142,18 @@ $(function(){ this.el = e.calendeer; $(".calendeers").append( e.calendeer ); - }, attach: function( $el, type ) { if ( ! this.el ) { return this; } - if ( type === "sibling" ) { - this.el.insertAfter( $el ); - } else if ( type === "prepend" ) { - this.el.prependTo( $el ); - } else if ( type === "append" ) { - this.el.appendTo( $el ); + var conditions = { + sibling: this.el.insertAfter, + prepend: this.el.prependTo, + append: this.el.appendTo + }; + if (conditions[type]) { + conditions[type].call( this.el, $el); } return this; }, From 50848aabdd0922cbb03c57c6029fceecd5048ffb Mon Sep 17 00:00:00 2001 From: Alex Tironati Date: Wed, 6 Feb 2013 16:50:18 -0500 Subject: [PATCH 4/4] remove whitespace --- javascripts/application.js | 2 -- javascripts/calendeer.js | 2 -- 2 files changed, 4 deletions(-) diff --git a/javascripts/application.js b/javascripts/application.js index fb0fb3a..6b43945 100644 --- a/javascripts/application.js +++ b/javascripts/application.js @@ -890,8 +890,6 @@ do{e=a.indexOf(c.charAt(l++));g=a.indexOf(c.charAt(l++));i=a.indexOf(c.charAt(l+ }, attachmentPoint: function( date ) { var attachment; - - var firstDOMMonth = this.el.children(":first"); // if no DOM element exists, we can just attach as child of calendeers div diff --git a/javascripts/calendeer.js b/javascripts/calendeer.js index 2c0718a..f5a3a73 100644 --- a/javascripts/calendeer.js +++ b/javascripts/calendeer.js @@ -285,8 +285,6 @@ $(function(){ }, attachmentPoint: function( date ) { var attachment; - - var firstDOMMonth = this.el.children(":first"); // if no DOM element exists, we can just attach as child of calendeers div