Special:Contributions: Open "To date" widget after selecting a "From date"
[lhc/web/wiklou.git] / resources / src / mediawiki.widgets / mw.widgets.DateInputWidget.js
index 0ec6a4c..ce9cf36 100644 (file)
@@ -56,7 +56,7 @@
         *     } );
         *
         * @class
-        * @extends OO.ui.InputWidget
+        * @extends OO.ui.TextInputWidget
         * @mixins OO.ui.mixin.IndicatorElement
         *
         * @constructor
 
                // Properties (must be set before parent constructor, which calls #setValue)
                this.$handle = $( '<div>' );
-               this.label = new OO.ui.LabelWidget();
+               this.innerLabel = new OO.ui.LabelWidget();
                this.textInput = new OO.ui.TextInputWidget( {
                        required: config.required,
                        placeholder: placeholderDateFormat,
                } );
                this.inCalendar = 0;
                this.inTextInput = 0;
+               this.closing = false;
                this.inputFormat = config.inputFormat;
                this.displayFormat = config.displayFormat;
                this.longDisplayFormat = config.longDisplayFormat;
                this.required = config.required;
                this.placeholderLabel = config.placeholderLabel;
-
                // Validate and set min and max dates as properties
+
                if ( config.mustBeAfter !== undefined ) {
                        mustBeAfter = moment( config.mustBeAfter, 'YYYY-MM-DD' );
                        if ( mustBeAfter.isValid() ) {
                                this.mustBeBefore = mustBeBefore;
                        }
                }
-
                // Parent constructor
                mw.widgets.DateInputWidget.parent.call( this, config );
 
                } );
                this.$handle.on( {
                        click: this.onClick.bind( this ),
-                       keypress: this.onKeyPress.bind( this )
+                       keypress: this.onKeyPress.bind( this ),
+                       focus: this.onFocus.bind( this )
                } );
 
                // Initialization
                // Move 'tabindex' from this.$input (which is invisible) to the visible handle
                this.setTabIndexedElement( this.$handle );
                this.$handle
-                       .append( this.label.$element, this.$indicator )
+                       .append( this.innerLabel.$element, this.$indicator )
                        .addClass( 'mw-widget-dateInputWidget-handle' );
                this.calendar.$element
                        .addClass( 'mw-widget-dateInputWidget-calendar' );
 
        /* Inheritance */
 
-       OO.inheritClass( mw.widgets.DateInputWidget, OO.ui.InputWidget );
+       OO.inheritClass( mw.widgets.DateInputWidget, OO.ui.TextInputWidget );
        OO.mixinClass( mw.widgets.DateInputWidget, OO.ui.mixin.IndicatorElement );
 
+       /* Events */
+
+       /**
+        * Fired when the widget is deactivated (i.e. the calendar is closed). This can happen because
+        * the user selected a value, or because the user blurred the widget.
+        *
+        * @event deactivate
+        * @param {boolean} userSelected Whether the deactivation happened because the user selected a value
+        */
+
        /* Methods */
 
        /**
                if ( this.getValue() === '' ) {
                        this.textInput.setValue( '' );
                        this.calendar.setDate( null );
-                       this.label.setLabel( this.placeholderLabel );
+                       this.innerLabel.setLabel( this.placeholderLabel );
                        this.$element.addClass( 'mw-widget-dateInputWidget-empty' );
                } else {
                        moment = this.getMoment();
                        if ( !this.inCalendar ) {
                                this.calendar.setDate( this.getValue() );
                        }
-                       this.label.setLabel( moment.format( this.getDisplayFormat() ) );
+                       this.innerLabel.setLabel( moment.format( this.getDisplayFormat() ) );
                        this.$element.removeClass( 'mw-widget-dateInputWidget-empty' );
                }
        };
         * Deactivate this input field for data entry. Closes the calendar and hides the text field.
         *
         * @private
+        * @param {boolean} [userSelected] Whether we are deactivating because the user selected a value
         */
-       mw.widgets.DateInputWidget.prototype.deactivate = function () {
+       mw.widgets.DateInputWidget.prototype.deactivate = function ( userSelected ) {
                this.$element.removeClass( 'mw-widget-dateInputWidget-active' );
                this.$handle.show();
                this.textInput.toggle( false );
                this.calendar.toggle( false );
                this.setValidityFlag();
+
+               if ( userSelected ) {
+                       // Prevent focusing the handle from reopening the calendar
+                       this.closing = true;
+                       this.$handle.focus();
+                       this.closing = false;
+               }
+
+               this.emit( 'deactivate', !!userSelected );
        };
 
        /**
                }
        };
 
+       /**
+        * Handle focus events.
+        *
+        * @private
+        */
+       mw.widgets.DateInputWidget.prototype.onFocus = function () {
+               if ( !this.closing ) {
+                       this.activate();
+               }
+       };
+
        /**
         * Handle calendar key press events.
         *
         */
        mw.widgets.DateInputWidget.prototype.onCalendarKeyPress = function ( e ) {
                if ( !this.isDisabled() && e.which === OO.ui.Keys.ENTER ) {
-                       this.deactivate();
-                       this.$handle.focus();
+                       this.deactivate( true );
                        return false;
                }
        };
                if (
                        !this.isDisabled() &&
                        e.which === 1 &&
-                       $( e.target ).hasClass( 'mw-widget-calendarWidget-day' )
+                       (
+                               $( e.target ).hasClass( 'mw-widget-calendarWidget-day' ) ||
+                               $( e.target ).hasClass( 'mw-widget-calendarWidget-month' )
+                       )
                ) {
-                       this.deactivate();
-                       this.$handle.focus();
+                       this.deactivate( true );
                        return false;
                }
        };
         * @private
         */
        mw.widgets.DateInputWidget.prototype.onEnter = function () {
-               this.deactivate();
-               this.$handle.focus();
+               this.deactivate( true );
        };
 
        /**