inputEx-library

inputex-date  3.0.0a

inputEx-library > inputex-date > inputex-datepicker.js (source view)
Search:
 
Filters
/**
 * @module inputex-datepicker
 */
YUI.add("inputex-datepicker",function(Y){

   var inputEx = Y.inputEx,
       lang = Y.Lang;
/**
 * A DatePicker Field.
 * @class inputEx.DatePickerField
 * @extends inputEx.DateField
 * @constructor
 * @param {Object} options No added option for this field (same as DateField)
 * <ul>
 *   <li>calendar: yui calendar configuration object</li>
 * </ul>
 */
inputEx.DatePickerField = function(options) {
   inputEx.DatePickerField.superclass.constructor.call(this,options);
};

Y.extend(inputEx.DatePickerField, inputEx.DateField, {
   /**
    * Set the default date picker CSS classes
    * @param {Object} options Options object as passed to the constructor
    */
   setOptions: function(options) {
      inputEx.DatePickerField.superclass.setOptions.call(this, options);
      
      // Overwrite default options
      this.options.className = options.className ? options.className : 'inputEx-Field inputEx-DateField inputEx-PickerField inputEx-DatePickerField';

      this.options.readonly = lang.isUndefined(options.readonly) ? true : options.readonly;
      
      // Added options
      this.options.calendar = options.calendar || inputEx.messages.defautCalendarOpts;
   },
   
   
   
   renderOverlay: function() {
      
	   // Create overlay
      this.oOverlay = new Y.Overlay({
         visible:false,
         zIndex: 4
      });
      
      this.oOverlay.render();
      
      Y.one( Y.DOM._getWin().document ).on('click', function(e) {
         var n = e.target._node
         if(n != this.button._node && n != this.el) {
            this.oOverlay.hide();
         }
      },this );

   },
   
   
	_toggleOverlay: function(e) {
	   
	   // DON'T stop the event since it will be used to close other overlays...
	   //e.stopPropagation();

      if(!this.oOverlay) {
         this.renderOverlay();
         
         this.renderCalendar();
      }
      
      if(this.oOverlay.get('visible')) {
         this.oOverlay.hide();
      }
      else {
         
         // Show menu
         this.oOverlay.show();

         // align
         this.oOverlay.set("align", {node:this.button,  points:[Y.WidgetPositionAlign.TL, Y.WidgetPositionAlign.BL]});
      }
      
	},
   
   /**
    * Render the input field and the minical container
    */
   renderComponent: function() {
      
      inputEx.DatePickerField.superclass.renderComponent.call(this);
      
      // Create button
      this.button = Y.Node.create("<button>&nbsp;</button>").addClass("inputEx-DatePicker-button");
      this.button.appendTo(this.wrapEl);
      
            
      // Subscribe the click handler on the field only if readonly
		if(this.options.readonly) {
	      Y.one(this.el).on('click', this._toggleOverlay, this);
      }      
      
      // Subscribe to the first click
      this.button.on('click', this._toggleOverlay, this);
   },

   
   /**
    * Called ONCE to render the calendar lazily
    */
   renderCalendar: function() {
      // if already rendered, ignore call
      if (!!this.calendarRendered) return;
      
      this.calendar = new Y.Calendar({
                //height:'180px',
                width:'250px',
                showPrevMonth: true,
                showNextMonth: true,
                date: new Date(1982,11,1)});
      
      this.calendar.render( this.oOverlay.get('contentBox') );
      
      /*
      this.calendar.cfg.setProperty("DATE_FIELD_DELIMITER", "/");
      this.calendar.cfg.setProperty("MDY_DAY_POSITION", 1);
      this.calendar.cfg.setProperty("MDY_MONTH_POSITION", 2);
      this.calendar.cfg.setProperty("MDY_YEAR_POSITION", 3);
      this.calendar.cfg.setProperty("MD_DAY_POSITION", 1);
      this.calendar.cfg.setProperty("MD_MONTH_POSITION", 2);*/

      // localization
      /*if(inputEx.messages.shortMonths) this.calendar.cfg.setProperty("MONTHS_SHORT", inputEx.messages.shortMonths);
      if(inputEx.messages.months) this.calendar.cfg.setProperty("MONTHS_LONG", inputEx.messages.months);
      if(inputEx.messages.weekdays1char) this.calendar.cfg.setProperty("WEEKDAYS_1CHAR", inputEx.messages.weekdays1char);
      if(inputEx.messages.shortWeekdays) this.calendar.cfg.setProperty("WEEKDAYS_SHORT", inputEx.messages.shortWeekdays);
      
      // HACK to keep focus on calendar/overlay 
      // so overlay is not hidden when changing page in calendar
      // (inspired by YUI examples)
      var focusDay = function () {

         var oCalendarTBody = Dom.get(calendarId).tBodies[0],
            aElements = oCalendarTBody.getElementsByTagName("a"),
            oAnchor;

         if (aElements.length > 0) {
         
            Dom.batch(aElements, function (element) {
               if (Dom.hasClass(element.parentNode, "today")) {
                  oAnchor = element;
               }
            });
            
            if (!oAnchor) {
               oAnchor = aElements[0];
            }

            // Focus the anchor element using a timer since Calendar will try 
            // to set focus to its next button by default
            
            lang.later(0, oAnchor, function () {
               try {
                  oAnchor.focus();
               }
               catch(e) {}
            });
         
         }
         
      };

      // Set focus to either the current day, or first day of the month in 
      // the Calendar when the month changes (renderEvent is fired)
      this.calendar.renderEvent.subscribe(focusDay, this.calendar, true);
      
      // Open minical on correct date / month if field contains a value
      this.oOverlay.beforeShowEvent.subscribe(this.beforeShowOverlay, this, true);
      
      // Render the calendar on the right page !
      //    ->  this.calendar.render(); is not enough...
      this.beforeShowOverlay();
      
      this.calendar.selectEvent.subscribe(function (type,args,obj) {
         // HACK: stop here if called from beforeShowOverlay
         if (!!this.ignoreBeforeShowOverlayCall) { return; }
         
         this.oOverlay.hide();
         var date = args[0][0];
         var year = date[0], month = date[1], day = date[2];
         
         // set value ("updated" event fired by setValue)
         this.setValue(new Date(year,month-1, day) );
         
      }, this, true);
      
      // Unsubscribe the event so this function is called only once
      this.button.unsubscribe("click", this.renderCalendar); 
      
      this.calendarRendered = true;*/
      
      
      this.calendar.on("selectionChange", function (ev) {

            // Get the date from the list of selected
            // dates returned with the event (since only
            // single selection is enabled by default,
            // we expect there to be only one date)
            var newDate = ev.newSelection[0];

            this.setValue(newDate);
            
            this.oOverlay.hide();
          }, this);
      
		   //this.oOverlay.hide();
   },
   
   /**
  	 * Select the right date and display the right page on calendar, when the field has a value
 	 */
   beforeShowOverlay: function(e) {
	
      if (!!this.calendar) {
         
         var date = this.getValue(true), valid = this.validate();
         
         // check if valid to exclude invalid dates (that are truthy !)
         // check date to exclude empty values ('')
			if (valid && !!date) {
			   
         	// HACK: don't fire Field "updated" event when selecting date
         	this.ignoreBeforeShowOverlayCall = true;
         	// select the previous date in calendar
        		this.calendar.select(date);
				this.ignoreBeforeShowOverlayCall = false;
         	this.calendar.cfg.setProperty("pagedate",(date.getMonth()+1)+"/"+date.getFullYear());
			}

         this.calendar.render(); // refresh calendar
      }
   },

	/**
	 * Disable the field
	 */
	disable: function() {
		inputEx.DatePickerField.superclass.disable.call(this);
		this.button.set('disabled', true);
	},
	
	/**
	 * Enable the field
	 */
	enable: function() {
		inputEx.DatePickerField.superclass.enable.call(this);
		this.button.set('disabled', false);
	}
   
});

inputEx.messages.defautCalendarOpts = { navigator: true };

// Register this class as "datepicker" type
inputEx.registerType("datepicker", inputEx.DatePickerField);

}, '3.0.0a',{
requires: ['inputex-date','node-event-delegate','overlay','calendar']
});

Copyright © 2011 Eric Abouaf All rights reserved.