# inputEx-library

### inputEx 0.5.1

inputEx-library > inputEx > DatePickerField.js (source view)
Search:
Filters Show Private Show Protected Show Deprecated

    (function() {

       var lang = YAHOO.lang, Event = YAHOO.util.Event, Dom = YAHOO.util.Dom;

    /**
     * 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);
    };

    lang.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 = YAHOO.lang.isUndefined(options.readonly) ? true : options.readonly;

          // Added options
          this.options.calendar = options.calendar || inputEx.messages.defautCalendarOpts;
       },

       /**
        * Render the input field and the minical container
        */
       renderComponent: function() {

          inputEx.DatePickerField.superclass.renderComponent.call(this);

          // Create overlay
          this.oOverlay = new YAHOO.widget.Overlay(Dom.generateId(), { visible: false });
          this.oOverlay.setBody(" ");
          this.oOverlay.body.id = Dom.generateId();

          // Create button
          this.button = new YAHOO.widget.Button({ type: "menu", menu: this.oOverlay, label: "&nbsp;&nbsp;&nbsp;&nbsp;" });
          this.button.appendTo(this.wrapEl);

          // Render the overlay
          this.oOverlay.render(this.wrapEl);
          // HACK: Set position absolute to the overlay
          Dom.setStyle(this.oOverlay.body.parentNode, "position", "absolute");

          // Subscribe the click handler on the field only if readonly
    		if(this.options.readonly) {
    	      Event.addListener(this.el,'click',function(){
    	         // calendar may not have been rendered yet
    	         this.renderCalendar();

    	         if (!this.oOverlay.justHidden) {
    	            this.button._showMenu();
    	         }
    	      },this,true);
          }

          this.oOverlay.hideEvent.subscribe(function() {
             this.oOverlay.justHidden = true;
             YAHOO.lang.later(250,this,function(){this.oOverlay.justHidden=false;});
          },this,true);

          // Subscribe to the first click
          this.button.on('click', this.renderCalendar, this, true);
       },

       /**
        * Called ONCE to render the calendar lazily
        */
       renderCalendar: function() {
          // if already rendered, ignore call
          if (!!this.calendarRendered) return;

          // Render the calendar
          var calendarId = Dom.generateId();
          this.calendar = new YAHOO.widget.Calendar(calendarId,this.oOverlay.body.id, this.options.calendar );

          /*
          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 (updatedEvt 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;

    		// Since we render the calendar AFTER the opening of the overlay,
    		// the overlay can be mis-positionned (outside of the viewport).
    		// We force the repositionning of the overlay by hiding it, and show it again.
    		this.oOverlay.hide();
          this.button._showMenu();
       },

       /**
      	 * Select the right date and display the right page on calendar, when the field has a value
     	 */
       beforeShowOverlay: function(e) {

          var date = this.getValue(true);
          if (!!this.calendar) {

    			if(!!date) {
             	// HACK: don't fire Field updatedEvt 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);

    })();

Copyright © 2010 Eric Abouaf All rights reserved.