Page Menu
Home
WickedGov Phorge
Search
Configure Global Search
Log In
Files
F6009552
DateTimeInputWidget.js
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
23 KB
Referenced Files
None
Subscribers
None
DateTimeInputWidget.js
View Options
(
function
()
{
/**
* @classdesc DateTimeInputWidgets can be used to input a date, a time, or
* a date and time, in either UTC or the user's local timezone.
* Please see the [OOUI documentation on MediaWiki](https://www.mediawiki.org/wiki/OOUI/Widgets/Inputs)
* for more information and examples.
*
* This widget can be used inside a HTML form, such as a OO.ui.FormLayout.
*
* @example
* // Example of a text input widget
* var dateTimeInput = new mw.widgets.datetime.DateTimeInputWidget( {} )
* $( document.body ).append( dateTimeInput.$element );
*
* @class
* @extends OO.ui.InputWidget
* @mixes OO.ui.mixin.IconElement
* @mixes OO.ui.mixin.IndicatorElement
* @mixes OO.ui.mixin.PendingElement
* @mixes OO.ui.mixin.FlaggedElement
*
* @constructor
* @description Create an instance of `mw.widgets.datetime.DateTimeInputWidget`.
* @param {Object} [config] Configuration options
* @param {string} [config.type='datetime'] Whether to act like a 'date', 'time', or 'datetime' input.
* Affects values stored in the relevant `<input>` and the formatting and
* interpretation of values passed to/from
* {@link https://doc.wikimedia.org/oojs-ui/master/js/OO.ui.InputWidget.html#getValue getValue()} and
* {@link https://doc.wikimedia.org/oojs-ui/master/js/OO.ui.InputWidget.html#setValue setValue()}.
* It's up to the user to configure the DateTimeFormatter correctly.
* @param {Object|mw.widgets.datetime.DateTimeFormatter} [config.formatter={}] Configuration options for
* {@link mw.widgets.datetime.ProlepticGregorianDateTimeFormatter} (with 'format' defaulting to
* '@date', '@time', or '@datetime' depending on 'type'), or an
* {@link mw.widgets.datetime.DateTimeFormatter} instance to use.
* @param {Object|null} [config.calendar={}] Configuration options for
* {@link mw.widgets.datetime.CalendarWidget}; note certain settings will be forced based on the
* settings passed to this widget. Set null to disable the calendar.
* @param {boolean} [config.required=false] Whether a value is required.
* @param {boolean} [config.clearable=true] Whether to provide for blanking the value.
* @param {Date|null} [config.value=null] Default value for the widget
* @param {Date|string|null} [config.min=null] Minimum allowed date
* @param {Date|string|null} [config.max=null] Maximum allowed date
*/
mw
.
widgets
.
datetime
.
DateTimeInputWidget
=
function
MwWidgetsDatetimeDateTimeInputWidget
(
config
)
{
// Configuration initialization
config
=
Object
.
assign
(
{
type
:
'datetime'
,
clearable
:
true
,
required
:
false
,
min
:
null
,
max
:
null
,
formatter
:
{},
calendar
:
{}
},
config
);
// See InputWidget#reusePreInfuseDOM about config.$input
if
(
config
.
$input
)
{
config
.
$input
.
addClass
(
'oo-ui-element-hidden'
);
}
if
(
$
.
isPlainObject
(
config
.
formatter
)
&&
config
.
formatter
.
format
===
undefined
)
{
config
.
formatter
.
format
=
'@'
+
config
.
type
;
}
// Early properties
this
.
type
=
config
.
type
;
// Parent constructor
mw
.
widgets
.
datetime
.
DateTimeInputWidget
.
super
.
call
(
this
,
config
);
// Mixin constructors
OO
.
ui
.
mixin
.
IconElement
.
call
(
this
,
config
);
OO
.
ui
.
mixin
.
IndicatorElement
.
call
(
this
,
config
);
OO
.
ui
.
mixin
.
PendingElement
.
call
(
this
,
config
);
OO
.
ui
.
mixin
.
FlaggedElement
.
call
(
this
,
config
);
// Properties
this
.
$handle
=
$
(
'<span>'
);
this
.
$fields
=
$
(
'<span>'
);
this
.
fields
=
[];
this
.
clearable
=
!!
config
.
clearable
;
this
.
required
=
!!
config
.
required
;
if
(
typeof
config
.
min
===
'string'
)
{
config
.
min
=
this
.
parseDateValue
(
config
.
min
);
}
if
(
config
.
min
instanceof
Date
&&
config
.
min
.
getTime
()
>=
-
62167219200000
)
{
this
.
min
=
config
.
min
;
}
else
{
this
.
min
=
new
Date
(
-
62167219200000
);
// 0000-01-01T00:00:00.000Z
}
if
(
typeof
config
.
max
===
'string'
)
{
config
.
max
=
this
.
parseDateValue
(
config
.
max
);
}
if
(
config
.
max
instanceof
Date
&&
config
.
max
.
getTime
()
<=
253402300799999
)
{
this
.
max
=
config
.
max
;
}
else
{
this
.
max
=
new
Date
(
253402300799999
);
// 9999-12-31T12:59:59.999Z
}
switch
(
this
.
type
)
{
case
'date'
:
this
.
min
.
setUTCHours
(
0
,
0
,
0
,
0
);
this
.
max
.
setUTCHours
(
23
,
59
,
59
,
999
);
break
;
case
'time'
:
this
.
min
.
setUTCFullYear
(
1970
,
0
,
1
);
this
.
max
.
setUTCFullYear
(
1970
,
0
,
1
);
break
;
}
if
(
this
.
min
>
this
.
max
)
{
throw
new
Error
(
'"min" ('
+
this
.
min
.
toISOString
()
+
') must not be greater than '
+
'"max" ('
+
this
.
max
.
toISOString
()
+
')'
);
}
if
(
config
.
formatter
instanceof
mw
.
widgets
.
datetime
.
DateTimeFormatter
)
{
this
.
formatter
=
config
.
formatter
;
}
else
if
(
$
.
isPlainObject
(
config
.
formatter
)
)
{
this
.
formatter
=
new
mw
.
widgets
.
datetime
.
ProlepticGregorianDateTimeFormatter
(
config
.
formatter
);
}
else
{
throw
new
Error
(
'"formatter" must be an mw.widgets.datetime.DateTimeFormatter or a plain object'
);
}
if
(
this
.
type
===
'time'
||
config
.
calendar
===
null
)
{
this
.
calendar
=
null
;
}
else
{
config
.
calendar
=
Object
.
assign
(
{},
config
.
calendar
,
{
formatter
:
this
.
formatter
,
widget
:
this
,
min
:
this
.
min
,
max
:
this
.
max
}
);
this
.
calendar
=
new
mw
.
widgets
.
datetime
.
CalendarWidget
(
config
.
calendar
);
}
// Events
this
.
$handle
.
on
(
{
click
:
this
.
onHandleClick
.
bind
(
this
)
}
);
this
.
connect
(
this
,
{
change
:
'onChange'
}
);
this
.
formatter
.
connect
(
this
,
{
local
:
'onChange'
}
);
if
(
this
.
calendar
)
{
this
.
calendar
.
connect
(
this
,
{
change
:
'onCalendarChange'
}
);
}
// Initialization
this
.
setTabIndex
(
-
1
);
this
.
$fields
.
addClass
(
'mw-widgets-datetime-dateTimeInputWidget-fields'
);
this
.
setupFields
();
this
.
$handle
.
addClass
(
'mw-widgets-datetime-dateTimeInputWidget-handle'
)
.
append
(
this
.
$icon
,
this
.
$indicator
,
this
.
$fields
);
this
.
$element
.
addClass
(
'mw-widgets-datetime-dateTimeInputWidget'
)
.
append
(
this
.
$handle
);
if
(
this
.
calendar
)
{
const
date
=
this
.
getValueAsDate
();
this
.
calendar
.
setSelected
(
date
);
if
(
date
)
{
this
.
calendar
.
setFocusedDate
(
date
);
}
this
.
$element
.
append
(
this
.
calendar
.
$element
);
}
};
/* Setup */
OO
.
inheritClass
(
mw
.
widgets
.
datetime
.
DateTimeInputWidget
,
OO
.
ui
.
InputWidget
);
OO
.
mixinClass
(
mw
.
widgets
.
datetime
.
DateTimeInputWidget
,
OO
.
ui
.
mixin
.
IconElement
);
OO
.
mixinClass
(
mw
.
widgets
.
datetime
.
DateTimeInputWidget
,
OO
.
ui
.
mixin
.
IndicatorElement
);
OO
.
mixinClass
(
mw
.
widgets
.
datetime
.
DateTimeInputWidget
,
OO
.
ui
.
mixin
.
PendingElement
);
OO
.
mixinClass
(
mw
.
widgets
.
datetime
.
DateTimeInputWidget
,
OO
.
ui
.
mixin
.
FlaggedElement
);
/* Static properties */
mw
.
widgets
.
datetime
.
DateTimeInputWidget
.
static
.
supportsSimpleLabel
=
false
;
/* Events */
/* Methods */
/**
* Get the currently focused field, if any.
*
* @private
* @return {jQuery}
*/
mw
.
widgets
.
datetime
.
DateTimeInputWidget
.
prototype
.
getFocusedField
=
function
()
{
return
this
.
$fields
.
find
(
this
.
getElementDocument
().
activeElement
);
};
/**
* Convert a date string to a Date.
*
* @private
* @param {string} value
* @return {Date|null}
*/
mw
.
widgets
.
datetime
.
DateTimeInputWidget
.
prototype
.
parseDateValue
=
function
(
value
)
{
value
=
String
(
value
);
switch
(
this
.
type
)
{
case
'date'
:
value
=
value
+
'T00:00:00Z'
;
break
;
case
'time'
:
value
=
'1970-01-01T'
+
value
+
'Z'
;
break
;
}
let
date
;
const
m
=
/^(\d{4,})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,3}))?Z$/
.
exec
(
value
);
if
(
m
)
{
if
(
m
[
7
]
)
{
while
(
m
[
7
].
length
<
3
)
{
m
[
7
]
+=
'0'
;
}
}
else
{
m
[
7
]
=
0
;
}
date
=
new
Date
();
date
.
setUTCFullYear
(
m
[
1
],
m
[
2
]
-
1
,
m
[
3
]
);
date
.
setUTCHours
(
m
[
4
],
m
[
5
],
m
[
6
],
m
[
7
]
);
if
(
date
.
getTime
()
<
-
62167219200000
||
date
.
getTime
()
>
253402300799999
||
date
.
getUTCFullYear
()
!==
+
m
[
1
]
||
date
.
getUTCMonth
()
+
1
!==
+
m
[
2
]
||
date
.
getUTCDate
()
!==
+
m
[
3
]
||
date
.
getUTCHours
()
!==
+
m
[
4
]
||
date
.
getUTCMinutes
()
!==
+
m
[
5
]
||
date
.
getUTCSeconds
()
!==
+
m
[
6
]
||
date
.
getUTCMilliseconds
()
!==
+
m
[
7
]
)
{
date
=
null
;
}
}
else
{
date
=
null
;
}
return
date
;
};
/**
* @inheritdoc
*/
mw
.
widgets
.
datetime
.
DateTimeInputWidget
.
prototype
.
cleanUpValue
=
function
(
value
)
{
let
date
,
pad
;
if
(
value
===
''
)
{
return
''
;
}
if
(
value
instanceof
Date
)
{
date
=
value
;
}
else
{
date
=
this
.
parseDateValue
(
value
);
}
if
(
date
instanceof
Date
)
{
pad
=
function
(
v
,
l
)
{
v
=
String
(
v
);
while
(
v
.
length
<
l
)
{
v
=
'0'
+
v
;
}
return
v
;
};
switch
(
this
.
type
)
{
case
'date'
:
value
=
pad
(
date
.
getUTCFullYear
(),
4
)
+
'-'
+
pad
(
date
.
getUTCMonth
()
+
1
,
2
)
+
'-'
+
pad
(
date
.
getUTCDate
(),
2
);
break
;
case
'time'
:
value
=
pad
(
date
.
getUTCHours
(),
2
)
+
':'
+
pad
(
date
.
getUTCMinutes
(),
2
)
+
':'
+
pad
(
date
.
getUTCSeconds
(),
2
)
+
'.'
+
pad
(
date
.
getUTCMilliseconds
(),
3
);
value
=
value
.
replace
(
/\.?0+$/
,
''
);
break
;
default
:
value
=
date
.
toISOString
();
break
;
}
}
else
{
value
=
''
;
}
return
value
;
};
/**
* Get the value of the input as a Date object.
*
* @return {Date|null}
*/
mw
.
widgets
.
datetime
.
DateTimeInputWidget
.
prototype
.
getValueAsDate
=
function
()
{
return
this
.
parseDateValue
(
this
.
getValue
()
);
};
/**
* Set up the UI fields.
*
* @private
*/
mw
.
widgets
.
datetime
.
DateTimeInputWidget
.
prototype
.
setupFields
=
function
()
{
let
i
,
$field
,
spec
,
placeholder
,
sz
,
maxlength
;
const
spanValFunc
=
function
(
v
)
{
if
(
v
===
undefined
)
{
return
this
.
data
(
'mw-widgets-datetime-dateTimeInputWidget-value'
);
}
else
{
v
=
String
(
v
);
this
.
data
(
'mw-widgets-datetime-dateTimeInputWidget-value'
,
v
);
if
(
v
===
''
)
{
v
=
this
.
data
(
'mw-widgets-datetime-dateTimeInputWidget-placeholder'
);
}
this
.
text
(
v
);
return
this
;
}
},
reduceFunc
=
function
(
k
,
v
)
{
maxlength
=
Math
.
max
(
maxlength
,
v
);
},
disabled
=
this
.
isDisabled
(),
specs
=
this
.
formatter
.
getFieldSpec
();
this
.
$fields
.
empty
();
this
.
clearButton
=
null
;
this
.
fields
=
[];
for
(
i
=
0
;
i
<
specs
.
length
;
i
++
)
{
spec
=
specs
[
i
];
if
(
typeof
spec
===
'string'
)
{
$
(
'<span>'
)
.
addClass
(
'mw-widgets-datetime-dateTimeInputWidget-field'
)
.
text
(
spec
)
.
appendTo
(
this
.
$fields
);
continue
;
}
placeholder
=
''
;
while
(
placeholder
.
length
<
spec
.
size
)
{
placeholder
+=
'_'
;
}
if
(
spec
.
type
===
'number'
)
{
sz
=
spec
.
size
+
'ch'
;
}
else
{
// Add a little for padding
sz
=
(
spec
.
size
*
1.25
)
+
'ch'
;
}
if
(
spec
.
editable
&&
spec
.
type
!==
'static'
)
{
if
(
spec
.
type
===
'boolean'
||
spec
.
type
===
'toggleLocal'
)
{
$field
=
$
(
'<span>'
)
.
attr
(
{
tabindex
:
disabled
?
-
1
:
0
}
)
.
width
(
sz
)
.
data
(
'mw-widgets-datetime-dateTimeInputWidget-placeholder'
,
placeholder
);
$field
.
on
(
{
keydown
:
this
.
onFieldKeyDown
.
bind
(
this
,
$field
),
focus
:
this
.
onFieldFocus
.
bind
(
this
,
$field
),
click
:
this
.
onFieldClick
.
bind
(
this
,
$field
),
'wheel mousewheel DOMMouseScroll'
:
this
.
onFieldWheel
.
bind
(
this
,
$field
)
}
);
$field
.
val
=
spanValFunc
;
}
else
{
maxlength
=
spec
.
size
;
if
(
spec
.
intercalarySize
)
{
// eslint-disable-next-line no-jquery/no-each-util
$
.
each
(
spec
.
intercalarySize
,
reduceFunc
);
}
$field
=
$
(
'<input>'
).
attr
(
'type'
,
'text'
)
.
attr
(
{
tabindex
:
disabled
?
-
1
:
0
,
size
:
spec
.
size
,
maxlength
:
maxlength
}
)
.
prop
(
{
disabled
:
disabled
,
placeholder
:
placeholder
}
)
.
width
(
sz
);
$field
.
on
(
{
keydown
:
this
.
onFieldKeyDown
.
bind
(
this
,
$field
),
click
:
this
.
onFieldClick
.
bind
(
this
,
$field
),
focus
:
this
.
onFieldFocus
.
bind
(
this
,
$field
),
blur
:
this
.
onFieldBlur
.
bind
(
this
,
$field
),
change
:
this
.
onFieldChange
.
bind
(
this
,
$field
),
'wheel mousewheel DOMMouseScroll'
:
this
.
onFieldWheel
.
bind
(
this
,
$field
)
}
);
}
$field
.
addClass
(
'mw-widgets-datetime-dateTimeInputWidget-editField'
);
}
else
{
$field
=
$
(
'<span>'
)
.
width
(
sz
)
.
data
(
'mw-widgets-datetime-dateTimeInputWidget-placeholder'
,
placeholder
);
if
(
spec
.
type
!==
'static'
)
{
$field
.
prop
(
'tabIndex'
,
-
1
);
$field
.
on
(
'focus'
,
this
.
onFieldFocus
.
bind
(
this
,
$field
)
);
}
if
(
spec
.
type
===
'static'
)
{
$field
.
text
(
spec
.
value
);
}
else
{
$field
.
val
=
spanValFunc
;
}
}
this
.
fields
.
push
(
$field
);
$field
.
addClass
(
'mw-widgets-datetime-dateTimeInputWidget-field'
)
.
data
(
'mw-widgets-datetime-dateTimeInputWidget-fieldSpec'
,
spec
)
.
appendTo
(
this
.
$fields
);
}
if
(
this
.
clearable
)
{
this
.
clearButton
=
new
OO
.
ui
.
ButtonWidget
(
{
classes
:
[
'mw-widgets-datetime-dateTimeInputWidget-field'
,
'mw-widgets-datetime-dateTimeInputWidget-clearButton'
],
framed
:
false
,
icon
:
'clear'
,
disabled
:
disabled
}
).
connect
(
this
,
{
click
:
'onClearClick'
}
);
this
.
$fields
.
append
(
this
.
clearButton
.
$element
);
}
this
.
updateFieldsFromValue
();
};
/**
* Update the UI fields from the current value.
*
* @private
*/
mw
.
widgets
.
datetime
.
DateTimeInputWidget
.
prototype
.
updateFieldsFromValue
=
function
()
{
let
i
,
$field
,
spec
,
intercalary
,
sz
;
const
date
=
this
.
getValueAsDate
();
if
(
date
===
null
)
{
this
.
components
=
null
;
for
(
i
=
0
;
i
<
this
.
fields
.
length
;
i
++
)
{
$field
=
this
.
fields
[
i
];
spec
=
$field
.
data
(
'mw-widgets-datetime-dateTimeInputWidget-fieldSpec'
);
$field
.
removeClass
(
'mw-widgets-datetime-dateTimeInputWidget-invalid oo-ui-element-hidden'
)
.
val
(
''
);
if
(
spec
.
intercalarySize
)
{
if
(
spec
.
type
===
'number'
)
{
$field
.
width
(
spec
.
size
+
'ch'
);
}
else
{
// Add a little for padding
$field
.
width
(
(
spec
.
size
*
1.25
)
+
'ch'
);
}
}
}
this
.
setFlags
(
{
invalid
:
this
.
required
}
);
}
else
{
this
.
components
=
this
.
formatter
.
getComponentsFromDate
(
date
);
intercalary
=
this
.
components
.
intercalary
;
for
(
i
=
0
;
i
<
this
.
fields
.
length
;
i
++
)
{
$field
=
this
.
fields
[
i
];
$field
.
removeClass
(
'mw-widgets-datetime-dateTimeInputWidget-invalid'
);
spec
=
$field
.
data
(
'mw-widgets-datetime-dateTimeInputWidget-fieldSpec'
);
if
(
spec
.
type
!==
'static'
)
{
$field
.
val
(
spec
.
formatValue
(
this
.
components
[
spec
.
component
]
)
);
}
if
(
spec
.
intercalarySize
)
{
if
(
intercalary
&&
spec
.
intercalarySize
[
intercalary
]
!==
undefined
)
{
sz
=
spec
.
intercalarySize
[
intercalary
];
}
else
{
sz
=
spec
.
size
;
}
$field
.
toggleClass
(
'oo-ui-element-hidden'
,
sz
<=
0
);
if
(
spec
.
type
===
'number'
)
{
this
.
fields
[
i
].
width
(
sz
+
'ch'
);
}
else
{
// Add a little for padding
this
.
fields
[
i
].
width
(
(
sz
*
1.25
)
+
'ch'
);
}
}
}
this
.
setFlags
(
{
invalid
:
date
<
this
.
min
||
date
>
this
.
max
}
);
}
this
.
$element
.
toggleClass
(
'mw-widgets-datetime-dateTimeInputWidget-empty'
,
date
===
null
);
};
/**
* Update the value with data from the UI fields.
*
* @private
*/
mw
.
widgets
.
datetime
.
DateTimeInputWidget
.
prototype
.
updateValueFromFields
=
function
()
{
let
i
,
v
,
$field
,
spec
,
curDate
,
newDate
,
anyInvalid
=
false
,
anyEmpty
=
false
,
allEmpty
=
true
;
const
components
=
{};
for
(
i
=
0
;
i
<
this
.
fields
.
length
;
i
++
)
{
$field
=
this
.
fields
[
i
];
spec
=
$field
.
data
(
'mw-widgets-datetime-dateTimeInputWidget-fieldSpec'
);
if
(
spec
.
editable
)
{
$field
.
removeClass
(
'mw-widgets-datetime-dateTimeInputWidget-invalid'
);
v
=
$field
.
val
();
if
(
v
===
''
)
{
$field
.
addClass
(
'mw-widgets-datetime-dateTimeInputWidget-invalid'
);
anyEmpty
=
true
;
}
else
{
allEmpty
=
false
;
v
=
spec
.
parseValue
(
v
);
if
(
v
===
undefined
)
{
$field
.
addClass
(
'mw-widgets-datetime-dateTimeInputWidget-invalid'
);
anyInvalid
=
true
;
}
else
{
components
[
spec
.
component
]
=
v
;
}
}
}
}
if
(
allEmpty
)
{
for
(
i
=
0
;
i
<
this
.
fields
.
length
;
i
++
)
{
this
.
fields
[
i
].
removeClass
(
'mw-widgets-datetime-dateTimeInputWidget-invalid'
);
}
}
else
if
(
anyEmpty
)
{
anyInvalid
=
true
;
}
if
(
!
anyInvalid
)
{
curDate
=
this
.
getValueAsDate
();
newDate
=
this
.
formatter
.
getDateFromComponents
(
components
);
if
(
!
curDate
||
!
newDate
||
curDate
.
getTime
()
!==
newDate
.
getTime
()
)
{
this
.
setValue
(
newDate
);
}
}
};
/**
* Handle change event.
*
* @private
*/
mw
.
widgets
.
datetime
.
DateTimeInputWidget
.
prototype
.
onChange
=
function
()
{
let
date
;
this
.
updateFieldsFromValue
();
if
(
this
.
calendar
)
{
date
=
this
.
getValueAsDate
();
this
.
calendar
.
setSelected
(
date
);
if
(
date
)
{
this
.
calendar
.
setFocusedDate
(
date
);
}
}
};
/**
* Handle clear button click event.
*
* @private
*/
mw
.
widgets
.
datetime
.
DateTimeInputWidget
.
prototype
.
onClearClick
=
function
()
{
this
.
blur
().
setValue
(
''
);
};
/**
* Handle click on the widget background.
*
* @private
* @param {jQuery.Event} e Click event
*/
mw
.
widgets
.
datetime
.
DateTimeInputWidget
.
prototype
.
onHandleClick
=
function
()
{
this
.
focus
();
};
/**
* Handle key down events on our field inputs.
*
* @private
* @param {jQuery} $field
* @param {jQuery.Event} e Key down event
* @return {boolean|undefined} False to cancel the default event
*/
mw
.
widgets
.
datetime
.
DateTimeInputWidget
.
prototype
.
onFieldKeyDown
=
function
(
$field
,
e
)
{
const
spec
=
$field
.
data
(
'mw-widgets-datetime-dateTimeInputWidget-fieldSpec'
);
if
(
!
this
.
isDisabled
()
)
{
switch
(
e
.
which
)
{
case
OO
.
ui
.
Keys
.
ENTER
:
case
OO
.
ui
.
Keys
.
SPACE
:
if
(
spec
.
type
===
'boolean'
)
{
this
.
setValue
(
this
.
formatter
.
adjustComponent
(
this
.
getValueAsDate
(),
spec
.
component
,
1
,
'wrap'
)
);
return
false
;
}
else
if
(
spec
.
type
===
'toggleLocal'
)
{
this
.
formatter
.
toggleLocal
();
}
break
;
case
OO
.
ui
.
Keys
.
UP
:
case
OO
.
ui
.
Keys
.
DOWN
:
if
(
spec
.
type
===
'toggleLocal'
)
{
this
.
formatter
.
toggleLocal
();
}
else
{
this
.
setValue
(
this
.
formatter
.
adjustComponent
(
this
.
getValueAsDate
(),
spec
.
component
,
e
.
keyCode
===
OO
.
ui
.
Keys
.
UP
?
-
1
:
1
,
'wrap'
)
);
}
if
(
$field
.
is
(
'input'
)
)
{
$field
.
trigger
(
'select'
);
}
return
false
;
}
}
};
/**
* Handle focus events on our field inputs.
*
* @private
* @param {jQuery} $field
* @param {jQuery.Event} e Focus event
*/
mw
.
widgets
.
datetime
.
DateTimeInputWidget
.
prototype
.
onFieldFocus
=
function
(
$field
)
{
const
spec
=
$field
.
data
(
'mw-widgets-datetime-dateTimeInputWidget-fieldSpec'
);
if
(
!
this
.
isDisabled
()
)
{
if
(
this
.
getValueAsDate
()
===
null
)
{
this
.
setValue
(
this
.
formatter
.
getDefaultDate
()
);
}
if
(
$field
.
is
(
'input'
)
)
{
$field
.
trigger
(
'select'
);
}
if
(
this
.
calendar
)
{
this
.
calendar
.
toggle
(
!!
spec
.
calendarComponent
);
}
}
};
/**
* Handle click events on our field inputs.
*
* @private
* @param {jQuery} $field
* @param {jQuery.Event} e Click event
*/
mw
.
widgets
.
datetime
.
DateTimeInputWidget
.
prototype
.
onFieldClick
=
function
(
$field
)
{
const
spec
=
$field
.
data
(
'mw-widgets-datetime-dateTimeInputWidget-fieldSpec'
);
if
(
!
this
.
isDisabled
()
)
{
if
(
spec
.
type
===
'boolean'
)
{
this
.
setValue
(
this
.
formatter
.
adjustComponent
(
this
.
getValueAsDate
(),
spec
.
component
,
1
,
'wrap'
)
);
}
else
if
(
spec
.
type
===
'toggleLocal'
)
{
this
.
formatter
.
toggleLocal
();
}
}
};
/**
* Handle blur events on our field inputs.
*
* @private
* @param {jQuery} $field
* @param {jQuery.Event} e Blur event
*/
mw
.
widgets
.
datetime
.
DateTimeInputWidget
.
prototype
.
onFieldBlur
=
function
(
$field
)
{
let
v
;
const
spec
=
$field
.
data
(
'mw-widgets-datetime-dateTimeInputWidget-fieldSpec'
);
this
.
updateValueFromFields
();
// Normalize
const
date
=
this
.
getValueAsDate
();
if
(
!
date
)
{
$field
.
val
(
''
);
}
else
{
v
=
spec
.
formatValue
(
this
.
formatter
.
getComponentsFromDate
(
date
)[
spec
.
component
]
);
if
(
v
!==
$field
.
val
()
)
{
$field
.
val
(
v
);
}
}
};
/**
* Handle change events on our field inputs.
*
* @private
* @param {jQuery} $field
* @param {jQuery.Event} e Change event
*/
mw
.
widgets
.
datetime
.
DateTimeInputWidget
.
prototype
.
onFieldChange
=
function
()
{
this
.
updateValueFromFields
();
};
/**
* Handle wheel events on our field inputs.
*
* @private
* @param {jQuery} $field
* @param {jQuery.Event} e Change event
* @return {boolean|undefined} False to cancel the default event
*/
mw
.
widgets
.
datetime
.
DateTimeInputWidget
.
prototype
.
onFieldWheel
=
function
(
$field
,
e
)
{
let
delta
=
0
;
const
spec
=
$field
.
data
(
'mw-widgets-datetime-dateTimeInputWidget-fieldSpec'
);
if
(
this
.
isDisabled
()
||
!
this
.
getFocusedField
().
length
)
{
return
;
}
// Standard 'wheel' event
if
(
e
.
originalEvent
.
deltaMode
!==
undefined
)
{
this
.
sawWheelEvent
=
true
;
}
if
(
e
.
originalEvent
.
deltaY
)
{
delta
=
-
e
.
originalEvent
.
deltaY
;
}
else
if
(
e
.
originalEvent
.
deltaX
)
{
delta
=
e
.
originalEvent
.
deltaX
;
}
// Non-standard events
if
(
!
this
.
sawWheelEvent
)
{
if
(
e
.
originalEvent
.
wheelDeltaX
)
{
delta
=
-
e
.
originalEvent
.
wheelDeltaX
;
}
else
if
(
e
.
originalEvent
.
wheelDeltaY
)
{
delta
=
e
.
originalEvent
.
wheelDeltaY
;
}
else
if
(
e
.
originalEvent
.
wheelDelta
)
{
delta
=
e
.
originalEvent
.
wheelDelta
;
}
else
if
(
e
.
originalEvent
.
detail
)
{
delta
=
-
e
.
originalEvent
.
detail
;
}
}
if
(
delta
&&
spec
)
{
if
(
spec
.
type
===
'toggleLocal'
)
{
this
.
formatter
.
toggleLocal
();
}
else
{
this
.
setValue
(
this
.
formatter
.
adjustComponent
(
this
.
getValueAsDate
(),
spec
.
component
,
delta
<
0
?
-
1
:
1
,
'wrap'
)
);
}
return
false
;
}
};
/**
* Handle calendar change event.
*
* @private
*/
mw
.
widgets
.
datetime
.
DateTimeInputWidget
.
prototype
.
onCalendarChange
=
function
()
{
const
curDate
=
this
.
getValueAsDate
(),
newDate
=
this
.
calendar
.
getSelected
()[
0
];
if
(
newDate
)
{
if
(
!
curDate
||
newDate
.
getTime
()
!==
curDate
.
getTime
()
)
{
this
.
setValue
(
newDate
);
}
}
};
/**
* @inheritdoc
* @private
*/
mw
.
widgets
.
datetime
.
DateTimeInputWidget
.
prototype
.
getInputElement
=
function
()
{
return
$
(
'<input>'
).
attr
(
'type'
,
'hidden'
);
};
/**
* @inheritdoc
*/
mw
.
widgets
.
datetime
.
DateTimeInputWidget
.
prototype
.
setDisabled
=
function
(
disabled
)
{
mw
.
widgets
.
datetime
.
DateTimeInputWidget
.
super
.
prototype
.
setDisabled
.
call
(
this
,
disabled
);
// Flag all our fields as disabled
if
(
this
.
$fields
)
{
this
.
$fields
.
find
(
'input'
).
prop
(
'disabled'
,
this
.
isDisabled
()
);
this
.
$fields
.
find
(
'[tabindex]'
).
attr
(
'tabindex'
,
this
.
isDisabled
()
?
-
1
:
0
);
}
if
(
this
.
clearButton
)
{
this
.
clearButton
.
setDisabled
(
disabled
);
}
return
this
;
};
/**
* @inheritdoc
*/
mw
.
widgets
.
datetime
.
DateTimeInputWidget
.
prototype
.
focus
=
function
()
{
if
(
!
this
.
getFocusedField
().
length
)
{
this
.
$fields
.
find
(
'.mw-widgets-datetime-dateTimeInputWidget-editField'
).
first
().
trigger
(
'focus'
);
}
return
this
;
};
/**
* @inheritdoc
*/
mw
.
widgets
.
datetime
.
DateTimeInputWidget
.
prototype
.
blur
=
function
()
{
this
.
getFocusedField
().
blur
();
return
this
;
};
/**
* @inheritdoc
*/
mw
.
widgets
.
datetime
.
DateTimeInputWidget
.
prototype
.
simulateLabelClick
=
function
()
{
this
.
focus
();
};
}()
);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Oct 4 2026, 09:27 (5 w, 2 d ago)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
8c/e0/e594d0b4283d3926cc3636d29a67
Default Alt Text
DateTimeInputWidget.js (23 KB)
Attached To
Mode
rMWPROD MediaWiki Production
Attached
Detach File
Event Timeline
Log In to Comment