2 * MediaWiki Widgets - ExpiryWidget class.
4 * @copyright 2018 MediaWiki Widgets Team and others; see AUTHORS.txt
5 * @license The MIT License (MIT); see LICENSE.txt
11 * Creates a mw.widgets.ExpiryWidget object.
13 * @class mw.widgets.ExpiryWidget
14 * @extends OO.ui.Widget
17 * @param {Object} [config] Configuration options
19 mw
.widgets
.ExpiryWidget = function ( config
) {
20 var RFC2822
= 'ddd, DD MMM YYYY HH:mm:ss [GMT]';
22 // Config initialization
23 config
= $.extend( {}, config
);
25 this.relativeField
= new config
.RelativeInputClass( config
.relativeInput
);
26 this.relativeField
.$element
.addClass( 'mw-widget-ExpiryWidget-relative' );
29 mw
.widgets
.ExpiryWidget
.parent
.call( this, config
);
31 // If the wiki does not want the date picker, then initialize the relative
33 if ( config
.noDatePicker
) {
34 this.relativeField
.on( 'change', function ( event
) {
35 // Emit a change event for this widget.
36 this.emit( 'change', event
);
41 .addClass( 'mw-widget-ExpiryWidget' )
43 this.relativeField
.$element
50 this.inputSwitch
= new OO
.ui
.ButtonSelectWidget( {
53 new OO
.ui
.ButtonOptionWidget( {
57 new OO
.ui
.ButtonOptionWidget( {
63 this.dateTimeField
= new mw
.widgets
.datetime
.DateTimeInputWidget( {
64 min
: new Date(), // The selected date must at least be now.
65 required
: config
.required
68 // Initially hide the dateTime field.
69 this.dateTimeField
.toggle( false );
70 // Initially set the relative input.
71 this.inputSwitch
.selectItemByData( 'relative' );
75 // Toggle the visible inputs.
76 this.inputSwitch
.on( 'choose', function ( event
) {
77 switch ( event
.getData() ) {
79 this.dateTimeField
.toggle( true );
80 this.relativeField
.toggle( false );
83 this.dateTimeField
.toggle( false );
84 this.relativeField
.toggle( true );
89 // When the date time field update, update the relative
91 this.dateTimeField
.on( 'change', function ( value
) {
94 // Do not alter the visible input.
95 if ( this.relativeField
.isVisible() ) {
99 // If the value was cleared, do not attempt to parse it.
101 this.relativeField
.setValue( value
);
105 datetime
= moment( value
);
107 // If the datetime is invlaid for some reason, reset the relative field.
108 if ( !datetime
.isValid() ) {
109 this.relativeField
.setValue( undefined );
112 // Set the relative field value. The field only accepts English strings.
113 this.relativeField
.setValue( datetime
.utc().locale( 'en' ).format( RFC2822
) );
116 // When the relative field update, update the date time field if it's a
117 // value that moment understands.
118 this.relativeField
.on( 'change', function ( event
) {
121 // Emit a change event for this widget.
122 this.emit( 'change', event
);
124 // Do not alter the visible input.
125 if ( this.dateTimeField
.isVisible() ) {
129 // Parsing of free text field may fail, so always check if the date is
131 datetime
= moment( event
);
133 if ( datetime
.isValid() ) {
134 this.dateTimeField
.setValue( datetime
.utc().toISOString() );
136 this.dateTimeField
.setValue( undefined );
142 .addClass( 'mw-widget-ExpiryWidget' )
143 .addClass( 'mw-widget-ExpiryWidget-hasDatePicker' )
145 this.inputSwitch
.$element
,
146 this.dateTimeField
.$element
,
147 this.relativeField
.$element
150 // Trigger an initial onChange.
151 this.relativeField
.emit( 'change', this.relativeField
.getValue() );
156 OO
.inheritClass( mw
.widgets
.ExpiryWidget
, OO
.ui
.Widget
);
161 mw
.widgets
.ExpiryWidget
.static.reusePreInfuseDOM = function ( node
, config
) {
162 var relativeElement
= $( node
).find( '.mw-widget-ExpiryWidget-relative' );
164 config
= mw
.widgets
.ExpiryWidget
.parent
.static.reusePreInfuseDOM( node
, config
);
166 if ( relativeElement
.hasClass( 'oo-ui-textInputWidget' ) ) {
167 config
.RelativeInputClass
= OO
.ui
.TextInputWidget
;
168 } else if ( relativeElement
.hasClass( 'mw-widget-selectWithInputWidget' ) ) {
169 config
.RelativeInputClass
= mw
.widgets
.SelectWithInputWidget
;
172 config
.relativeInput
= config
.RelativeInputClass
.static.reusePreInfuseDOM(
183 mw
.widgets
.ExpiryWidget
.static.gatherPreInfuseState = function ( node
, config
) {
184 var state
= mw
.widgets
.ExpiryWidget
.parent
.static.gatherPreInfuseState( node
, config
);
186 state
.relativeInput
= config
.RelativeInputClass
.static.gatherPreInfuseState(
187 $( node
).find( '.mw-widget-ExpiryWidget-relative' ),
197 mw
.widgets
.ExpiryWidget
.prototype.restorePreInfuseState = function ( state
) {
198 mw
.widgets
.ExpiryWidget
.parent
.prototype.restorePreInfuseState
.call( this, state
);
199 this.relativeField
.restorePreInfuseState( state
.relativeInput
);
205 mw
.widgets
.ExpiryWidget
.prototype.setDisabled = function ( disabled
) {
206 mw
.widgets
.ExpiryWidget
.parent
.prototype.setDisabled
.call( this, disabled
);
207 this.relativeField
.setDisabled( disabled
);
209 if ( this.inputSwitch
) {
210 this.inputSwitch
.setDisabled( disabled
);
213 if ( this.dateTimeField
) {
214 this.dateTimeField
.setDisabled( disabled
);
219 * Gets the value of the widget.
223 mw
.widgets
.ExpiryWidget
.prototype.getValue = function () {
224 return this.relativeField
.getValue();
227 }( jQuery
, mediaWiki
) );