11<template >
22  <div  class =" vdp-datepicker"   :class =" wrapperClass"  >
3-     <input 
3+     <div  :class =" {'input-group' : bootstrapStyling}"  >
4+       <span  class =" vdp-datepicker__calendar-button"   :class =" {'input-group-addon' : bootstrapStyling}"   v-if =" calendarButton"   @click =" showCalendar"  ><i  :class =" calendarButtonIcon"  ><span  v-if =" calendarButtonIcon.length === 0"  >&hellip ; </span ></i ></span >
5+       <input 
46        :type =" inline ? 'hidden' : 'text'" 
5-         :class =" inputClass" 
7+         :class =" [  inputClass, { 'form-control' : bootstrapStyling } ] " 
68        :name =" name" 
79        :id =" id" 
8-         @click =" showCalendar() " 
10+         @click =" showCalendar" 
911        :value =" formattedValue" 
1012        :placeholder =" placeholder" 
1113        :clear-button =" clearButton" 
1214        :disabled =" disabledPicker" 
1315        :required =" required" 
1416        readonly >
15-     <i  class =" vdp-datepicker__clear-button"   v-if =" clearButton"   @click =" clearDate()"  >× ; </i >
17+       <span  class =" vdp-datepicker__clear-button"   :class =" {'input-group-addon' : bootstrapStyling}"   v-if =" clearButton && selectedDate"   @click =" clearDate()"  ><i  :class =" clearButtonIcon"  ><span  v-if =" calendarButtonIcon.length === 0"  >× ; </span ></i ></span >
18+     </div >
19+ 
1620        <!--  Day View --> 
1721        <div  class =" vdp-datepicker__calendar"   v-show =" showDayView"   v-bind:style =" calendarStyle"  >
1822            <header >
3135            -->  <span  class =" cell day" 
3236                v-for =" day in days" 
3337                track-by =" timestamp" 
34-                 v-bind:class =" { 'selected':day.isSelected, 'disabled':day.isDisabled, 'highlighted': day.isHighlighted}" 
38+                 v-bind:class =" { 'selected':day.isSelected, 'disabled':day.isDisabled, 'highlighted': day.isHighlighted, 'today': day.isToday }" 
3539                @click =" selectDate(day)"  >{{ day.date }}</span >
3640        </div >
3741
3842        <!--  Month View --> 
39-         <div  class =" vdp-datepicker__calendar"   v-show =" showMonthView"   v-bind:style =" calendarStyleSecondary "  >
43+         <div  class =" vdp-datepicker__calendar"   v-show =" showMonthView"   v-bind:style =" calendarStyle "  >
4044            <header >
4145                <span 
4246                    @click =" previousYear" 
5660        </div >
5761
5862        <!--  Year View --> 
59-         <div  class =" vdp-datepicker__calendar"   v-show =" showYearView"   v-bind:style =" calendarStyleSecondary "  >
63+         <div  class =" vdp-datepicker__calendar"   v-show =" showYearView"   v-bind:style =" calendarStyle "  >
6064            <header >
6165                <span  @click =" previousDecade"   class =" prev" 
6266                    v-bind:class =" { 'disabled' : previousDecadeDisabled(currDate) }"  >< ; </span >
7175                v-bind:class =" { 'selected': year.isSelected, 'disabled': year.isDisabled }" 
7276                @click.stop =" selectYear(year)"  >{{ year.year }}</span >
7377        </div >
74- 
7578  </div >
7679</template >
7780
@@ -126,6 +129,26 @@ export default {
126129      type:  Boolean , 
127130      default:  false  
128131    }, 
132+     clearButtonIcon:  { 
133+       type:  String , 
134+       default:  ' '  
135+     }, 
136+     calendarButton:  { 
137+       type:  Boolean , 
138+       default:  false  
139+     }, 
140+     calendarButtonIcon:  { 
141+       type:  String , 
142+       default:  ' '  
143+     }, 
144+     bootstrapStyling:  { 
145+       type:  Boolean , 
146+       default:  false  
147+     }, 
148+     initialView:  { 
149+       type:  String , 
150+       default:  ' day'  
151+     }, 
129152    disabledPicker:  { 
130153      type:  Boolean , 
131154      default:  false  
@@ -217,7 +240,8 @@ export default {
217240          timestamp:  dObj .getTime (), 
218241          isSelected:  this .isSelectedDate (dObj), 
219242          isDisabled:  this .isDisabledDate (dObj), 
220-           isHighlighted:  this .isHighlightedDate (dObj) 
243+           isHighlighted:  this .isHighlightedDate (dObj), 
244+           isToday:  dObj .toDateString () ===  (new  Date ()).toDateString () 
221245        }) 
222246        dObj .setDate (dObj .getDate () +  1 ) 
223247      } 
@@ -257,70 +281,77 @@ export default {
257281    }, 
258282    calendarStyle  () { 
259283      let  styles =  {} 
260-       if  (! this .$isServer ) { 
261-         let  elSize =  { 
262-           top:  0 , 
263-           height:  0  
264-         } 
265-         if  (this .$el ) { 
266-           elSize =  this .$el .getBoundingClientRect () 
267-         } 
268-         let  heightNeeded =  elSize .top  +  elSize .height  +  this .calendarHeight  ||  0  
269-         //  if the calendar doesn't fit on the window without scrolling position it above the input 
270-         if  (heightNeeded >  window .innerHeight ) { 
271-           styles =  { 
272-             ' bottom' :  elSize .height  +  ' px'  
273-           } 
274-         } 
275-       } 
276-       if  (this .isInline ()) { 
284+ 
285+       if  (this .isInline ) { 
277286        styles .position  =  ' static'  
278287      } 
279288
280289      return  styles 
281290    }, 
282-     calendarStyleSecondary  () { 
283-       return  (this .isInline ()) ?  { ' position' :  ' static'   } :  {} 
291+     isOpen  () { 
292+       return  this .showDayView  ||  this .showMonthView  ||  this .showYearView  
293+     }, 
294+     isInline  () { 
295+       return  typeof  this .inline  !==  ' undefined'   &&  this .inline  
284296    } 
285297  }, 
286298  methods:  { 
299+     /**  
300+      * Close all calendar layers 
301+      */  
287302    close  () { 
288303      this .showDayView  =  this .showMonthView  =  this .showYearView  =  false  
289304      this .$emit (' closed'  ) 
305+       document .removeEventListener (' click'  , this .clickOutside , false ) 
290306    }, 
291307    getDefaultDate  () { 
292308      return  new  Date (new  Date ().getFullYear (), new  Date ().getMonth (), 1 ).getTime () 
293309    }, 
294310    resetDefaultDate  () { 
295-       this .currDate  =  (this .selectedDate  ===  null ) ?  this .getDefaultDate () :  this .selectedDate .getTime () 
296-     }, 
297-     isOpen  () { 
298-       return  this .showDayView  ||  this .showMonthView  ||  this .showYearView  
299-     }, 
300-     isInline  () { 
301-       return  typeof  this .inline  !==  ' undefined'   &&  this .inline  
311+       if  (this .selectedDate  ===  null ) { 
312+         this .currDate  =  this .getDefaultDate () 
313+         return  
314+       } 
315+       this .currDate  =  this .currDate  =  new  Date (this .selectedDate .getFullYear (), this .selectedDate .getMonth (), 1 ).getTime () 
302316    }, 
317+     /**  
318+      * Effectively a toggle to show/hide the calendar 
319+      * @return  {[type]}  [description] 
320+      */  
303321    showCalendar  () { 
304-       if  (this .isInline () ) { 
322+       if  (this .isInline ) { 
305323        return  false  
306324      } 
307-       if  (this .isOpen () ) { 
325+       if  (this .isOpen ) { 
308326        return  this .close () 
309327      } 
310-       this .showDayCalendar () 
328+       switch  (this .initialView ) { 
329+         case  ' year'  : 
330+           this .showYearCalendar () 
331+           break  
332+         case  ' month'  : 
333+           this .showMonthCalendar () 
334+           break  
335+         default : 
336+           this .showDayCalendar () 
337+           break  
338+       } 
311339    }, 
312340    showDayCalendar  () { 
313341      this .close () 
314342      this .showDayView  =  true  
315343      this .$emit (' opened'  ) 
344+       document .addEventListener (' click'  , this .clickOutside , false ) 
316345    }, 
317346    showMonthCalendar  () { 
318347      this .close () 
319348      this .showMonthView  =  true  
349+       document .addEventListener (' click'  , this .clickOutside , false ) 
320350    }, 
321351    showYearCalendar  () { 
322352      this .close () 
323353      this .showYearView  =  true  
354+       document .addEventListener (' click'  , this .clickOutside , false ) 
324355    }, 
325356
326357    setDate  (timestamp ) { 
@@ -332,7 +363,8 @@ export default {
332363
333364    clearDate  () { 
334365      this .selectedDate  =  null  
335-       this .$emit (' selected'  , this .selectedDate ) 
366+       this .$emit (' selected'  , null ) 
367+       this .$emit (' input'  , null ) 
336368      this .$emit (' cleared'  ) 
337369    }, 
338370
@@ -344,7 +376,7 @@ export default {
344376        return  false  
345377      } 
346378      this .setDate (day .timestamp ) 
347-       if  (this .isInline () ) { 
379+       if  (this .isInline ) { 
348380        return  this .showDayCalendar () 
349381      } 
350382      this .close () 
@@ -713,29 +745,28 @@ export default {
713745      this .currDate  =  new  Date (date .getFullYear (), date .getMonth (), 1 ).getTime () 
714746    }, 
715747
748+     /**  
749+      * Close the calendar if clicked outside the datepicker 
750+      * @param   {Event}  event  
751+      */  
752+     clickOutside  (event ) { 
753+       if  (this .$el  &&  ! this .$el .contains (event .target )) { 
754+         if  (this .isInline ) { 
755+           return  this .showDayCalendar () 
756+         } 
757+         this .resetDefaultDate () 
758+         this .close () 
759+         document .removeEventListener (' click'  , this .clickOutside , false ) 
760+       } 
761+     }, 
762+ 
716763    init  () { 
717764      if  (this .value ) { 
718765        this .setValue (this .value ) 
719766      } 
720-       if  (this .isInline () ) { 
767+       if  (this .isInline ) { 
721768        this .showDayCalendar () 
722769      } 
723- 
724-       if  (! this .$isServer ) { 
725-         this .$nextTick (() =>  { 
726-           this .calendarHeight  =  this .$el .querySelector (' .vdp-datepicker__calendar'  ).getBoundingClientRect ().height  
727-         }) 
728-       } 
729- 
730-       document .addEventListener (' click'  , (e ) =>  { 
731-         if  (this .$el  &&  ! this .$el .contains (e .target )) { 
732-           if  (this .isInline ()) { 
733-             return  this .showDayCalendar () 
734-           } 
735-           this .resetDefaultDate () 
736-           this .close () 
737-         } 
738-       }, false ) 
739770    } 
740771  }, 
741772  /**  
@@ -857,7 +888,7 @@ $width = 300px
857888    .year  
858889        width  33.333%   
859890
860- .vdp-datepicker__clear-button 
861-     cursor :  pointer  
862-     font-style :  normal  
891+ .vdp-datepicker__clear-button ,  .vdp-datepicker__calendar-button 
892+     cursor  pointer  
893+     font-style  normal  
863894 </style >
0 commit comments