Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
jinli gu
MCMS
Commits
a866cd37
Commit
a866cd37
authored
Jun 22, 2020
by
panpp
Browse files
static init
parent
5c8b50e7
Changes
372
Hide whitespace changes
Inline
Side-by-side
Too many changes to show.
To preserve performance only
20 of 372+
files are displayed.
Plain diff
Email patch
src/main/webapp/static/plugins/pickadate/3.5.6/compressed/translations/th_TH.js
0 → 100644
View file @
a866cd37
jQuery
.
extend
(
jQuery
.
fn
.
pickadate
.
defaults
,{
monthsFull
:[
"
มกราคม
"
,
"
กุมภาพันธ์
"
,
"
มีนาคม
"
,
"
เมษายน
"
,
"
พฤษภาคม
"
,
"
มิถุนายน
"
,
"
กรกฎาคม
"
,
"
สิงหาคม
"
,
"
กันยายน
"
,
"
ตุลาคม
"
,
"
พฤศจิกายน
"
,
"
ธันวาคม
"
],
monthsShort
:[
"
ม.ค.
"
,
"
ก.พ.
"
,
"
มี.ค.
"
,
"
เม.ย.
"
,
"
พ.ค.
"
,
"
มิ.ย.
"
,
"
ก.ค.
"
,
"
ส.ค.
"
,
"
ก.ย.
"
,
"
ต.ค.
"
,
"
พ.ย.
"
,
"
ธ.ค.
"
],
weekdaysFull
:[
"
อาทติย
"
,
"
จันทร
"
,
"
องัคาร
"
,
"
พุธ
"
,
"
พฤหสั บดี
"
,
"
ศกุร
"
,
"
เสาร
"
],
weekdaysShort
:[
"
อ.
"
,
"
จ.
"
,
"
อ.
"
,
"
พ.
"
,
"
พฤ.
"
,
"
ศ.
"
,
"
ส.
"
],
today
:
"
วันนี้
"
,
clear
:
"
ลบ
"
,
format
:
"
d mmmm yyyy
"
,
formatSubmit
:
"
yyyy/mm/dd
"
}),
jQuery
.
extend
(
jQuery
.
fn
.
pickatime
.
defaults
,{
clear
:
"
ลบ
"
});
\ No newline at end of file
src/main/webapp/static/plugins/pickadate/3.5.6/compressed/translations/tr_TR.js
0 → 100644
View file @
a866cd37
jQuery
.
extend
(
jQuery
.
fn
.
pickadate
.
defaults
,{
monthsFull
:[
"
Ocak
"
,
"
Şubat
"
,
"
Mart
"
,
"
Nisan
"
,
"
Mayıs
"
,
"
Haziran
"
,
"
Temmuz
"
,
"
Ağustos
"
,
"
Eylül
"
,
"
Ekim
"
,
"
Kasım
"
,
"
Aralık
"
],
monthsShort
:[
"
Oca
"
,
"
Şub
"
,
"
Mar
"
,
"
Nis
"
,
"
May
"
,
"
Haz
"
,
"
Tem
"
,
"
Ağu
"
,
"
Eyl
"
,
"
Eki
"
,
"
Kas
"
,
"
Ara
"
],
weekdaysFull
:[
"
Pazar
"
,
"
Pazartesi
"
,
"
Salı
"
,
"
Çarşamba
"
,
"
Perşembe
"
,
"
Cuma
"
,
"
Cumartesi
"
],
weekdaysShort
:[
"
Pzr
"
,
"
Pzt
"
,
"
Sal
"
,
"
Çrş
"
,
"
Prş
"
,
"
Cum
"
,
"
Cmt
"
],
today
:
"
Bugün
"
,
clear
:
"
Sil
"
,
close
:
"
Kapat
"
,
firstDay
:
1
,
format
:
"
dd mmmm yyyy dddd
"
,
formatSubmit
:
"
yyyy/mm/dd
"
}),
jQuery
.
extend
(
jQuery
.
fn
.
pickatime
.
defaults
,{
clear
:
"
sil
"
});
\ No newline at end of file
src/main/webapp/static/plugins/pickadate/3.5.6/compressed/translations/uk_UA.js
0 → 100644
View file @
a866cd37
jQuery
.
extend
(
jQuery
.
fn
.
pickadate
.
defaults
,{
monthsFull
:[
"
січень
"
,
"
лютий
"
,
"
березень
"
,
"
квітень
"
,
"
травень
"
,
"
червень
"
,
"
липень
"
,
"
серпень
"
,
"
вересень
"
,
"
жовтень
"
,
"
листопад
"
,
"
грудень
"
],
monthsShort
:[
"
січ
"
,
"
лют
"
,
"
бер
"
,
"
кві
"
,
"
тра
"
,
"
чер
"
,
"
лип
"
,
"
сер
"
,
"
вер
"
,
"
жов
"
,
"
лис
"
,
"
гру
"
],
weekdaysFull
:[
"
неділя
"
,
"
понеділок
"
,
"
вівторок
"
,
"
середа
"
,
"
четвер
"
,
"
п‘ятниця
"
,
"
субота
"
],
weekdaysShort
:[
"
нд
"
,
"
пн
"
,
"
вт
"
,
"
ср
"
,
"
чт
"
,
"
пт
"
,
"
сб
"
],
today
:
"
сьогодні
"
,
clear
:
"
викреслити
"
,
firstDay
:
1
,
format
:
"
dd mmmm yyyy p.
"
,
formatSubmit
:
"
yyyy/mm/dd
"
}),
jQuery
.
extend
(
jQuery
.
fn
.
pickatime
.
defaults
,{
clear
:
"
викреслити
"
});
\ No newline at end of file
src/main/webapp/static/plugins/pickadate/3.5.6/compressed/translations/vi_VN.js
0 → 100644
View file @
a866cd37
jQuery
.
extend
(
jQuery
.
fn
.
pickadate
.
defaults
,{
monthsFull
:[
"
Tháng Một
"
,
"
Tháng Hai
"
,
"
Tháng Ba
"
,
"
Tháng Tư
"
,
"
Tháng Năm
"
,
"
Tháng Sáu
"
,
"
Tháng Bảy
"
,
"
Tháng Tám
"
,
"
Tháng Chín
"
,
"
Tháng Mười
"
,
"
Tháng Mười Một
"
,
"
Tháng Mười Hai
"
],
monthsShort
:[
"
Một
"
,
"
Hai
"
,
"
Ba
"
,
"
Tư
"
,
"
Năm
"
,
"
Sáu
"
,
"
Bảy
"
,
"
Tám
"
,
"
Chín
"
,
"
Mưới
"
,
"
Mười Một
"
,
"
Mười Hai
"
],
weekdaysFull
:[
"
Chủ Nhật
"
,
"
Thứ Hai
"
,
"
Thứ Ba
"
,
"
Thứ Tư
"
,
"
Thứ Năm
"
,
"
Thứ Sáu
"
,
"
Thứ Bảy
"
],
weekdaysShort
:[
"
C.Nhật
"
,
"
T.Hai
"
,
"
T.Ba
"
,
"
T.Tư
"
,
"
T.Năm
"
,
"
T.Sáu
"
,
"
T.Bảy
"
],
today
:
"
Hôm Nay
"
,
clear
:
"
Xoá
"
,
firstDay
:
1
}),
jQuery
.
extend
(
jQuery
.
fn
.
pickatime
.
defaults
,{
clear
:
"
Xoá
"
});
\ No newline at end of file
src/main/webapp/static/plugins/pickadate/3.5.6/compressed/translations/zh_CN.js
0 → 100644
View file @
a866cd37
jQuery
.
extend
(
jQuery
.
fn
.
pickadate
.
defaults
,{
monthsFull
:[
"
一月
"
,
"
二月
"
,
"
三月
"
,
"
四月
"
,
"
五月
"
,
"
六月
"
,
"
七月
"
,
"
八月
"
,
"
九月
"
,
"
十月
"
,
"
十一月
"
,
"
十二月
"
],
monthsShort
:[
"
一
"
,
"
二
"
,
"
三
"
,
"
四
"
,
"
五
"
,
"
六
"
,
"
七
"
,
"
八
"
,
"
九
"
,
"
十
"
,
"
十一
"
,
"
十二
"
],
weekdaysFull
:[
"
星期日
"
,
"
星期一
"
,
"
星期二
"
,
"
星期三
"
,
"
星期四
"
,
"
星期五
"
,
"
星期六
"
],
weekdaysShort
:[
"
日
"
,
"
一
"
,
"
二
"
,
"
三
"
,
"
四
"
,
"
五
"
,
"
六
"
],
today
:
"
今日
"
,
clear
:
"
清除
"
,
close
:
"
关闭
"
,
firstDay
:
1
,
format
:
"
yyyy 年 mm 月 dd 日
"
,
formatSubmit
:
"
yyyy/mm/dd
"
}),
jQuery
.
extend
(
jQuery
.
fn
.
pickatime
.
defaults
,{
clear
:
"
清除
"
});
\ No newline at end of file
src/main/webapp/static/plugins/pickadate/3.5.6/compressed/translations/zh_TW.js
0 → 100644
View file @
a866cd37
jQuery
.
extend
(
jQuery
.
fn
.
pickadate
.
defaults
,{
monthsFull
:[
"
一月
"
,
"
二月
"
,
"
三月
"
,
"
四月
"
,
"
五月
"
,
"
六月
"
,
"
七月
"
,
"
八月
"
,
"
九月
"
,
"
十月
"
,
"
十一月
"
,
"
十二月
"
],
monthsShort
:[
"
一
"
,
"
二
"
,
"
三
"
,
"
四
"
,
"
五
"
,
"
六
"
,
"
七
"
,
"
八
"
,
"
九
"
,
"
十
"
,
"
十一
"
,
"
十二
"
],
weekdaysFull
:[
"
星期日
"
,
"
星期一
"
,
"
星期二
"
,
"
星期三
"
,
"
星期四
"
,
"
星期五
"
,
"
星期六
"
],
weekdaysShort
:[
"
日
"
,
"
一
"
,
"
二
"
,
"
三
"
,
"
四
"
,
"
五
"
,
"
六
"
],
today
:
"
今天
"
,
clear
:
"
清除
"
,
close
:
"
关闭
"
,
firstDay
:
1
,
format
:
"
yyyy 年 mm 月 dd 日
"
,
formatSubmit
:
"
yyyy/mm/dd
"
}),
jQuery
.
extend
(
jQuery
.
fn
.
pickatime
.
defaults
,{
clear
:
"
清除
"
});
\ No newline at end of file
src/main/webapp/static/plugins/pickadate/3.5.6/legacy.js
0 → 100644
View file @
a866cd37
/*jshint
asi: true,
unused: true,
boss: true,
loopfunc: true,
eqnull: true
*/
/*!
* Legacy browser support
*/
// Map array support
if
(
!
[].
map
)
{
Array
.
prototype
.
map
=
function
(
callback
,
self
)
{
var
array
=
this
,
len
=
array
.
length
,
newArray
=
new
Array
(
len
)
for
(
var
i
=
0
;
i
<
len
;
i
++
)
{
if
(
i
in
array
)
{
newArray
[
i
]
=
callback
.
call
(
self
,
array
[
i
],
i
,
array
)
}
}
return
newArray
}
}
// Filter array support
if
(
!
[].
filter
)
{
Array
.
prototype
.
filter
=
function
(
callback
)
{
if
(
this
==
null
)
throw
new
TypeError
()
var
t
=
Object
(
this
),
len
=
t
.
length
>>>
0
if
(
typeof
callback
!=
'
function
'
)
throw
new
TypeError
()
var
newArray
=
[],
thisp
=
arguments
[
1
]
for
(
var
i
=
0
;
i
<
len
;
i
++
)
{
if
(
i
in
t
)
{
var
val
=
t
[
i
]
if
(
callback
.
call
(
thisp
,
val
,
i
,
t
)
)
newArray
.
push
(
val
)
}
}
return
newArray
}
}
// Index of array support
if
(
!
[].
indexOf
)
{
Array
.
prototype
.
indexOf
=
function
(
searchElement
)
{
if
(
this
==
null
)
throw
new
TypeError
()
var
t
=
Object
(
this
),
len
=
t
.
length
>>>
0
if
(
len
===
0
)
return
-
1
var
n
=
0
if
(
arguments
.
length
>
1
)
{
n
=
Number
(
arguments
[
1
]
)
if
(
n
!=
n
)
{
n
=
0
}
else
if
(
n
!==
0
&&
n
!=
Infinity
&&
n
!=
-
Infinity
)
{
n
=
(
n
>
0
||
-
1
)
*
Math
.
floor
(
Math
.
abs
(
n
)
)
}
}
if
(
n
>=
len
)
return
-
1
var
k
=
n
>=
0
?
n
:
Math
.
max
(
len
-
Math
.
abs
(
n
),
0
)
for
(
;
k
<
len
;
k
++
)
{
if
(
k
in
t
&&
t
[
k
]
===
searchElement
)
return
k
}
return
-
1
}
}
/*!
* Cross-Browser Split 1.1.1
* Copyright 2007-2012 Steven Levithan <stevenlevithan.com>
* Available under the MIT License
* http://blog.stevenlevithan.com/archives/cross-browser-split
*/
var
nativeSplit
=
String
.
prototype
.
split
,
compliantExecNpcg
=
/
()??
/
.
exec
(
''
)[
1
]
===
undefined
String
.
prototype
.
split
=
function
(
separator
,
limit
)
{
var
str
=
this
if
(
Object
.
prototype
.
toString
.
call
(
separator
)
!==
'
[object RegExp]
'
)
{
return
nativeSplit
.
call
(
str
,
separator
,
limit
)
}
var
output
=
[],
flags
=
(
separator
.
ignoreCase
?
'
i
'
:
''
)
+
(
separator
.
multiline
?
'
m
'
:
''
)
+
(
separator
.
extended
?
'
x
'
:
''
)
+
(
separator
.
sticky
?
'
y
'
:
''
),
lastLastIndex
=
0
,
separator2
,
match
,
lastIndex
,
lastLength
separator
=
new
RegExp
(
separator
.
source
,
flags
+
'
g
'
)
str
+=
''
if
(
!
compliantExecNpcg
)
{
separator2
=
new
RegExp
(
'
^
'
+
separator
.
source
+
'
$(?!
\\
s)
'
,
flags
)
}
limit
=
limit
===
undefined
?
-
1
>>>
0
:
limit
>>>
0
while
(
match
=
separator
.
exec
(
str
))
{
lastIndex
=
match
.
index
+
match
[
0
].
length
if
(
lastIndex
>
lastLastIndex
)
{
output
.
push
(
str
.
slice
(
lastLastIndex
,
match
.
index
))
if
(
!
compliantExecNpcg
&&
match
.
length
>
1
)
{
match
[
0
].
replace
(
separator2
,
function
()
{
for
(
var
i
=
1
;
i
<
arguments
.
length
-
2
;
i
++
)
{
if
(
arguments
[
i
]
===
undefined
)
{
match
[
i
]
=
undefined
}
}
})
}
if
(
match
.
length
>
1
&&
match
.
index
<
str
.
length
)
{
Array
.
prototype
.
push
.
apply
(
output
,
match
.
slice
(
1
))
}
lastLength
=
match
[
0
].
length
lastLastIndex
=
lastIndex
if
(
output
.
length
>=
limit
)
{
break
}
}
if
(
separator
.
lastIndex
===
match
.
index
)
{
separator
.
lastIndex
++
}
}
if
(
lastLastIndex
===
str
.
length
)
{
if
(
lastLength
||
!
separator
.
test
(
''
))
{
output
.
push
(
''
)
}
}
else
{
output
.
push
(
str
.
slice
(
lastLastIndex
))
}
return
output
.
length
>
limit
?
output
.
slice
(
0
,
limit
)
:
output
};
src/main/webapp/static/plugins/pickadate/3.5.6/picker.date.js
0 → 100644
View file @
a866cd37
/*!
* Date picker for pickadate.js v3.5.6
* http://amsul.github.io/pickadate.js/date.htm
*/
(
function
(
factory
)
{
// AMD.
if
(
typeof
define
==
'
function
'
&&
define
.
amd
)
define
(
[
'
picker
'
,
'
jquery
'
],
factory
)
// Node.js/browserify.
else
if
(
typeof
exports
==
'
object
'
)
module
.
exports
=
factory
(
require
(
'
./picker.js
'
),
require
(
'
jquery
'
)
)
// Browser globals.
else
factory
(
Picker
,
jQuery
)
}(
function
(
Picker
,
$
)
{
/**
* Globals and constants
*/
var
DAYS_IN_WEEK
=
7
,
WEEKS_IN_CALENDAR
=
6
,
_
=
Picker
.
_
/**
* The date picker constructor
*/
function
DatePicker
(
picker
,
settings
)
{
var
calendar
=
this
,
element
=
picker
.
$node
[
0
],
elementValue
=
element
.
value
,
elementDataValue
=
picker
.
$node
.
data
(
'
value
'
),
valueString
=
elementDataValue
||
elementValue
,
formatString
=
elementDataValue
?
settings
.
formatSubmit
:
settings
.
format
,
isRTL
=
function
()
{
return
element
.
currentStyle
?
// For IE.
element
.
currentStyle
.
direction
==
'
rtl
'
:
// For normal browsers.
getComputedStyle
(
picker
.
$root
[
0
]
).
direction
==
'
rtl
'
}
calendar
.
settings
=
settings
calendar
.
$node
=
picker
.
$node
// The queue of methods that will be used to build item objects.
calendar
.
queue
=
{
min
:
'
measure create
'
,
max
:
'
measure create
'
,
now
:
'
now create
'
,
select
:
'
parse create validate
'
,
highlight
:
'
parse navigate create validate
'
,
view
:
'
parse create validate viewset
'
,
disable
:
'
deactivate
'
,
enable
:
'
activate
'
}
// The component's item object.
calendar
.
item
=
{}
calendar
.
item
.
clear
=
null
calendar
.
item
.
disable
=
(
settings
.
disable
||
[]
).
slice
(
0
)
calendar
.
item
.
enable
=
-
(
function
(
collectionDisabled
)
{
return
collectionDisabled
[
0
]
===
true
?
collectionDisabled
.
shift
()
:
-
1
})(
calendar
.
item
.
disable
)
calendar
.
set
(
'
min
'
,
settings
.
min
).
set
(
'
max
'
,
settings
.
max
).
set
(
'
now
'
)
// When there’s a value, set the `select`, which in turn
// also sets the `highlight` and `view`.
if
(
valueString
)
{
calendar
.
set
(
'
select
'
,
valueString
,
{
format
:
formatString
,
defaultValue
:
true
})
}
// If there’s no value, default to highlighting “today”.
else
{
calendar
.
set
(
'
select
'
,
null
).
set
(
'
highlight
'
,
calendar
.
item
.
now
)
}
// The keycode to movement mapping.
calendar
.
key
=
{
40
:
7
,
// Down
38
:
-
7
,
// Up
39
:
function
()
{
return
isRTL
()
?
-
1
:
1
},
// Right
37
:
function
()
{
return
isRTL
()
?
1
:
-
1
},
// Left
go
:
function
(
timeChange
)
{
var
highlightedObject
=
calendar
.
item
.
highlight
,
targetDate
=
new
Date
(
highlightedObject
.
year
,
highlightedObject
.
month
,
highlightedObject
.
date
+
timeChange
)
calendar
.
set
(
'
highlight
'
,
targetDate
,
{
interval
:
timeChange
}
)
this
.
render
()
}
}
// Bind some picker events.
picker
.
on
(
'
render
'
,
function
()
{
picker
.
$root
.
find
(
'
.
'
+
settings
.
klass
.
selectMonth
).
on
(
'
change
'
,
function
()
{
var
value
=
this
.
value
if
(
value
)
{
picker
.
set
(
'
highlight
'
,
[
picker
.
get
(
'
view
'
).
year
,
value
,
picker
.
get
(
'
highlight
'
).
date
]
)
picker
.
$root
.
find
(
'
.
'
+
settings
.
klass
.
selectMonth
).
trigger
(
'
focus
'
)
}
})
picker
.
$root
.
find
(
'
.
'
+
settings
.
klass
.
selectYear
).
on
(
'
change
'
,
function
()
{
var
value
=
this
.
value
if
(
value
)
{
picker
.
set
(
'
highlight
'
,
[
value
,
picker
.
get
(
'
view
'
).
month
,
picker
.
get
(
'
highlight
'
).
date
]
)
picker
.
$root
.
find
(
'
.
'
+
settings
.
klass
.
selectYear
).
trigger
(
'
focus
'
)
}
})
},
1
).
on
(
'
open
'
,
function
()
{
var
includeToday
=
''
if
(
calendar
.
disabled
(
calendar
.
get
(
'
now
'
)
)
)
{
includeToday
=
'
:not(.
'
+
settings
.
klass
.
buttonToday
+
'
)
'
}
picker
.
$root
.
find
(
'
button
'
+
includeToday
+
'
, select
'
).
attr
(
'
disabled
'
,
false
)
},
1
).
on
(
'
close
'
,
function
()
{
picker
.
$root
.
find
(
'
button, select
'
).
attr
(
'
disabled
'
,
true
)
},
1
)
}
//DatePicker
/**
* Set a datepicker item object.
*/
DatePicker
.
prototype
.
set
=
function
(
type
,
value
,
options
)
{
var
calendar
=
this
,
calendarItem
=
calendar
.
item
// If the value is `null` just set it immediately.
if
(
value
===
null
)
{
if
(
type
==
'
clear
'
)
type
=
'
select
'
calendarItem
[
type
]
=
value
return
calendar
}
// Otherwise go through the queue of methods, and invoke the functions.
// Update this as the time unit, and set the final value as this item.
// * In the case of `enable`, keep the queue but set `disable` instead.
// And in the case of `flip`, keep the queue but set `enable` instead.
calendarItem
[
(
type
==
'
enable
'
?
'
disable
'
:
type
==
'
flip
'
?
'
enable
'
:
type
)
]
=
calendar
.
queue
[
type
].
split
(
'
'
).
map
(
function
(
method
)
{
value
=
calendar
[
method
](
type
,
value
,
options
)
return
value
}).
pop
()
// Check if we need to cascade through more updates.
if
(
type
==
'
select
'
)
{
calendar
.
set
(
'
highlight
'
,
calendarItem
.
select
,
options
)
}
else
if
(
type
==
'
highlight
'
)
{
calendar
.
set
(
'
view
'
,
calendarItem
.
highlight
,
options
)
}
else
if
(
type
.
match
(
/^
(
flip|min|max|disable|enable
)
$/
)
)
{
if
(
calendarItem
.
select
&&
calendar
.
disabled
(
calendarItem
.
select
)
)
{
calendar
.
set
(
'
select
'
,
calendarItem
.
select
,
options
)
}
if
(
calendarItem
.
highlight
&&
calendar
.
disabled
(
calendarItem
.
highlight
)
)
{
calendar
.
set
(
'
highlight
'
,
calendarItem
.
highlight
,
options
)
}
}
return
calendar
}
//DatePicker.prototype.set
/**
* Get a datepicker item object.
*/
DatePicker
.
prototype
.
get
=
function
(
type
)
{
return
this
.
item
[
type
]
}
//DatePicker.prototype.get
/**
* Create a picker date object.
*/
DatePicker
.
prototype
.
create
=
function
(
type
,
value
,
options
)
{
var
isInfiniteValue
,
calendar
=
this
// If there’s no value, use the type as the value.
value
=
value
===
undefined
?
type
:
value
// If it’s infinity, update the value.
if
(
value
==
-
Infinity
||
value
==
Infinity
)
{
isInfiniteValue
=
value
}
// If it’s an object, use the native date object.
else
if
(
$
.
isPlainObject
(
value
)
&&
_
.
isInteger
(
value
.
pick
)
)
{
value
=
value
.
obj
}
// If it’s an array, convert it into a date and make sure
// that it’s a valid date – otherwise default to today.
else
if
(
$
.
isArray
(
value
)
)
{
value
=
new
Date
(
value
[
0
],
value
[
1
],
value
[
2
]
)
value
=
_
.
isDate
(
value
)
?
value
:
calendar
.
create
().
obj
}
// If it’s a number or date object, make a normalized date.
else
if
(
_
.
isInteger
(
value
)
||
_
.
isDate
(
value
)
)
{
value
=
calendar
.
normalize
(
new
Date
(
value
),
options
)
}
// If it’s a literal true or any other case, set it to now.
else
/*if ( value === true )*/
{
value
=
calendar
.
now
(
type
,
value
,
options
)
}
// Return the compiled object.
return
{
year
:
isInfiniteValue
||
value
.
getFullYear
(),
month
:
isInfiniteValue
||
value
.
getMonth
(),
date
:
isInfiniteValue
||
value
.
getDate
(),
day
:
isInfiniteValue
||
value
.
getDay
(),
obj
:
isInfiniteValue
||
value
,
pick
:
isInfiniteValue
||
value
.
getTime
()
}
}
//DatePicker.prototype.create
/**
* Create a range limit object using an array, date object,
* literal “true”, or integer relative to another time.
*/
DatePicker
.
prototype
.
createRange
=
function
(
from
,
to
)
{
var
calendar
=
this
,
createDate
=
function
(
date
)
{
if
(
date
===
true
||
$
.
isArray
(
date
)
||
_
.
isDate
(
date
)
)
{
return
calendar
.
create
(
date
)
}
return
date
}
// Create objects if possible.
if
(
!
_
.
isInteger
(
from
)
)
{
from
=
createDate
(
from
)
}
if
(
!
_
.
isInteger
(
to
)
)
{
to
=
createDate
(
to
)
}
// Create relative dates.
if
(
_
.
isInteger
(
from
)
&&
$
.
isPlainObject
(
to
)
)
{
from
=
[
to
.
year
,
to
.
month
,
to
.
date
+
from
];
}
else
if
(
_
.
isInteger
(
to
)
&&
$
.
isPlainObject
(
from
)
)
{
to
=
[
from
.
year
,
from
.
month
,
from
.
date
+
to
];
}
return
{
from
:
createDate
(
from
),
to
:
createDate
(
to
)
}
}
//DatePicker.prototype.createRange
/**
* Check if a date unit falls within a date range object.
*/
DatePicker
.
prototype
.
withinRange
=
function
(
range
,
dateUnit
)
{
range
=
this
.
createRange
(
range
.
from
,
range
.
to
)
return
dateUnit
.
pick
>=
range
.
from
.
pick
&&
dateUnit
.
pick
<=
range
.
to
.
pick
}
/**
* Check if two date range objects overlap.
*/
DatePicker
.
prototype
.
overlapRanges
=
function
(
one
,
two
)
{
var
calendar
=
this
// Convert the ranges into comparable dates.
one
=
calendar
.
createRange
(
one
.
from
,
one
.
to
)
two
=
calendar
.
createRange
(
two
.
from
,
two
.
to
)
return
calendar
.
withinRange
(
one
,
two
.
from
)
||
calendar
.
withinRange
(
one
,
two
.
to
)
||
calendar
.
withinRange
(
two
,
one
.
from
)
||
calendar
.
withinRange
(
two
,
one
.
to
)
}
/**
* Get the date today.
*/
DatePicker
.
prototype
.
now
=
function
(
type
,
value
,
options
)
{
value
=
new
Date
()
if
(
options
&&
options
.
rel
)
{
value
.
setDate
(
value
.
getDate
()
+
options
.
rel
)
}
return
this
.
normalize
(
value
,
options
)
}
/**
* Navigate to next/prev month.
*/
DatePicker
.
prototype
.
navigate
=
function
(
type
,
value
,
options
)
{
var
targetDateObject
,
targetYear
,
targetMonth
,
targetDate
,
isTargetArray
=
$
.
isArray
(
value
),
isTargetObject
=
$
.
isPlainObject
(
value
),
viewsetObject
=
this
.
item
.
view
/*,
safety = 100*/
if
(
isTargetArray
||
isTargetObject
)
{
if
(
isTargetObject
)
{
targetYear
=
value
.
year
targetMonth
=
value
.
month
targetDate
=
value
.
date
}
else
{
targetYear
=
+
value
[
0
]
targetMonth
=
+
value
[
1
]
targetDate
=
+
value
[
2
]
}
// If we’re navigating months but the view is in a different
// month, navigate to the view’s year and month.
if
(
options
&&
options
.
nav
&&
viewsetObject
&&
viewsetObject
.
month
!==
targetMonth
)
{
targetYear
=
viewsetObject
.
year
targetMonth
=
viewsetObject
.
month
}
// Figure out the expected target year and month.
targetDateObject
=
new
Date
(
targetYear
,
targetMonth
+
(
options
&&
options
.
nav
?
options
.
nav
:
0
),
1
)
targetYear
=
targetDateObject
.
getFullYear
()
targetMonth
=
targetDateObject
.
getMonth
()
// If the month we’re going to doesn’t have enough days,
// keep decreasing the date until we reach the month’s last date.
while
(
/*safety &&*/
new
Date
(
targetYear
,
targetMonth
,
targetDate
).
getMonth
()
!==
targetMonth
)
{
targetDate
-=
1
/*safety -= 1
if ( !safety ) {
throw 'Fell into an infinite loop while navigating to ' + new Date( targetYear, targetMonth, targetDate ) + '.'
}*/
}
value
=
[
targetYear
,
targetMonth
,
targetDate
]
}
return
value
}
//DatePicker.prototype.navigate
/**
* Normalize a date by setting the hours to midnight.
*/
DatePicker
.
prototype
.
normalize
=
function
(
value
/*, options*/
)
{
value
.
setHours
(
0
,
0
,
0
,
0
)
return
value
}
/**
* Measure the range of dates.
*/
DatePicker
.
prototype
.
measure
=
function
(
type
,
value
/*, options*/
)
{
var
calendar
=
this
// If it’s anything false-y, remove the limits.
if
(
!
value
)
{
value
=
type
==
'
min
'
?
-
Infinity
:
Infinity
}
// If it’s a string, parse it.
else
if
(
typeof
value
==
'
string
'
)
{
value
=
calendar
.
parse
(
type
,
value
)
}
// If it's an integer, get a date relative to today.
else
if
(
_
.
isInteger
(
value
)
)
{
value
=
calendar
.
now
(
type
,
value
,
{
rel
:
value
}
)
}
return
value
}
///DatePicker.prototype.measure
/**
* Create a viewset object based on navigation.
*/
DatePicker
.
prototype
.
viewset
=
function
(
type
,
dateObject
/*, options*/
)
{
return
this
.
create
([
dateObject
.
year
,
dateObject
.
month
,
1
])
}
/**
* Validate a date as enabled and shift if needed.
*/
DatePicker
.
prototype
.
validate
=
function
(
type
,
dateObject
,
options
)
{
var
calendar
=
this
,
// Keep a reference to the original date.
originalDateObject
=
dateObject
,
// Make sure we have an interval.
interval
=
options
&&
options
.
interval
?
options
.
interval
:
1
,
// Check if the calendar enabled dates are inverted.
isFlippedBase
=
calendar
.
item
.
enable
===
-
1
,
// Check if we have any enabled dates after/before now.
hasEnabledBeforeTarget
,
hasEnabledAfterTarget
,
// The min & max limits.
minLimitObject
=
calendar
.
item
.
min
,
maxLimitObject
=
calendar
.
item
.
max
,
// Check if we’ve reached the limit during shifting.
reachedMin
,
reachedMax
,
// Check if the calendar is inverted and at least one weekday is enabled.
hasEnabledWeekdays
=
isFlippedBase
&&
calendar
.
item
.
disable
.
filter
(
function
(
value
)
{
// If there’s a date, check where it is relative to the target.
if
(
$
.
isArray
(
value
)
)
{
var
dateTime
=
calendar
.
create
(
value
).
pick
if
(
dateTime
<
dateObject
.
pick
)
hasEnabledBeforeTarget
=
true
else
if
(
dateTime
>
dateObject
.
pick
)
hasEnabledAfterTarget
=
true
}
// Return only integers for enabled weekdays.
return
_
.
isInteger
(
value
)
}).
length
/*,
safety = 100*/
// Cases to validate for:
// [1] Not inverted and date disabled.
// [2] Inverted and some dates enabled.
// [3] Not inverted and out of range.
//
// Cases to **not** validate for:
// • Navigating months.
// • Not inverted and date enabled.
// • Inverted and all dates disabled.
// • ..and anything else.
if
(
!
options
||
(
!
options
.
nav
&&
!
options
.
defaultValue
)
)
if
(
/* 1 */
(
!
isFlippedBase
&&
calendar
.
disabled
(
dateObject
)
)
||
/* 2 */
(
isFlippedBase
&&
calendar
.
disabled
(
dateObject
)
&&
(
hasEnabledWeekdays
||
hasEnabledBeforeTarget
||
hasEnabledAfterTarget
)
)
||
/* 3 */
(
!
isFlippedBase
&&
(
dateObject
.
pick
<=
minLimitObject
.
pick
||
dateObject
.
pick
>=
maxLimitObject
.
pick
)
)
)
{
// When inverted, flip the direction if there aren’t any enabled weekdays
// and there are no enabled dates in the direction of the interval.
if
(
isFlippedBase
&&
!
hasEnabledWeekdays
&&
(
(
!
hasEnabledAfterTarget
&&
interval
>
0
)
||
(
!
hasEnabledBeforeTarget
&&
interval
<
0
)
)
)
{
interval
*=
-
1
}
// Keep looping until we reach an enabled date.
while
(
/*safety &&*/
calendar
.
disabled
(
dateObject
)
)
{
/*safety -= 1
if ( !safety ) {
throw 'Fell into an infinite loop while validating ' + dateObject.obj + '.'
}*/
// If we’ve looped into the next/prev month with a large interval, return to the original date and flatten the interval.
if
(
Math
.
abs
(
interval
)
>
1
&&
(
dateObject
.
month
<
originalDateObject
.
month
||
dateObject
.
month
>
originalDateObject
.
month
)
)
{
dateObject
=
originalDateObject
interval
=
interval
>
0
?
1
:
-
1
}
// If we’ve reached the min/max limit, reverse the direction, flatten the interval and set it to the limit.
if
(
dateObject
.
pick
<=
minLimitObject
.
pick
)
{
reachedMin
=
true
interval
=
1
dateObject
=
calendar
.
create
([
minLimitObject
.
year
,
minLimitObject
.
month
,
minLimitObject
.
date
+
(
dateObject
.
pick
===
minLimitObject
.
pick
?
0
:
-
1
)
])
}
else
if
(
dateObject
.
pick
>=
maxLimitObject
.
pick
)
{
reachedMax
=
true
interval
=
-
1
dateObject
=
calendar
.
create
([
maxLimitObject
.
year
,
maxLimitObject
.
month
,
maxLimitObject
.
date
+
(
dateObject
.
pick
===
maxLimitObject
.
pick
?
0
:
1
)
])
}
// If we’ve reached both limits, just break out of the loop.
if
(
reachedMin
&&
reachedMax
)
{
break
}
// Finally, create the shifted date using the interval and keep looping.
dateObject
=
calendar
.
create
([
dateObject
.
year
,
dateObject
.
month
,
dateObject
.
date
+
interval
])
}
}
//endif
// Return the date object settled on.
return
dateObject
}
//DatePicker.prototype.validate
/**
* Check if a date is disabled.
*/
DatePicker
.
prototype
.
disabled
=
function
(
dateToVerify
)
{
var
calendar
=
this
,
// Filter through the disabled dates to check if this is one.
isDisabledMatch
=
calendar
.
item
.
disable
.
filter
(
function
(
dateToDisable
)
{
// If the date is a number, match the weekday with 0index and `firstDay` check.
if
(
_
.
isInteger
(
dateToDisable
)
)
{
return
dateToVerify
.
day
===
(
calendar
.
settings
.
firstDay
?
dateToDisable
:
dateToDisable
-
1
)
%
7
}
// If it’s an array or a native JS date, create and match the exact date.
if
(
$
.
isArray
(
dateToDisable
)
||
_
.
isDate
(
dateToDisable
)
)
{
return
dateToVerify
.
pick
===
calendar
.
create
(
dateToDisable
).
pick
}
// If it’s an object, match a date within the “from” and “to” range.
if
(
$
.
isPlainObject
(
dateToDisable
)
)
{
return
calendar
.
withinRange
(
dateToDisable
,
dateToVerify
)
}
})
// If this date matches a disabled date, confirm it’s not inverted.
isDisabledMatch
=
isDisabledMatch
.
length
&&
!
isDisabledMatch
.
filter
(
function
(
dateToDisable
)
{
return
$
.
isArray
(
dateToDisable
)
&&
dateToDisable
[
3
]
==
'
inverted
'
||
$
.
isPlainObject
(
dateToDisable
)
&&
dateToDisable
.
inverted
}).
length
// Check the calendar “enabled” flag and respectively flip the
// disabled state. Then also check if it’s beyond the min/max limits.
return
calendar
.
item
.
enable
===
-
1
?
!
isDisabledMatch
:
isDisabledMatch
||
dateToVerify
.
pick
<
calendar
.
item
.
min
.
pick
||
dateToVerify
.
pick
>
calendar
.
item
.
max
.
pick
}
//DatePicker.prototype.disabled
/**
* Parse a string into a usable type.
*/
DatePicker
.
prototype
.
parse
=
function
(
type
,
value
,
options
)
{
var
calendar
=
this
,
parsingObject
=
{}
// If it’s already parsed, we’re good.
if
(
!
value
||
typeof
value
!=
'
string
'
)
{
return
value
}
// We need a `.format` to parse the value with.
if
(
!
(
options
&&
options
.
format
)
)
{
options
=
options
||
{}
options
.
format
=
calendar
.
settings
.
format
}
// Convert the format into an array and then map through it.
calendar
.
formats
.
toArray
(
options
.
format
).
map
(
function
(
label
)
{
var
// Grab the formatting label.
formattingLabel
=
calendar
.
formats
[
label
],
// The format length is from the formatting label function or the
// label length without the escaping exclamation (!) mark.
formatLength
=
formattingLabel
?
_
.
trigger
(
formattingLabel
,
calendar
,
[
value
,
parsingObject
]
)
:
label
.
replace
(
/^!/
,
''
).
length
// If there's a format label, split the value up to the format length.
// Then add it to the parsing object with appropriate label.
if
(
formattingLabel
)
{
parsingObject
[
label
]
=
value
.
substr
(
0
,
formatLength
)
}
// Update the value as the substring from format length to end.
value
=
value
.
substr
(
formatLength
)
})
// Compensate for month 0index.
return
[
parsingObject
.
yyyy
||
parsingObject
.
yy
,
+
(
parsingObject
.
mm
||
parsingObject
.
m
)
-
1
,
parsingObject
.
dd
||
parsingObject
.
d
]
}
//DatePicker.prototype.parse
/**
* Various formats to display the object in.
*/
DatePicker
.
prototype
.
formats
=
(
function
()
{
// Return the length of the first word in a collection.
function
getWordLengthFromCollection
(
string
,
collection
,
dateObject
)
{
// Grab the first word from the string.
// Regex pattern from http://stackoverflow.com/q/150033
var
word
=
string
.
match
(
/
[^\x
00-
\x
7F
]
+|
\w
+/
)[
0
]
// If there's no month index, add it to the date object
if
(
!
dateObject
.
mm
&&
!
dateObject
.
m
)
{
dateObject
.
m
=
collection
.
indexOf
(
word
)
+
1
}
// Return the length of the word.
return
word
.
length
}
// Get the length of the first word in a string.
function
getFirstWordLength
(
string
)
{
return
string
.
match
(
/
\w
+/
)[
0
].
length
}
return
{
d
:
function
(
string
,
dateObject
)
{
// If there's string, then get the digits length.
// Otherwise return the selected date.
return
string
?
_
.
digits
(
string
)
:
dateObject
.
date
},
dd
:
function
(
string
,
dateObject
)
{
// If there's a string, then the length is always 2.
// Otherwise return the selected date with a leading zero.
return
string
?
2
:
_
.
lead
(
dateObject
.
date
)
},
ddd
:
function
(
string
,
dateObject
)
{
// If there's a string, then get the length of the first word.
// Otherwise return the short selected weekday.
return
string
?
getFirstWordLength
(
string
)
:
this
.
settings
.
weekdaysShort
[
dateObject
.
day
]
},
dddd
:
function
(
string
,
dateObject
)
{
// If there's a string, then get the length of the first word.
// Otherwise return the full selected weekday.
return
string
?
getFirstWordLength
(
string
)
:
this
.
settings
.
weekdaysFull
[
dateObject
.
day
]
},
m
:
function
(
string
,
dateObject
)
{
// If there's a string, then get the length of the digits
// Otherwise return the selected month with 0index compensation.
return
string
?
_
.
digits
(
string
)
:
dateObject
.
month
+
1
},
mm
:
function
(
string
,
dateObject
)
{
// If there's a string, then the length is always 2.
// Otherwise return the selected month with 0index and leading zero.
return
string
?
2
:
_
.
lead
(
dateObject
.
month
+
1
)
},
mmm
:
function
(
string
,
dateObject
)
{
var
collection
=
this
.
settings
.
monthsShort
// If there's a string, get length of the relevant month from the short
// months collection. Otherwise return the selected month from that collection.
return
string
?
getWordLengthFromCollection
(
string
,
collection
,
dateObject
)
:
collection
[
dateObject
.
month
]
},
mmmm
:
function
(
string
,
dateObject
)
{
var
collection
=
this
.
settings
.
monthsFull
// If there's a string, get length of the relevant month from the full
// months collection. Otherwise return the selected month from that collection.
return
string
?
getWordLengthFromCollection
(
string
,
collection
,
dateObject
)
:
collection
[
dateObject
.
month
]
},
yy
:
function
(
string
,
dateObject
)
{
// If there's a string, then the length is always 2.
// Otherwise return the selected year by slicing out the first 2 digits.
return
string
?
2
:
(
''
+
dateObject
.
year
).
slice
(
2
)
},
yyyy
:
function
(
string
,
dateObject
)
{
// If there's a string, then the length is always 4.
// Otherwise return the selected year.
return
string
?
4
:
dateObject
.
year
},
// Create an array by splitting the formatting string passed.
toArray
:
function
(
formatString
)
{
return
formatString
.
split
(
/
(
d
{1,4}
|m
{1,4}
|y
{4}
|yy|!.
)
/g
)
},
// Format an object into a string using the formatting options.
toString
:
function
(
formatString
,
itemObject
)
{
var
calendar
=
this
return
calendar
.
formats
.
toArray
(
formatString
).
map
(
function
(
label
)
{
return
_
.
trigger
(
calendar
.
formats
[
label
],
calendar
,
[
0
,
itemObject
]
)
||
label
.
replace
(
/^!/
,
''
)
}).
join
(
''
)
}
}
})()
//DatePicker.prototype.formats
/**
* Check if two date units are the exact.
*/
DatePicker
.
prototype
.
isDateExact
=
function
(
one
,
two
)
{
var
calendar
=
this
// When we’re working with weekdays, do a direct comparison.
if
(
(
_
.
isInteger
(
one
)
&&
_
.
isInteger
(
two
)
)
||
(
typeof
one
==
'
boolean
'
&&
typeof
two
==
'
boolean
'
)
)
{
return
one
===
two
}
// When we’re working with date representations, compare the “pick” value.
if
(
(
_
.
isDate
(
one
)
||
$
.
isArray
(
one
)
)
&&
(
_
.
isDate
(
two
)
||
$
.
isArray
(
two
)
)
)
{
return
calendar
.
create
(
one
).
pick
===
calendar
.
create
(
two
).
pick
}
// When we’re working with range objects, compare the “from” and “to”.
if
(
$
.
isPlainObject
(
one
)
&&
$
.
isPlainObject
(
two
)
)
{
return
calendar
.
isDateExact
(
one
.
from
,
two
.
from
)
&&
calendar
.
isDateExact
(
one
.
to
,
two
.
to
)
}
return
false
}
/**
* Check if two date units overlap.
*/
DatePicker
.
prototype
.
isDateOverlap
=
function
(
one
,
two
)
{
var
calendar
=
this
,
firstDay
=
calendar
.
settings
.
firstDay
?
1
:
0
// When we’re working with a weekday index, compare the days.
if
(
_
.
isInteger
(
one
)
&&
(
_
.
isDate
(
two
)
||
$
.
isArray
(
two
)
)
)
{
one
=
one
%
7
+
firstDay
return
one
===
calendar
.
create
(
two
).
day
+
1
}
if
(
_
.
isInteger
(
two
)
&&
(
_
.
isDate
(
one
)
||
$
.
isArray
(
one
)
)
)
{
two
=
two
%
7
+
firstDay
return
two
===
calendar
.
create
(
one
).
day
+
1
}
// When we’re working with range objects, check if the ranges overlap.
if
(
$
.
isPlainObject
(
one
)
&&
$
.
isPlainObject
(
two
)
)
{
return
calendar
.
overlapRanges
(
one
,
two
)
}
return
false
}
/**
* Flip the “enabled” state.
*/
DatePicker
.
prototype
.
flipEnable
=
function
(
val
)
{
var
itemObject
=
this
.
item
itemObject
.
enable
=
val
||
(
itemObject
.
enable
==
-
1
?
1
:
-
1
)
}
/**
* Mark a collection of dates as “disabled”.
*/
DatePicker
.
prototype
.
deactivate
=
function
(
type
,
datesToDisable
)
{
var
calendar
=
this
,
disabledItems
=
calendar
.
item
.
disable
.
slice
(
0
)
// If we’re flipping, that’s all we need to do.
if
(
datesToDisable
==
'
flip
'
)
{
calendar
.
flipEnable
()
}
else
if
(
datesToDisable
===
false
)
{
calendar
.
flipEnable
(
1
)
disabledItems
=
[]
}
else
if
(
datesToDisable
===
true
)
{
calendar
.
flipEnable
(
-
1
)
disabledItems
=
[]
}
// Otherwise go through the dates to disable.
else
{
datesToDisable
.
map
(
function
(
unitToDisable
)
{
var
matchFound
// When we have disabled items, check for matches.
// If something is matched, immediately break out.
for
(
var
index
=
0
;
index
<
disabledItems
.
length
;
index
+=
1
)
{
if
(
calendar
.
isDateExact
(
unitToDisable
,
disabledItems
[
index
]
)
)
{
matchFound
=
true
break
}
}
// If nothing was found, add the validated unit to the collection.
if
(
!
matchFound
)
{
if
(
_
.
isInteger
(
unitToDisable
)
||
_
.
isDate
(
unitToDisable
)
||
$
.
isArray
(
unitToDisable
)
||
(
$
.
isPlainObject
(
unitToDisable
)
&&
unitToDisable
.
from
&&
unitToDisable
.
to
)
)
{
disabledItems
.
push
(
unitToDisable
)
}
}
})
}
// Return the updated collection.
return
disabledItems
}
//DatePicker.prototype.deactivate
/**
* Mark a collection of dates as “enabled”.
*/
DatePicker
.
prototype
.
activate
=
function
(
type
,
datesToEnable
)
{
var
calendar
=
this
,
disabledItems
=
calendar
.
item
.
disable
,
disabledItemsCount
=
disabledItems
.
length
// If we’re flipping, that’s all we need to do.
if
(
datesToEnable
==
'
flip
'
)
{
calendar
.
flipEnable
()
}
else
if
(
datesToEnable
===
true
)
{
calendar
.
flipEnable
(
1
)
disabledItems
=
[]
}
else
if
(
datesToEnable
===
false
)
{
calendar
.
flipEnable
(
-
1
)
disabledItems
=
[]
}
// Otherwise go through the disabled dates.
else
{
datesToEnable
.
map
(
function
(
unitToEnable
)
{
var
matchFound
,
disabledUnit
,
index
,
isExactRange
// Go through the disabled items and try to find a match.
for
(
index
=
0
;
index
<
disabledItemsCount
;
index
+=
1
)
{
disabledUnit
=
disabledItems
[
index
]
// When an exact match is found, remove it from the collection.
if
(
calendar
.
isDateExact
(
disabledUnit
,
unitToEnable
)
)
{
matchFound
=
disabledItems
[
index
]
=
null
isExactRange
=
true
break
}
// When an overlapped match is found, add the “inverted” state to it.
else
if
(
calendar
.
isDateOverlap
(
disabledUnit
,
unitToEnable
)
)
{
if
(
$
.
isPlainObject
(
unitToEnable
)
)
{
unitToEnable
.
inverted
=
true
matchFound
=
unitToEnable
}
else
if
(
$
.
isArray
(
unitToEnable
)
)
{
matchFound
=
unitToEnable
if
(
!
matchFound
[
3
]
)
matchFound
.
push
(
'
inverted
'
)
}
else
if
(
_
.
isDate
(
unitToEnable
)
)
{
matchFound
=
[
unitToEnable
.
getFullYear
(),
unitToEnable
.
getMonth
(),
unitToEnable
.
getDate
(),
'
inverted
'
]
}
break
}
}
// If a match was found, remove a previous duplicate entry.
if
(
matchFound
)
for
(
index
=
0
;
index
<
disabledItemsCount
;
index
+=
1
)
{
if
(
calendar
.
isDateExact
(
disabledItems
[
index
],
unitToEnable
)
)
{
disabledItems
[
index
]
=
null
break
}
}
// In the event that we’re dealing with an exact range of dates,
// make sure there are no “inverted” dates because of it.
if
(
isExactRange
)
for
(
index
=
0
;
index
<
disabledItemsCount
;
index
+=
1
)
{
if
(
calendar
.
isDateOverlap
(
disabledItems
[
index
],
unitToEnable
)
)
{
disabledItems
[
index
]
=
null
break
}
}
// If something is still matched, add it into the collection.
if
(
matchFound
)
{
disabledItems
.
push
(
matchFound
)
}
})
}
// Return the updated collection.
return
disabledItems
.
filter
(
function
(
val
)
{
return
val
!=
null
})
}
//DatePicker.prototype.activate
/**
* Create a string for the nodes in the picker.
*/
DatePicker
.
prototype
.
nodes
=
function
(
isOpen
)
{
var
calendar
=
this
,
settings
=
calendar
.
settings
,
calendarItem
=
calendar
.
item
,
nowObject
=
calendarItem
.
now
,
selectedObject
=
calendarItem
.
select
,
highlightedObject
=
calendarItem
.
highlight
,
viewsetObject
=
calendarItem
.
view
,
disabledCollection
=
calendarItem
.
disable
,
minLimitObject
=
calendarItem
.
min
,
maxLimitObject
=
calendarItem
.
max
,
// Create the calendar table head using a copy of weekday labels collection.
// * We do a copy so we don't mutate the original array.
tableHead
=
(
function
(
collection
,
fullCollection
)
{
// If the first day should be Monday, move Sunday to the end.
if
(
settings
.
firstDay
)
{
collection
.
push
(
collection
.
shift
()
)
fullCollection
.
push
(
fullCollection
.
shift
()
)
}
// Create and return the table head group.
return
_
.
node
(
'
thead
'
,
_
.
node
(
'
tr
'
,
_
.
group
({
min
:
0
,
max
:
DAYS_IN_WEEK
-
1
,
i
:
1
,
node
:
'
th
'
,
item
:
function
(
counter
)
{
return
[
collection
[
counter
],
settings
.
klass
.
weekdays
,
'
scope=col title="
'
+
fullCollection
[
counter
]
+
'
"
'
]
}
})
)
)
//endreturn
})(
(
settings
.
showWeekdaysFull
?
settings
.
weekdaysFull
:
settings
.
weekdaysShort
).
slice
(
0
),
settings
.
weekdaysFull
.
slice
(
0
)
),
//tableHead
// Create the nav for next/prev month.
createMonthNav
=
function
(
next
)
{
// Otherwise, return the created month tag.
return
_
.
node
(
'
div
'
,
'
'
,
settings
.
klass
[
'
nav
'
+
(
next
?
'
Next
'
:
'
Prev
'
)
]
+
(
// If the focused month is outside the range, disabled the button.
(
next
&&
viewsetObject
.
year
>=
maxLimitObject
.
year
&&
viewsetObject
.
month
>=
maxLimitObject
.
month
)
||
(
!
next
&&
viewsetObject
.
year
<=
minLimitObject
.
year
&&
viewsetObject
.
month
<=
minLimitObject
.
month
)
?
'
'
+
settings
.
klass
.
navDisabled
:
''
),
'
data-nav=
'
+
(
next
||
-
1
)
+
'
'
+
_
.
ariaAttr
({
role
:
'
button
'
,
controls
:
calendar
.
$node
[
0
].
id
+
'
_table
'
})
+
'
'
+
'
title="
'
+
(
next
?
settings
.
labelMonthNext
:
settings
.
labelMonthPrev
)
+
'
"
'
)
//endreturn
},
//createMonthNav
// Create the month label.
createMonthLabel
=
function
()
{
var
monthsCollection
=
settings
.
showMonthsShort
?
settings
.
monthsShort
:
settings
.
monthsFull
// If there are months to select, add a dropdown menu.
if
(
settings
.
selectMonths
)
{
return
_
.
node
(
'
select
'
,
_
.
group
({
min
:
0
,
max
:
11
,
i
:
1
,
node
:
'
option
'
,
item
:
function
(
loopedMonth
)
{
return
[
// The looped month and no classes.
monthsCollection
[
loopedMonth
],
0
,
// Set the value and selected index.
'
value=
'
+
loopedMonth
+
(
viewsetObject
.
month
==
loopedMonth
?
'
selected
'
:
''
)
+
(
(
(
viewsetObject
.
year
==
minLimitObject
.
year
&&
loopedMonth
<
minLimitObject
.
month
)
||
(
viewsetObject
.
year
==
maxLimitObject
.
year
&&
loopedMonth
>
maxLimitObject
.
month
)
)
?
'
disabled
'
:
''
)
]
}
}),
settings
.
klass
.
selectMonth
,
(
isOpen
?
''
:
'
disabled
'
)
+
'
'
+
_
.
ariaAttr
({
controls
:
calendar
.
$node
[
0
].
id
+
'
_table
'
})
+
'
'
+
'
title="
'
+
settings
.
labelMonthSelect
+
'
"
'
)
}
// If there's a need for a month selector
return
_
.
node
(
'
div
'
,
monthsCollection
[
viewsetObject
.
month
],
settings
.
klass
.
month
)
},
//createMonthLabel
// Create the year label.
createYearLabel
=
function
()
{
var
focusedYear
=
viewsetObject
.
year
,
// If years selector is set to a literal "true", set it to 5. Otherwise
// divide in half to get half before and half after focused year.
numberYears
=
settings
.
selectYears
===
true
?
5
:
~~
(
settings
.
selectYears
/
2
)
// If there are years to select, add a dropdown menu.
if
(
numberYears
)
{
var
minYear
=
minLimitObject
.
year
,
maxYear
=
maxLimitObject
.
year
,
lowestYear
=
focusedYear
-
numberYears
,
highestYear
=
focusedYear
+
numberYears
// If the min year is greater than the lowest year, increase the highest year
// by the difference and set the lowest year to the min year.
if
(
minYear
>
lowestYear
)
{
highestYear
+=
minYear
-
lowestYear
lowestYear
=
minYear
}
// If the max year is less than the highest year, decrease the lowest year
// by the lower of the two: available and needed years. Then set the
// highest year to the max year.
if
(
maxYear
<
highestYear
)
{
var
availableYears
=
lowestYear
-
minYear
,
neededYears
=
highestYear
-
maxYear
lowestYear
-=
availableYears
>
neededYears
?
neededYears
:
availableYears
highestYear
=
maxYear
}
return
_
.
node
(
'
select
'
,
_
.
group
({
min
:
lowestYear
,
max
:
highestYear
,
i
:
1
,
node
:
'
option
'
,
item
:
function
(
loopedYear
)
{
return
[
// The looped year and no classes.
loopedYear
,
0
,
// Set the value and selected index.
'
value=
'
+
loopedYear
+
(
focusedYear
==
loopedYear
?
'
selected
'
:
''
)
]
}
}),
settings
.
klass
.
selectYear
,
(
isOpen
?
''
:
'
disabled
'
)
+
'
'
+
_
.
ariaAttr
({
controls
:
calendar
.
$node
[
0
].
id
+
'
_table
'
})
+
'
'
+
'
title="
'
+
settings
.
labelYearSelect
+
'
"
'
)
}
// Otherwise just return the year focused
return
_
.
node
(
'
div
'
,
focusedYear
,
settings
.
klass
.
year
)
}
//createYearLabel
// Create and return the entire calendar.
return
_
.
node
(
'
div
'
,
(
settings
.
selectYears
?
createYearLabel
()
+
createMonthLabel
()
:
createMonthLabel
()
+
createYearLabel
()
)
+
createMonthNav
()
+
createMonthNav
(
1
),
settings
.
klass
.
header
)
+
_
.
node
(
'
table
'
,
tableHead
+
_
.
node
(
'
tbody
'
,
_
.
group
({
min
:
0
,
max
:
WEEKS_IN_CALENDAR
-
1
,
i
:
1
,
node
:
'
tr
'
,
item
:
function
(
rowCounter
)
{
// If Monday is the first day and the month starts on Sunday, shift the date back a week.
var
shiftDateBy
=
settings
.
firstDay
&&
calendar
.
create
([
viewsetObject
.
year
,
viewsetObject
.
month
,
1
]).
day
===
0
?
-
7
:
0
return
[
_
.
group
({
min
:
DAYS_IN_WEEK
*
rowCounter
-
viewsetObject
.
day
+
shiftDateBy
+
1
,
// Add 1 for weekday 0index
max
:
function
()
{
return
this
.
min
+
DAYS_IN_WEEK
-
1
},
i
:
1
,
node
:
'
td
'
,
item
:
function
(
targetDate
)
{
// Convert the time date from a relative date to a target date.
targetDate
=
calendar
.
create
([
viewsetObject
.
year
,
viewsetObject
.
month
,
targetDate
+
(
settings
.
firstDay
?
1
:
0
)
])
var
isSelected
=
selectedObject
&&
selectedObject
.
pick
==
targetDate
.
pick
,
isHighlighted
=
highlightedObject
&&
highlightedObject
.
pick
==
targetDate
.
pick
,
isDisabled
=
disabledCollection
&&
calendar
.
disabled
(
targetDate
)
||
targetDate
.
pick
<
minLimitObject
.
pick
||
targetDate
.
pick
>
maxLimitObject
.
pick
,
formattedDate
=
_
.
trigger
(
calendar
.
formats
.
toString
,
calendar
,
[
settings
.
format
,
targetDate
]
)
return
[
_
.
node
(
'
div
'
,
targetDate
.
date
,
(
function
(
klasses
)
{
// Add the `infocus` or `outfocus` classes based on month in view.
klasses
.
push
(
viewsetObject
.
month
==
targetDate
.
month
?
settings
.
klass
.
infocus
:
settings
.
klass
.
outfocus
)
// Add the `today` class if needed.
if
(
nowObject
.
pick
==
targetDate
.
pick
)
{
klasses
.
push
(
settings
.
klass
.
now
)
}
// Add the `selected` class if something's selected and the time matches.
if
(
isSelected
)
{
klasses
.
push
(
settings
.
klass
.
selected
)
}
// Add the `highlighted` class if something's highlighted and the time matches.
if
(
isHighlighted
)
{
klasses
.
push
(
settings
.
klass
.
highlighted
)
}
// Add the `disabled` class if something's disabled and the object matches.
if
(
isDisabled
)
{
klasses
.
push
(
settings
.
klass
.
disabled
)
}
return
klasses
.
join
(
'
'
)
})([
settings
.
klass
.
day
]),
'
data-pick=
'
+
targetDate
.
pick
+
'
'
+
_
.
ariaAttr
({
role
:
'
gridcell
'
,
label
:
formattedDate
,
selected
:
isSelected
&&
calendar
.
$node
.
val
()
===
formattedDate
?
true
:
null
,
activedescendant
:
isHighlighted
?
true
:
null
,
disabled
:
isDisabled
?
true
:
null
})
),
''
,
_
.
ariaAttr
({
role
:
'
presentation
'
})
]
//endreturn
}
})
]
//endreturn
}
})
),
settings
.
klass
.
table
,
'
id="
'
+
calendar
.
$node
[
0
].
id
+
'
_table
'
+
'
"
'
+
_
.
ariaAttr
({
role
:
'
grid
'
,
controls
:
calendar
.
$node
[
0
].
id
,
readonly
:
true
})
)
+
// * For Firefox forms to submit, make sure to set the buttons’ `type` attributes as “button”.
_
.
node
(
'
div
'
,
_
.
node
(
'
button
'
,
settings
.
today
,
settings
.
klass
.
buttonToday
,
'
type=button data-pick=
'
+
nowObject
.
pick
+
(
isOpen
&&
!
calendar
.
disabled
(
nowObject
)
?
''
:
'
disabled
'
)
+
'
'
+
_
.
ariaAttr
({
controls
:
calendar
.
$node
[
0
].
id
})
)
+
_
.
node
(
'
button
'
,
settings
.
clear
,
settings
.
klass
.
buttonClear
,
'
type=button data-clear=1
'
+
(
isOpen
?
''
:
'
disabled
'
)
+
'
'
+
_
.
ariaAttr
({
controls
:
calendar
.
$node
[
0
].
id
})
)
+
_
.
node
(
'
button
'
,
settings
.
close
,
settings
.
klass
.
buttonClose
,
'
type=button data-close=true
'
+
(
isOpen
?
''
:
'
disabled
'
)
+
'
'
+
_
.
ariaAttr
({
controls
:
calendar
.
$node
[
0
].
id
})
),
settings
.
klass
.
footer
)
//endreturn
}
//DatePicker.prototype.nodes
/**
* The date picker defaults.
*/
DatePicker
.
defaults
=
(
function
(
prefix
)
{
return
{
// The title label to use for the month nav buttons
labelMonthNext
:
'
Next month
'
,
labelMonthPrev
:
'
Previous month
'
,
// The title label to use for the dropdown selectors
labelMonthSelect
:
'
Select a month
'
,
labelYearSelect
:
'
Select a year
'
,
// Months and weekdays
monthsFull
:
[
'
January
'
,
'
February
'
,
'
March
'
,
'
April
'
,
'
May
'
,
'
June
'
,
'
July
'
,
'
August
'
,
'
September
'
,
'
October
'
,
'
November
'
,
'
December
'
],
monthsShort
:
[
'
Jan
'
,
'
Feb
'
,
'
Mar
'
,
'
Apr
'
,
'
May
'
,
'
Jun
'
,
'
Jul
'
,
'
Aug
'
,
'
Sep
'
,
'
Oct
'
,
'
Nov
'
,
'
Dec
'
],
weekdaysFull
:
[
'
Sunday
'
,
'
Monday
'
,
'
Tuesday
'
,
'
Wednesday
'
,
'
Thursday
'
,
'
Friday
'
,
'
Saturday
'
],
weekdaysShort
:
[
'
Sun
'
,
'
Mon
'
,
'
Tue
'
,
'
Wed
'
,
'
Thu
'
,
'
Fri
'
,
'
Sat
'
],
// Today and clear
today
:
'
Today
'
,
clear
:
'
Clear
'
,
close
:
'
Close
'
,
// Picker close behavior
closeOnSelect
:
true
,
closeOnClear
:
true
,
// The format to show on the `input` element
format
:
'
d mmmm, yyyy
'
,
// Classes
klass
:
{
table
:
prefix
+
'
table
'
,
header
:
prefix
+
'
header
'
,
navPrev
:
prefix
+
'
nav--prev
'
,
navNext
:
prefix
+
'
nav--next
'
,
navDisabled
:
prefix
+
'
nav--disabled
'
,
month
:
prefix
+
'
month
'
,
year
:
prefix
+
'
year
'
,
selectMonth
:
prefix
+
'
select--month
'
,
selectYear
:
prefix
+
'
select--year
'
,
weekdays
:
prefix
+
'
weekday
'
,
day
:
prefix
+
'
day
'
,
disabled
:
prefix
+
'
day--disabled
'
,
selected
:
prefix
+
'
day--selected
'
,
highlighted
:
prefix
+
'
day--highlighted
'
,
now
:
prefix
+
'
day--today
'
,
infocus
:
prefix
+
'
day--infocus
'
,
outfocus
:
prefix
+
'
day--outfocus
'
,
footer
:
prefix
+
'
footer
'
,
buttonClear
:
prefix
+
'
button--clear
'
,
buttonToday
:
prefix
+
'
button--today
'
,
buttonClose
:
prefix
+
'
button--close
'
}
}
})(
Picker
.
klasses
().
picker
+
'
__
'
)
/**
* Extend the picker to add the date picker.
*/
Picker
.
extend
(
'
pickadate
'
,
DatePicker
)
}));
src/main/webapp/static/plugins/pickadate/3.5.6/picker.js
0 → 100644
View file @
a866cd37
/*!
* pickadate.js v3.5.6, 2015/04/20
* By Amsul, http://amsul.ca
* Hosted on http://amsul.github.io/pickadate.js
* Licensed under MIT
*/
(
function
(
factory
)
{
// AMD.
if
(
typeof
define
==
'
function
'
&&
define
.
amd
)
define
(
'
picker
'
,
[
'
jquery
'
],
factory
)
// Node.js/browserify.
else
if
(
typeof
exports
==
'
object
'
)
module
.
exports
=
factory
(
require
(
'
jquery
'
)
)
// Browser globals.
else
this
.
Picker
=
factory
(
jQuery
)
}(
function
(
$
)
{
var
$window
=
$
(
window
)
var
$document
=
$
(
document
)
var
$html
=
$
(
document
.
documentElement
)
var
supportsTransitions
=
document
.
documentElement
.
style
.
transition
!=
null
/**
* The picker constructor that creates a blank picker.
*/
function
PickerConstructor
(
ELEMENT
,
NAME
,
COMPONENT
,
OPTIONS
)
{
// If there’s no element, return the picker constructor.
if
(
!
ELEMENT
)
return
PickerConstructor
var
IS_DEFAULT_THEME
=
false
,
// The state of the picker.
STATE
=
{
id
:
ELEMENT
.
id
||
'
P
'
+
Math
.
abs
(
~~
(
Math
.
random
()
*
new
Date
())
)
},
// Merge the defaults and options passed.
SETTINGS
=
COMPONENT
?
$
.
extend
(
true
,
{},
COMPONENT
.
defaults
,
OPTIONS
)
:
OPTIONS
||
{},
// Merge the default classes with the settings classes.
CLASSES
=
$
.
extend
(
{},
PickerConstructor
.
klasses
(),
SETTINGS
.
klass
),
// The element node wrapper into a jQuery object.
$ELEMENT
=
$
(
ELEMENT
),
// Pseudo picker constructor.
PickerInstance
=
function
()
{
return
this
.
start
()
},
// The picker prototype.
P
=
PickerInstance
.
prototype
=
{
constructor
:
PickerInstance
,
$node
:
$ELEMENT
,
/**
* Initialize everything
*/
start
:
function
()
{
// If it’s already started, do nothing.
if
(
STATE
&&
STATE
.
start
)
return
P
// Update the picker states.
STATE
.
methods
=
{}
STATE
.
start
=
true
STATE
.
open
=
false
STATE
.
type
=
ELEMENT
.
type
// Confirm focus state, convert into text input to remove UA stylings,
// and set as readonly to prevent keyboard popup.
ELEMENT
.
autofocus
=
ELEMENT
==
getActiveElement
()
ELEMENT
.
readOnly
=
!
SETTINGS
.
editable
ELEMENT
.
id
=
ELEMENT
.
id
||
STATE
.
id
if
(
ELEMENT
.
type
!=
'
text
'
)
{
ELEMENT
.
type
=
'
text
'
}
// Create a new picker component with the settings.
P
.
component
=
new
COMPONENT
(
P
,
SETTINGS
)
// Create the picker root and then prepare it.
P
.
$root
=
$
(
'
<div class="
'
+
CLASSES
.
picker
+
'
" id="
'
+
ELEMENT
.
id
+
'
_root" />
'
)
prepareElementRoot
()
// Create the picker holder and then prepare it.
P
.
$holder
=
$
(
createWrappedComponent
()
).
appendTo
(
P
.
$root
)
prepareElementHolder
()
// If there’s a format for the hidden input element, create the element.
if
(
SETTINGS
.
formatSubmit
)
{
prepareElementHidden
()
}
// Prepare the input element.
prepareElement
()
// Insert the hidden input as specified in the settings.
if
(
SETTINGS
.
containerHidden
)
$
(
SETTINGS
.
containerHidden
).
append
(
P
.
_hidden
)
else
$ELEMENT
.
after
(
P
.
_hidden
)
// Insert the root as specified in the settings.
if
(
SETTINGS
.
container
)
$
(
SETTINGS
.
container
).
append
(
P
.
$root
)
else
$ELEMENT
.
after
(
P
.
$root
)
// Bind the default component and settings events.
P
.
on
({
start
:
P
.
component
.
onStart
,
render
:
P
.
component
.
onRender
,
stop
:
P
.
component
.
onStop
,
open
:
P
.
component
.
onOpen
,
close
:
P
.
component
.
onClose
,
set
:
P
.
component
.
onSet
}).
on
({
start
:
SETTINGS
.
onStart
,
render
:
SETTINGS
.
onRender
,
stop
:
SETTINGS
.
onStop
,
open
:
SETTINGS
.
onOpen
,
close
:
SETTINGS
.
onClose
,
set
:
SETTINGS
.
onSet
})
// Once we’re all set, check the theme in use.
IS_DEFAULT_THEME
=
isUsingDefaultTheme
(
P
.
$holder
[
0
]
)
// If the element has autofocus, open the picker.
if
(
ELEMENT
.
autofocus
)
{
P
.
open
()
}
// Trigger queued the “start” and “render” events.
return
P
.
trigger
(
'
start
'
).
trigger
(
'
render
'
)
},
//start
/**
* Render a new picker
*/
render
:
function
(
entireComponent
)
{
// Insert a new component holder in the root or box.
if
(
entireComponent
)
{
P
.
$holder
=
$
(
createWrappedComponent
()
)
prepareElementHolder
()
P
.
$root
.
html
(
P
.
$holder
)
}
else
P
.
$root
.
find
(
'
.
'
+
CLASSES
.
box
).
html
(
P
.
component
.
nodes
(
STATE
.
open
)
)
// Trigger the queued “render” events.
return
P
.
trigger
(
'
render
'
)
},
//render
/**
* Destroy everything
*/
stop
:
function
()
{
// If it’s already stopped, do nothing.
if
(
!
STATE
.
start
)
return
P
// Then close the picker.
P
.
close
()
// Remove the hidden field.
if
(
P
.
_hidden
)
{
P
.
_hidden
.
parentNode
.
removeChild
(
P
.
_hidden
)
}
// Remove the root.
P
.
$root
.
remove
()
// Remove the input class, remove the stored data, and unbind
// the events (after a tick for IE - see `P.close`).
$ELEMENT
.
removeClass
(
CLASSES
.
input
).
removeData
(
NAME
)
setTimeout
(
function
()
{
$ELEMENT
.
off
(
'
.
'
+
STATE
.
id
)
},
0
)
// Restore the element state
ELEMENT
.
type
=
STATE
.
type
ELEMENT
.
readOnly
=
false
// Trigger the queued “stop” events.
P
.
trigger
(
'
stop
'
)
// Reset the picker states.
STATE
.
methods
=
{}
STATE
.
start
=
false
return
P
},
//stop
/**
* Open up the picker
*/
open
:
function
(
dontGiveFocus
)
{
// If it’s already open, do nothing.
if
(
STATE
.
open
)
return
P
// Add the “active” class.
$ELEMENT
.
addClass
(
CLASSES
.
active
)
aria
(
ELEMENT
,
'
expanded
'
,
true
)
// * A Firefox bug, when `html` has `overflow:hidden`, results in
// killing transitions :(. So add the “opened” state on the next tick.
// Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=625289
setTimeout
(
function
()
{
// Add the “opened” class to the picker root.
P
.
$root
.
addClass
(
CLASSES
.
opened
)
aria
(
P
.
$root
[
0
],
'
hidden
'
,
false
)
},
0
)
// If we have to give focus, bind the element and doc events.
if
(
dontGiveFocus
!==
false
)
{
// Set it as open.
STATE
.
open
=
true
// Prevent the page from scrolling.
if
(
IS_DEFAULT_THEME
)
{
$html
.
css
(
'
overflow
'
,
'
hidden
'
).
css
(
'
padding-right
'
,
'
+=
'
+
getScrollbarWidth
()
)
}
// Pass focus to the root element’s jQuery object.
focusPickerOnceOpened
()
// Bind the document events.
$document
.
on
(
'
click.
'
+
STATE
.
id
+
'
focusin.
'
+
STATE
.
id
,
function
(
event
)
{
var
target
=
event
.
target
// If the target of the event is not the element, close the picker picker.
// * Don’t worry about clicks or focusins on the root because those don’t bubble up.
// Also, for Firefox, a click on an `option` element bubbles up directly
// to the doc. So make sure the target wasn't the doc.
// * In Firefox stopPropagation() doesn’t prevent right-click events from bubbling,
// which causes the picker to unexpectedly close when right-clicking it. So make
// sure the event wasn’t a right-click.
if
(
target
!=
ELEMENT
&&
target
!=
document
&&
event
.
which
!=
3
)
{
// If the target was the holder that covers the screen,
// keep the element focused to maintain tabindex.
P
.
close
(
target
===
P
.
$holder
[
0
]
)
}
}).
on
(
'
keydown.
'
+
STATE
.
id
,
function
(
event
)
{
var
// Get the keycode.
keycode
=
event
.
keyCode
,
// Translate that to a selection change.
keycodeToMove
=
P
.
component
.
key
[
keycode
],
// Grab the target.
target
=
event
.
target
// On escape, close the picker and give focus.
if
(
keycode
==
27
)
{
P
.
close
(
true
)
}
// Check if there is a key movement or “enter” keypress on the element.
else
if
(
target
==
P
.
$holder
[
0
]
&&
(
keycodeToMove
||
keycode
==
13
)
)
{
// Prevent the default action to stop page movement.
event
.
preventDefault
()
// Trigger the key movement action.
if
(
keycodeToMove
)
{
PickerConstructor
.
_
.
trigger
(
P
.
component
.
key
.
go
,
P
,
[
PickerConstructor
.
_
.
trigger
(
keycodeToMove
)
]
)
}
// On “enter”, if the highlighted item isn’t disabled, set the value and close.
else
if
(
!
P
.
$root
.
find
(
'
.
'
+
CLASSES
.
highlighted
).
hasClass
(
CLASSES
.
disabled
)
)
{
P
.
set
(
'
select
'
,
P
.
component
.
item
.
highlight
)
if
(
SETTINGS
.
closeOnSelect
)
{
P
.
close
(
true
)
}
}
}
// If the target is within the root and “enter” is pressed,
// prevent the default action and trigger a click on the target instead.
else
if
(
$
.
contains
(
P
.
$root
[
0
],
target
)
&&
keycode
==
13
)
{
event
.
preventDefault
()
target
.
click
()
}
})
}
// Trigger the queued “open” events.
return
P
.
trigger
(
'
open
'
)
},
//open
/**
* Close the picker
*/
close
:
function
(
giveFocus
)
{
// If we need to give focus, do it before changing states.
if
(
giveFocus
)
{
if
(
SETTINGS
.
editable
)
{
ELEMENT
.
focus
()
}
else
{
// ....ah yes! It would’ve been incomplete without a crazy workaround for IE :|
// The focus is triggered *after* the close has completed - causing it
// to open again. So unbind and rebind the event at the next tick.
P
.
$holder
.
off
(
'
focus.toOpen
'
).
focus
()
setTimeout
(
function
()
{
P
.
$holder
.
on
(
'
focus.toOpen
'
,
handleFocusToOpenEvent
)
},
0
)
}
}
// Remove the “active” class.
$ELEMENT
.
removeClass
(
CLASSES
.
active
)
aria
(
ELEMENT
,
'
expanded
'
,
false
)
// * A Firefox bug, when `html` has `overflow:hidden`, results in
// killing transitions :(. So remove the “opened” state on the next tick.
// Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=625289
setTimeout
(
function
()
{
// Remove the “opened” and “focused” class from the picker root.
P
.
$root
.
removeClass
(
CLASSES
.
opened
+
'
'
+
CLASSES
.
focused
)
aria
(
P
.
$root
[
0
],
'
hidden
'
,
true
)
},
0
)
// If it’s already closed, do nothing more.
if
(
!
STATE
.
open
)
return
P
// Set it as closed.
STATE
.
open
=
false
// Allow the page to scroll.
if
(
IS_DEFAULT_THEME
)
{
$html
.
css
(
'
overflow
'
,
''
).
css
(
'
padding-right
'
,
'
-=
'
+
getScrollbarWidth
()
)
}
// Unbind the document events.
$document
.
off
(
'
.
'
+
STATE
.
id
)
// Trigger the queued “close” events.
return
P
.
trigger
(
'
close
'
)
},
//close
/**
* Clear the values
*/
clear
:
function
(
options
)
{
return
P
.
set
(
'
clear
'
,
null
,
options
)
},
//clear
/**
* Set something
*/
set
:
function
(
thing
,
value
,
options
)
{
var
thingItem
,
thingValue
,
thingIsObject
=
$
.
isPlainObject
(
thing
),
thingObject
=
thingIsObject
?
thing
:
{}
// Make sure we have usable options.
options
=
thingIsObject
&&
$
.
isPlainObject
(
value
)
?
value
:
options
||
{}
if
(
thing
)
{
// If the thing isn’t an object, make it one.
if
(
!
thingIsObject
)
{
thingObject
[
thing
]
=
value
}
// Go through the things of items to set.
for
(
thingItem
in
thingObject
)
{
// Grab the value of the thing.
thingValue
=
thingObject
[
thingItem
]
// First, if the item exists and there’s a value, set it.
if
(
thingItem
in
P
.
component
.
item
)
{
if
(
thingValue
===
undefined
)
thingValue
=
null
P
.
component
.
set
(
thingItem
,
thingValue
,
options
)
}
// Then, check to update the element value and broadcast a change.
if
(
thingItem
==
'
select
'
||
thingItem
==
'
clear
'
)
{
$ELEMENT
.
val
(
thingItem
==
'
clear
'
?
''
:
P
.
get
(
thingItem
,
SETTINGS
.
format
)
).
trigger
(
'
change
'
)
}
}
// Render a new picker.
P
.
render
()
}
// When the method isn’t muted, trigger queued “set” events and pass the `thingObject`.
return
options
.
muted
?
P
:
P
.
trigger
(
'
set
'
,
thingObject
)
},
//set
/**
* Get something
*/
get
:
function
(
thing
,
format
)
{
// Make sure there’s something to get.
thing
=
thing
||
'
value
'
// If a picker state exists, return that.
if
(
STATE
[
thing
]
!=
null
)
{
return
STATE
[
thing
]
}
// Return the submission value, if that.
if
(
thing
==
'
valueSubmit
'
)
{
if
(
P
.
_hidden
)
{
return
P
.
_hidden
.
value
}
thing
=
'
value
'
}
// Return the value, if that.
if
(
thing
==
'
value
'
)
{
return
ELEMENT
.
value
}
// Check if a component item exists, return that.
if
(
thing
in
P
.
component
.
item
)
{
if
(
typeof
format
==
'
string
'
)
{
var
thingValue
=
P
.
component
.
get
(
thing
)
return
thingValue
?
PickerConstructor
.
_
.
trigger
(
P
.
component
.
formats
.
toString
,
P
.
component
,
[
format
,
thingValue
]
)
:
''
}
return
P
.
component
.
get
(
thing
)
}
},
//get
/**
* Bind events on the things.
*/
on
:
function
(
thing
,
method
,
internal
)
{
var
thingName
,
thingMethod
,
thingIsObject
=
$
.
isPlainObject
(
thing
),
thingObject
=
thingIsObject
?
thing
:
{}
if
(
thing
)
{
// If the thing isn’t an object, make it one.
if
(
!
thingIsObject
)
{
thingObject
[
thing
]
=
method
}
// Go through the things to bind to.
for
(
thingName
in
thingObject
)
{
// Grab the method of the thing.
thingMethod
=
thingObject
[
thingName
]
// If it was an internal binding, prefix it.
if
(
internal
)
{
thingName
=
'
_
'
+
thingName
}
// Make sure the thing methods collection exists.
STATE
.
methods
[
thingName
]
=
STATE
.
methods
[
thingName
]
||
[]
// Add the method to the relative method collection.
STATE
.
methods
[
thingName
].
push
(
thingMethod
)
}
}
return
P
},
//on
/**
* Unbind events on the things.
*/
off
:
function
()
{
var
i
,
thingName
,
names
=
arguments
;
for
(
i
=
0
,
namesCount
=
names
.
length
;
i
<
namesCount
;
i
+=
1
)
{
thingName
=
names
[
i
]
if
(
thingName
in
STATE
.
methods
)
{
delete
STATE
.
methods
[
thingName
]
}
}
return
P
},
/**
* Fire off method events.
*/
trigger
:
function
(
name
,
data
)
{
var
_trigger
=
function
(
name
)
{
var
methodList
=
STATE
.
methods
[
name
]
if
(
methodList
)
{
methodList
.
map
(
function
(
method
)
{
PickerConstructor
.
_
.
trigger
(
method
,
P
,
[
data
]
)
})
}
}
_trigger
(
'
_
'
+
name
)
_trigger
(
name
)
return
P
}
//trigger
}
//PickerInstance.prototype
/**
* Wrap the picker holder components together.
*/
function
createWrappedComponent
()
{
// Create a picker wrapper holder
return
PickerConstructor
.
_
.
node
(
'
div
'
,
// Create a picker wrapper node
PickerConstructor
.
_
.
node
(
'
div
'
,
// Create a picker frame
PickerConstructor
.
_
.
node
(
'
div
'
,
// Create a picker box node
PickerConstructor
.
_
.
node
(
'
div
'
,
// Create the components nodes.
P
.
component
.
nodes
(
STATE
.
open
),
// The picker box class
CLASSES
.
box
),
// Picker wrap class
CLASSES
.
wrap
),
// Picker frame class
CLASSES
.
frame
),
// Picker holder class
CLASSES
.
holder
,
'
tabindex="-1"
'
)
//endreturn
}
//createWrappedComponent
/**
* Prepare the input element with all bindings.
*/
function
prepareElement
()
{
$ELEMENT
.
// Store the picker data by component name.
data
(
NAME
,
P
).
// Add the “input” class name.
addClass
(
CLASSES
.
input
).
// If there’s a `data-value`, update the value of the element.
val
(
$ELEMENT
.
data
(
'
value
'
)
?
P
.
get
(
'
select
'
,
SETTINGS
.
format
)
:
ELEMENT
.
value
)
// Only bind keydown events if the element isn’t editable.
if
(
!
SETTINGS
.
editable
)
{
$ELEMENT
.
// On focus/click, open the picker.
on
(
'
focus.
'
+
STATE
.
id
+
'
click.
'
+
STATE
.
id
,
function
(
event
)
{
event
.
preventDefault
()
P
.
open
()
}).
// Handle keyboard event based on the picker being opened or not.
on
(
'
keydown.
'
+
STATE
.
id
,
handleKeydownEvent
)
}
// Update the aria attributes.
aria
(
ELEMENT
,
{
haspopup
:
true
,
expanded
:
false
,
readonly
:
false
,
owns
:
ELEMENT
.
id
+
'
_root
'
})
}
/**
* Prepare the root picker element with all bindings.
*/
function
prepareElementRoot
()
{
aria
(
P
.
$root
[
0
],
'
hidden
'
,
true
)
}
/**
* Prepare the holder picker element with all bindings.
*/
function
prepareElementHolder
()
{
P
.
$holder
.
on
({
// For iOS8.
keydown
:
handleKeydownEvent
,
'
focus.toOpen
'
:
handleFocusToOpenEvent
,
blur
:
function
()
{
// Remove the “target” class.
$ELEMENT
.
removeClass
(
CLASSES
.
target
)
},
// When something within the holder is focused, stop from bubbling
// to the doc and remove the “focused” state from the root.
focusin
:
function
(
event
)
{
P
.
$root
.
removeClass
(
CLASSES
.
focused
)
event
.
stopPropagation
()
},
// When something within the holder is clicked, stop it
// from bubbling to the doc.
'
mousedown click
'
:
function
(
event
)
{
var
target
=
event
.
target
// Make sure the target isn’t the root holder so it can bubble up.
if
(
target
!=
P
.
$holder
[
0
]
)
{
event
.
stopPropagation
()
// * For mousedown events, cancel the default action in order to
// prevent cases where focus is shifted onto external elements
// when using things like jQuery mobile or MagnificPopup (ref: #249 & #120).
// Also, for Firefox, don’t prevent action on the `option` element.
if
(
event
.
type
==
'
mousedown
'
&&
!
$
(
target
).
is
(
'
input, select, textarea, button, option
'
))
{
event
.
preventDefault
()
// Re-focus onto the holder so that users can click away
// from elements focused within the picker.
P
.
$holder
[
0
].
focus
()
}
}
}
}).
// If there’s a click on an actionable element, carry out the actions.
on
(
'
click
'
,
'
[data-pick], [data-nav], [data-clear], [data-close]
'
,
function
()
{
var
$target
=
$
(
this
),
targetData
=
$target
.
data
(),
targetDisabled
=
$target
.
hasClass
(
CLASSES
.
navDisabled
)
||
$target
.
hasClass
(
CLASSES
.
disabled
),
// * For IE, non-focusable elements can be active elements as well
// (http://stackoverflow.com/a/2684561).
activeElement
=
getActiveElement
()
activeElement
=
activeElement
&&
(
activeElement
.
type
||
activeElement
.
href
)
// If it’s disabled or nothing inside is actively focused, re-focus the element.
if
(
targetDisabled
||
activeElement
&&
!
$
.
contains
(
P
.
$root
[
0
],
activeElement
)
)
{
P
.
$holder
[
0
].
focus
()
}
// If something is superficially changed, update the `highlight` based on the `nav`.
if
(
!
targetDisabled
&&
targetData
.
nav
)
{
P
.
set
(
'
highlight
'
,
P
.
component
.
item
.
highlight
,
{
nav
:
targetData
.
nav
}
)
}
// If something is picked, set `select` then close with focus.
else
if
(
!
targetDisabled
&&
'
pick
'
in
targetData
)
{
P
.
set
(
'
select
'
,
targetData
.
pick
)
if
(
SETTINGS
.
closeOnSelect
)
{
P
.
close
(
true
)
}
}
// If a “clear” button is pressed, empty the values and close with focus.
else
if
(
targetData
.
clear
)
{
P
.
clear
()
if
(
SETTINGS
.
closeOnClear
)
{
P
.
close
(
true
)
}
}
else
if
(
targetData
.
close
)
{
P
.
close
(
true
)
}
})
//P.$holder
}
/**
* Prepare the hidden input element along with all bindings.
*/
function
prepareElementHidden
()
{
var
name
if
(
SETTINGS
.
hiddenName
===
true
)
{
name
=
ELEMENT
.
name
ELEMENT
.
name
=
''
}
else
{
name
=
[
typeof
SETTINGS
.
hiddenPrefix
==
'
string
'
?
SETTINGS
.
hiddenPrefix
:
''
,
typeof
SETTINGS
.
hiddenSuffix
==
'
string
'
?
SETTINGS
.
hiddenSuffix
:
'
_submit
'
]
name
=
name
[
0
]
+
ELEMENT
.
name
+
name
[
1
]
}
P
.
_hidden
=
$
(
'
<input
'
+
'
type=hidden
'
+
// Create the name using the original input’s with a prefix and suffix.
'
name="
'
+
name
+
'
"
'
+
// If the element has a value, set the hidden value as well.
(
$ELEMENT
.
data
(
'
value
'
)
||
ELEMENT
.
value
?
'
value="
'
+
P
.
get
(
'
select
'
,
SETTINGS
.
formatSubmit
)
+
'
"
'
:
''
)
+
'
>
'
)[
0
]
$ELEMENT
.
// If the value changes, update the hidden input with the correct format.
on
(
'
change.
'
+
STATE
.
id
,
function
()
{
P
.
_hidden
.
value
=
ELEMENT
.
value
?
P
.
get
(
'
select
'
,
SETTINGS
.
formatSubmit
)
:
''
})
}
// Wait for transitions to end before focusing the holder. Otherwise, while
// using the `container` option, the view jumps to the container.
function
focusPickerOnceOpened
()
{
if
(
IS_DEFAULT_THEME
&&
supportsTransitions
)
{
P
.
$holder
.
find
(
'
.
'
+
CLASSES
.
frame
).
one
(
'
transitionend
'
,
function
()
{
P
.
$holder
[
0
].
focus
()
})
}
else
{
P
.
$holder
[
0
].
focus
()
}
}
function
handleFocusToOpenEvent
(
event
)
{
// Stop the event from propagating to the doc.
event
.
stopPropagation
()
// Add the “target” class.
$ELEMENT
.
addClass
(
CLASSES
.
target
)
// Add the “focused” class to the root.
P
.
$root
.
addClass
(
CLASSES
.
focused
)
// And then finally open the picker.
P
.
open
()
}
// For iOS8.
function
handleKeydownEvent
(
event
)
{
var
keycode
=
event
.
keyCode
,
// Check if one of the delete keys was pressed.
isKeycodeDelete
=
/^
(
8|46
)
$/
.
test
(
keycode
)
// For some reason IE clears the input value on “escape”.
if
(
keycode
==
27
)
{
P
.
close
(
true
)
return
false
}
// Check if `space` or `delete` was pressed or the picker is closed with a key movement.
if
(
keycode
==
32
||
isKeycodeDelete
||
!
STATE
.
open
&&
P
.
component
.
key
[
keycode
]
)
{
// Prevent it from moving the page and bubbling to doc.
event
.
preventDefault
()
event
.
stopPropagation
()
// If `delete` was pressed, clear the values and close the picker.
// Otherwise open the picker.
if
(
isKeycodeDelete
)
{
P
.
clear
().
close
()
}
else
{
P
.
open
()
}
}
}
// Return a new picker instance.
return
new
PickerInstance
()
}
//PickerConstructor
/**
* The default classes and prefix to use for the HTML classes.
*/
PickerConstructor
.
klasses
=
function
(
prefix
)
{
prefix
=
prefix
||
'
picker
'
return
{
picker
:
prefix
,
opened
:
prefix
+
'
--opened
'
,
focused
:
prefix
+
'
--focused
'
,
input
:
prefix
+
'
__input
'
,
active
:
prefix
+
'
__input--active
'
,
target
:
prefix
+
'
__input--target
'
,
holder
:
prefix
+
'
__holder
'
,
frame
:
prefix
+
'
__frame
'
,
wrap
:
prefix
+
'
__wrap
'
,
box
:
prefix
+
'
__box
'
}
}
//PickerConstructor.klasses
/**
* Check if the default theme is being used.
*/
function
isUsingDefaultTheme
(
element
)
{
var
theme
,
prop
=
'
position
'
// For IE.
if
(
element
.
currentStyle
)
{
theme
=
element
.
currentStyle
[
prop
]
}
// For normal browsers.
else
if
(
window
.
getComputedStyle
)
{
theme
=
getComputedStyle
(
element
)[
prop
]
}
return
theme
==
'
fixed
'
}
/**
* Get the width of the browser’s scrollbar.
* Taken from: https://github.com/VodkaBears/Remodal/blob/master/src/jquery.remodal.js
*/
function
getScrollbarWidth
()
{
if
(
$html
.
height
()
<=
$window
.
height
()
)
{
return
0
}
var
$outer
=
$
(
'
<div style="visibility:hidden;width:100px" />
'
).
appendTo
(
'
body
'
)
// Get the width without scrollbars.
var
widthWithoutScroll
=
$outer
[
0
].
offsetWidth
// Force adding scrollbars.
$outer
.
css
(
'
overflow
'
,
'
scroll
'
)
// Add the inner div.
var
$inner
=
$
(
'
<div style="width:100%" />
'
).
appendTo
(
$outer
)
// Get the width with scrollbars.
var
widthWithScroll
=
$inner
[
0
].
offsetWidth
// Remove the divs.
$outer
.
remove
()
// Return the difference between the widths.
return
widthWithoutScroll
-
widthWithScroll
}
/**
* PickerConstructor helper methods.
*/
PickerConstructor
.
_
=
{
/**
* Create a group of nodes. Expects:
* `
{
min: {Integer},
max: {Integer},
i: {Integer},
node: {String},
item: {Function}
}
* `
*/
group
:
function
(
groupObject
)
{
var
// Scope for the looped object
loopObjectScope
,
// Create the nodes list
nodesList
=
''
,
// The counter starts from the `min`
counter
=
PickerConstructor
.
_
.
trigger
(
groupObject
.
min
,
groupObject
)
// Loop from the `min` to `max`, incrementing by `i`
for
(
;
counter
<=
PickerConstructor
.
_
.
trigger
(
groupObject
.
max
,
groupObject
,
[
counter
]
);
counter
+=
groupObject
.
i
)
{
// Trigger the `item` function within scope of the object
loopObjectScope
=
PickerConstructor
.
_
.
trigger
(
groupObject
.
item
,
groupObject
,
[
counter
]
)
// Splice the subgroup and create nodes out of the sub nodes
nodesList
+=
PickerConstructor
.
_
.
node
(
groupObject
.
node
,
loopObjectScope
[
0
],
// the node
loopObjectScope
[
1
],
// the classes
loopObjectScope
[
2
]
// the attributes
)
}
// Return the list of nodes
return
nodesList
},
//group
/**
* Create a dom node string
*/
node
:
function
(
wrapper
,
item
,
klass
,
attribute
)
{
// If the item is false-y, just return an empty string
if
(
!
item
)
return
''
// If the item is an array, do a join
item
=
$
.
isArray
(
item
)
?
item
.
join
(
''
)
:
item
// Check for the class
klass
=
klass
?
'
class="
'
+
klass
+
'
"
'
:
''
// Check for any attributes
attribute
=
attribute
?
'
'
+
attribute
:
''
// Return the wrapped item
return
'
<
'
+
wrapper
+
klass
+
attribute
+
'
>
'
+
item
+
'
</
'
+
wrapper
+
'
>
'
},
//node
/**
* Lead numbers below 10 with a zero.
*/
lead
:
function
(
number
)
{
return
(
number
<
10
?
'
0
'
:
''
)
+
number
},
/**
* Trigger a function otherwise return the value.
*/
trigger
:
function
(
callback
,
scope
,
args
)
{
return
typeof
callback
==
'
function
'
?
callback
.
apply
(
scope
,
args
||
[]
)
:
callback
},
/**
* If the second character is a digit, length is 2 otherwise 1.
*/
digits
:
function
(
string
)
{
return
(
/
\d
/
).
test
(
string
[
1
]
)
?
2
:
1
},
/**
* Tell if something is a date object.
*/
isDate
:
function
(
value
)
{
return
{}.
toString
.
call
(
value
).
indexOf
(
'
Date
'
)
>
-
1
&&
this
.
isInteger
(
value
.
getDate
()
)
},
/**
* Tell if something is an integer.
*/
isInteger
:
function
(
value
)
{
return
{}.
toString
.
call
(
value
).
indexOf
(
'
Number
'
)
>
-
1
&&
value
%
1
===
0
},
/**
* Create ARIA attribute strings.
*/
ariaAttr
:
ariaAttr
}
//PickerConstructor._
/**
* Extend the picker with a component and defaults.
*/
PickerConstructor
.
extend
=
function
(
name
,
Component
)
{
// Extend jQuery.
$
.
fn
[
name
]
=
function
(
options
,
action
)
{
// Grab the component data.
var
componentData
=
this
.
data
(
name
)
// If the picker is requested, return the data object.
if
(
options
==
'
picker
'
)
{
return
componentData
}
// If the component data exists and `options` is a string, carry out the action.
if
(
componentData
&&
typeof
options
==
'
string
'
)
{
return
PickerConstructor
.
_
.
trigger
(
componentData
[
options
],
componentData
,
[
action
]
)
}
// Otherwise go through each matched element and if the component
// doesn’t exist, create a new picker using `this` element
// and merging the defaults and options with a deep copy.
return
this
.
each
(
function
()
{
var
$this
=
$
(
this
)
if
(
!
$this
.
data
(
name
)
)
{
new
PickerConstructor
(
this
,
name
,
Component
,
options
)
}
})
}
// Set the defaults.
$
.
fn
[
name
].
defaults
=
Component
.
defaults
}
//PickerConstructor.extend
function
aria
(
element
,
attribute
,
value
)
{
if
(
$
.
isPlainObject
(
attribute
)
)
{
for
(
var
key
in
attribute
)
{
ariaSet
(
element
,
key
,
attribute
[
key
])
}
}
else
{
ariaSet
(
element
,
attribute
,
value
)
}
}
function
ariaSet
(
element
,
attribute
,
value
)
{
element
.
setAttribute
(
(
attribute
==
'
role
'
?
''
:
'
aria-
'
)
+
attribute
,
value
)
}
function
ariaAttr
(
attribute
,
data
)
{
if
(
!
$
.
isPlainObject
(
attribute
)
)
{
attribute
=
{
attribute
:
data
}
}
data
=
''
for
(
var
key
in
attribute
)
{
var
attr
=
(
key
==
'
role
'
?
''
:
'
aria-
'
)
+
key
,
attrVal
=
attribute
[
key
]
data
+=
attrVal
==
null
?
''
:
attr
+
'
="
'
+
attribute
[
key
]
+
'
"
'
}
return
data
}
// IE8 bug throws an error for activeElements within iframes.
function
getActiveElement
()
{
try
{
return
document
.
activeElement
}
catch
(
err
)
{
}
}
// Expose the picker constructor.
return
PickerConstructor
}));
src/main/webapp/static/plugins/pickadate/3.5.6/picker.time.js
0 → 100644
View file @
a866cd37
/*!
* Time picker for pickadate.js v3.5.6
* http://amsul.github.io/pickadate.js/time.htm
*/
(
function
(
factory
)
{
// AMD.
if
(
typeof
define
==
'
function
'
&&
define
.
amd
)
define
(
[
'
picker
'
,
'
jquery
'
],
factory
)
// Node.js/browserify.
else
if
(
typeof
exports
==
'
object
'
)
module
.
exports
=
factory
(
require
(
'
./picker.js
'
),
require
(
'
jquery
'
)
)
// Browser globals.
else
factory
(
Picker
,
jQuery
)
}(
function
(
Picker
,
$
)
{
/**
* Globals and constants
*/
var
HOURS_IN_DAY
=
24
,
MINUTES_IN_HOUR
=
60
,
HOURS_TO_NOON
=
12
,
MINUTES_IN_DAY
=
HOURS_IN_DAY
*
MINUTES_IN_HOUR
,
_
=
Picker
.
_
/**
* The time picker constructor
*/
function
TimePicker
(
picker
,
settings
)
{
var
clock
=
this
,
elementValue
=
picker
.
$node
[
0
].
value
,
elementDataValue
=
picker
.
$node
.
data
(
'
value
'
),
valueString
=
elementDataValue
||
elementValue
,
formatString
=
elementDataValue
?
settings
.
formatSubmit
:
settings
.
format
clock
.
settings
=
settings
clock
.
$node
=
picker
.
$node
// The queue of methods that will be used to build item objects.
clock
.
queue
=
{
interval
:
'
i
'
,
min
:
'
measure create
'
,
max
:
'
measure create
'
,
now
:
'
now create
'
,
select
:
'
parse create validate
'
,
highlight
:
'
parse create validate
'
,
view
:
'
parse create validate
'
,
disable
:
'
deactivate
'
,
enable
:
'
activate
'
}
// The component's item object.
clock
.
item
=
{}
clock
.
item
.
clear
=
null
clock
.
item
.
interval
=
settings
.
interval
||
30
clock
.
item
.
disable
=
(
settings
.
disable
||
[]
).
slice
(
0
)
clock
.
item
.
enable
=
-
(
function
(
collectionDisabled
)
{
return
collectionDisabled
[
0
]
===
true
?
collectionDisabled
.
shift
()
:
-
1
})(
clock
.
item
.
disable
)
clock
.
set
(
'
min
'
,
settings
.
min
).
set
(
'
max
'
,
settings
.
max
).
set
(
'
now
'
)
// When there’s a value, set the `select`, which in turn
// also sets the `highlight` and `view`.
if
(
valueString
)
{
clock
.
set
(
'
select
'
,
valueString
,
{
format
:
formatString
})
}
// If there’s no value, default to highlighting “today”.
else
{
clock
.
set
(
'
select
'
,
null
).
set
(
'
highlight
'
,
clock
.
item
.
now
)
}
// The keycode to movement mapping.
clock
.
key
=
{
40
:
1
,
// Down
38
:
-
1
,
// Up
39
:
1
,
// Right
37
:
-
1
,
// Left
go
:
function
(
timeChange
)
{
clock
.
set
(
'
highlight
'
,
clock
.
item
.
highlight
.
pick
+
timeChange
*
clock
.
item
.
interval
,
{
interval
:
timeChange
*
clock
.
item
.
interval
}
)
this
.
render
()
}
}
// Bind some picker events.
picker
.
on
(
'
render
'
,
function
()
{
var
$pickerHolder
=
picker
.
$root
.
children
(),
$viewset
=
$pickerHolder
.
find
(
'
.
'
+
settings
.
klass
.
viewset
),
vendors
=
function
(
prop
)
{
return
[
'
webkit
'
,
'
moz
'
,
'
ms
'
,
'
o
'
,
''
].
map
(
function
(
vendor
)
{
return
(
vendor
?
'
-
'
+
vendor
+
'
-
'
:
''
)
+
prop
})
},
animations
=
function
(
$el
,
state
)
{
vendors
(
'
transform
'
).
map
(
function
(
prop
)
{
$el
.
css
(
prop
,
state
)
})
vendors
(
'
transition
'
).
map
(
function
(
prop
)
{
$el
.
css
(
prop
,
state
)
})
}
if
(
$viewset
.
length
)
{
animations
(
$pickerHolder
,
'
none
'
)
$pickerHolder
[
0
].
scrollTop
=
~~
$viewset
.
position
().
top
-
(
$viewset
[
0
].
clientHeight
*
2
)
animations
(
$pickerHolder
,
''
)
}
},
1
).
on
(
'
open
'
,
function
()
{
picker
.
$root
.
find
(
'
button
'
).
attr
(
'
disabled
'
,
false
)
},
1
).
on
(
'
close
'
,
function
()
{
picker
.
$root
.
find
(
'
button
'
).
attr
(
'
disabled
'
,
true
)
},
1
)
}
//TimePicker
/**
* Set a timepicker item object.
*/
TimePicker
.
prototype
.
set
=
function
(
type
,
value
,
options
)
{
var
clock
=
this
,
clockItem
=
clock
.
item
// If the value is `null` just set it immediately.
if
(
value
===
null
)
{
if
(
type
==
'
clear
'
)
type
=
'
select
'
clockItem
[
type
]
=
value
return
clock
}
// Otherwise go through the queue of methods, and invoke the functions.
// Update this as the time unit, and set the final value as this item.
// * In the case of `enable`, keep the queue but set `disable` instead.
// And in the case of `flip`, keep the queue but set `enable` instead.
clockItem
[
(
type
==
'
enable
'
?
'
disable
'
:
type
==
'
flip
'
?
'
enable
'
:
type
)
]
=
clock
.
queue
[
type
].
split
(
'
'
).
map
(
function
(
method
)
{
value
=
clock
[
method
](
type
,
value
,
options
)
return
value
}).
pop
()
// Check if we need to cascade through more updates.
if
(
type
==
'
select
'
)
{
clock
.
set
(
'
highlight
'
,
clockItem
.
select
,
options
)
}
else
if
(
type
==
'
highlight
'
)
{
clock
.
set
(
'
view
'
,
clockItem
.
highlight
,
options
)
}
else
if
(
type
==
'
interval
'
)
{
clock
.
set
(
'
min
'
,
clockItem
.
min
,
options
).
set
(
'
max
'
,
clockItem
.
max
,
options
)
}
else
if
(
type
.
match
(
/^
(
flip|min|max|disable|enable
)
$/
)
)
{
if
(
clockItem
.
select
&&
clock
.
disabled
(
clockItem
.
select
)
)
{
clock
.
set
(
'
select
'
,
value
,
options
)
}
if
(
clockItem
.
highlight
&&
clock
.
disabled
(
clockItem
.
highlight
)
)
{
clock
.
set
(
'
highlight
'
,
value
,
options
)
}
if
(
type
==
'
min
'
)
{
clock
.
set
(
'
max
'
,
clockItem
.
max
,
options
)
}
}
return
clock
}
//TimePicker.prototype.set
/**
* Get a timepicker item object.
*/
TimePicker
.
prototype
.
get
=
function
(
type
)
{
return
this
.
item
[
type
]
}
//TimePicker.prototype.get
/**
* Create a picker time object.
*/
TimePicker
.
prototype
.
create
=
function
(
type
,
value
,
options
)
{
var
clock
=
this
// If there’s no value, use the type as the value.
value
=
value
===
undefined
?
type
:
value
// If it’s a date object, convert it into an array.
if
(
_
.
isDate
(
value
)
)
{
value
=
[
value
.
getHours
(),
value
.
getMinutes
()
]
}
// If it’s an object, use the “pick” value.
if
(
$
.
isPlainObject
(
value
)
&&
_
.
isInteger
(
value
.
pick
)
)
{
value
=
value
.
pick
}
// If it’s an array, convert it into minutes.
else
if
(
$
.
isArray
(
value
)
)
{
value
=
+
value
[
0
]
*
MINUTES_IN_HOUR
+
(
+
value
[
1
])
}
// If no valid value is passed, set it to “now”.
else
if
(
!
_
.
isInteger
(
value
)
)
{
value
=
clock
.
now
(
type
,
value
,
options
)
}
// If we’re setting the max, make sure it’s greater than the min.
if
(
type
==
'
max
'
&&
value
<
clock
.
item
.
min
.
pick
)
{
value
+=
MINUTES_IN_DAY
}
// If the value doesn’t fall directly on the interval,
// add one interval to indicate it as “passed”.
if
(
type
!=
'
min
'
&&
type
!=
'
max
'
&&
(
value
-
clock
.
item
.
min
.
pick
)
%
clock
.
item
.
interval
!==
0
)
{
value
+=
clock
.
item
.
interval
}
// Normalize it into a “reachable” interval.
value
=
clock
.
normalize
(
type
,
value
,
options
)
// Return the compiled object.
return
{
// Divide to get hours from minutes.
hour
:
~~
(
HOURS_IN_DAY
+
value
/
MINUTES_IN_HOUR
)
%
HOURS_IN_DAY
,
// The remainder is the minutes.
mins
:
(
MINUTES_IN_HOUR
+
value
%
MINUTES_IN_HOUR
)
%
MINUTES_IN_HOUR
,
// The time in total minutes.
time
:
(
MINUTES_IN_DAY
+
value
)
%
MINUTES_IN_DAY
,
// Reference to the “relative” value to pick.
pick
:
value
%
MINUTES_IN_DAY
}
}
//TimePicker.prototype.create
/**
* Create a range limit object using an array, date object,
* literal “true”, or integer relative to another time.
*/
TimePicker
.
prototype
.
createRange
=
function
(
from
,
to
)
{
var
clock
=
this
,
createTime
=
function
(
time
)
{
if
(
time
===
true
||
$
.
isArray
(
time
)
||
_
.
isDate
(
time
)
)
{
return
clock
.
create
(
time
)
}
return
time
}
// Create objects if possible.
if
(
!
_
.
isInteger
(
from
)
)
{
from
=
createTime
(
from
)
}
if
(
!
_
.
isInteger
(
to
)
)
{
to
=
createTime
(
to
)
}
// Create relative times.
if
(
_
.
isInteger
(
from
)
&&
$
.
isPlainObject
(
to
)
)
{
from
=
[
to
.
hour
,
to
.
mins
+
(
from
*
clock
.
settings
.
interval
)
];
}
else
if
(
_
.
isInteger
(
to
)
&&
$
.
isPlainObject
(
from
)
)
{
to
=
[
from
.
hour
,
from
.
mins
+
(
to
*
clock
.
settings
.
interval
)
];
}
return
{
from
:
createTime
(
from
),
to
:
createTime
(
to
)
}
}
//TimePicker.prototype.createRange
/**
* Check if a time unit falls within a time range object.
*/
TimePicker
.
prototype
.
withinRange
=
function
(
range
,
timeUnit
)
{
range
=
this
.
createRange
(
range
.
from
,
range
.
to
)
return
timeUnit
.
pick
>=
range
.
from
.
pick
&&
timeUnit
.
pick
<=
range
.
to
.
pick
}
/**
* Check if two time range objects overlap.
*/
TimePicker
.
prototype
.
overlapRanges
=
function
(
one
,
two
)
{
var
clock
=
this
// Convert the ranges into comparable times.
one
=
clock
.
createRange
(
one
.
from
,
one
.
to
)
two
=
clock
.
createRange
(
two
.
from
,
two
.
to
)
return
clock
.
withinRange
(
one
,
two
.
from
)
||
clock
.
withinRange
(
one
,
two
.
to
)
||
clock
.
withinRange
(
two
,
one
.
from
)
||
clock
.
withinRange
(
two
,
one
.
to
)
}
/**
* Get the time relative to now.
*/
TimePicker
.
prototype
.
now
=
function
(
type
,
value
/*, options*/
)
{
var
interval
=
this
.
item
.
interval
,
date
=
new
Date
(),
nowMinutes
=
date
.
getHours
()
*
MINUTES_IN_HOUR
+
date
.
getMinutes
(),
isValueInteger
=
_
.
isInteger
(
value
),
isBelowInterval
// Make sure “now” falls within the interval range.
nowMinutes
-=
nowMinutes
%
interval
// Check if the difference is less than the interval itself.
isBelowInterval
=
value
<
0
&&
interval
*
value
+
nowMinutes
<=
-
interval
// Add an interval because the time has “passed”.
nowMinutes
+=
type
==
'
min
'
&&
isBelowInterval
?
0
:
interval
// If the value is a number, adjust by that many intervals.
if
(
isValueInteger
)
{
nowMinutes
+=
interval
*
(
isBelowInterval
&&
type
!=
'
max
'
?
value
+
1
:
value
)
}
// Return the final calculation.
return
nowMinutes
}
//TimePicker.prototype.now
/**
* Normalize minutes to be “reachable” based on the min and interval.
*/
TimePicker
.
prototype
.
normalize
=
function
(
type
,
value
/*, options*/
)
{
var
interval
=
this
.
item
.
interval
,
minTime
=
this
.
item
.
min
&&
this
.
item
.
min
.
pick
||
0
// If setting min time, don’t shift anything.
// Otherwise get the value and min difference and then
// normalize the difference with the interval.
value
-=
type
==
'
min
'
?
0
:
(
value
-
minTime
)
%
interval
// Return the adjusted value.
return
value
}
//TimePicker.prototype.normalize
/**
* Measure the range of minutes.
*/
TimePicker
.
prototype
.
measure
=
function
(
type
,
value
,
options
)
{
var
clock
=
this
// If it’s anything false-y, set it to the default.
if
(
!
value
)
{
value
=
type
==
'
min
'
?
[
0
,
0
]
:
[
HOURS_IN_DAY
-
1
,
MINUTES_IN_HOUR
-
1
]
}
// If it’s a string, parse it.
if
(
typeof
value
==
'
string
'
)
{
value
=
clock
.
parse
(
type
,
value
)
}
// If it’s a literal true, or an integer, make it relative to now.
else
if
(
value
===
true
||
_
.
isInteger
(
value
)
)
{
value
=
clock
.
now
(
type
,
value
,
options
)
}
// If it’s an object already, just normalize it.
else
if
(
$
.
isPlainObject
(
value
)
&&
_
.
isInteger
(
value
.
pick
)
)
{
value
=
clock
.
normalize
(
type
,
value
.
pick
,
options
)
}
return
value
}
///TimePicker.prototype.measure
/**
* Validate an object as enabled.
*/
TimePicker
.
prototype
.
validate
=
function
(
type
,
timeObject
,
options
)
{
var
clock
=
this
,
interval
=
options
&&
options
.
interval
?
options
.
interval
:
clock
.
item
.
interval
// Check if the object is disabled.
if
(
clock
.
disabled
(
timeObject
)
)
{
// Shift with the interval until we reach an enabled time.
timeObject
=
clock
.
shift
(
timeObject
,
interval
)
}
// Scope the object into range.
timeObject
=
clock
.
scope
(
timeObject
)
// Do a second check to see if we landed on a disabled min/max.
// In that case, shift using the opposite interval as before.
if
(
clock
.
disabled
(
timeObject
)
)
{
timeObject
=
clock
.
shift
(
timeObject
,
interval
*
-
1
)
}
// Return the final object.
return
timeObject
}
//TimePicker.prototype.validate
/**
* Check if an object is disabled.
*/
TimePicker
.
prototype
.
disabled
=
function
(
timeToVerify
)
{
var
clock
=
this
,
// Filter through the disabled times to check if this is one.
isDisabledMatch
=
clock
.
item
.
disable
.
filter
(
function
(
timeToDisable
)
{
// If the time is a number, match the hours.
if
(
_
.
isInteger
(
timeToDisable
)
)
{
return
timeToVerify
.
hour
==
timeToDisable
}
// If it’s an array, create the object and match the times.
if
(
$
.
isArray
(
timeToDisable
)
||
_
.
isDate
(
timeToDisable
)
)
{
return
timeToVerify
.
pick
==
clock
.
create
(
timeToDisable
).
pick
}
// If it’s an object, match a time within the “from” and “to” range.
if
(
$
.
isPlainObject
(
timeToDisable
)
)
{
return
clock
.
withinRange
(
timeToDisable
,
timeToVerify
)
}
})
// If this time matches a disabled time, confirm it’s not inverted.
isDisabledMatch
=
isDisabledMatch
.
length
&&
!
isDisabledMatch
.
filter
(
function
(
timeToDisable
)
{
return
$
.
isArray
(
timeToDisable
)
&&
timeToDisable
[
2
]
==
'
inverted
'
||
$
.
isPlainObject
(
timeToDisable
)
&&
timeToDisable
.
inverted
}).
length
// If the clock is "enabled" flag is flipped, flip the condition.
return
clock
.
item
.
enable
===
-
1
?
!
isDisabledMatch
:
isDisabledMatch
||
timeToVerify
.
pick
<
clock
.
item
.
min
.
pick
||
timeToVerify
.
pick
>
clock
.
item
.
max
.
pick
}
//TimePicker.prototype.disabled
/**
* Shift an object by an interval until we reach an enabled object.
*/
TimePicker
.
prototype
.
shift
=
function
(
timeObject
,
interval
)
{
var
clock
=
this
,
minLimit
=
clock
.
item
.
min
.
pick
,
maxLimit
=
clock
.
item
.
max
.
pick
/*,
safety = 1000*/
interval
=
interval
||
clock
.
item
.
interval
// Keep looping as long as the time is disabled.
while
(
/*safety &&*/
clock
.
disabled
(
timeObject
)
)
{
/*safety -= 1
if ( !safety ) {
throw 'Fell into an infinite loop while shifting to ' + timeObject.hour + ':' + timeObject.mins + '.'
}*/
// Increase/decrease the time by the interval and keep looping.
timeObject
=
clock
.
create
(
timeObject
.
pick
+=
interval
)
// If we've looped beyond the limits, break out of the loop.
if
(
timeObject
.
pick
<=
minLimit
||
timeObject
.
pick
>=
maxLimit
)
{
break
}
}
// Return the final object.
return
timeObject
}
//TimePicker.prototype.shift
/**
* Scope an object to be within range of min and max.
*/
TimePicker
.
prototype
.
scope
=
function
(
timeObject
)
{
var
minLimit
=
this
.
item
.
min
.
pick
,
maxLimit
=
this
.
item
.
max
.
pick
return
this
.
create
(
timeObject
.
pick
>
maxLimit
?
maxLimit
:
timeObject
.
pick
<
minLimit
?
minLimit
:
timeObject
)
}
//TimePicker.prototype.scope
/**
* Parse a string into a usable type.
*/
TimePicker
.
prototype
.
parse
=
function
(
type
,
value
,
options
)
{
var
hour
,
minutes
,
isPM
,
item
,
parseValue
,
clock
=
this
,
parsingObject
=
{}
// If it’s already parsed, we’re good.
if
(
!
value
||
typeof
value
!=
'
string
'
)
{
return
value
}
// We need a `.format` to parse the value with.
if
(
!
(
options
&&
options
.
format
)
)
{
options
=
options
||
{}
options
.
format
=
clock
.
settings
.
format
}
// Convert the format into an array and then map through it.
clock
.
formats
.
toArray
(
options
.
format
).
map
(
function
(
label
)
{
var
substring
,
// Grab the formatting label.
formattingLabel
=
clock
.
formats
[
label
],
// The format length is from the formatting label function or the
// label length without the escaping exclamation (!) mark.
formatLength
=
formattingLabel
?
_
.
trigger
(
formattingLabel
,
clock
,
[
value
,
parsingObject
]
)
:
label
.
replace
(
/^!/
,
''
).
length
// If there's a format label, split the value up to the format length.
// Then add it to the parsing object with appropriate label.
if
(
formattingLabel
)
{
substring
=
value
.
substr
(
0
,
formatLength
)
parsingObject
[
label
]
=
substring
.
match
(
/^
\d
+$/
)
?
+
substring
:
substring
}
// Update the time value as the substring from format length to end.
value
=
value
.
substr
(
formatLength
)
})
// Grab the hour and minutes from the parsing object.
for
(
item
in
parsingObject
)
{
parseValue
=
parsingObject
[
item
]
if
(
_
.
isInteger
(
parseValue
)
)
{
if
(
item
.
match
(
/^
(
h|hh
)
$/i
)
)
{
hour
=
parseValue
if
(
item
==
'
h
'
||
item
==
'
hh
'
)
{
hour
%=
12
}
}
else
if
(
item
==
'
i
'
)
{
minutes
=
parseValue
}
}
else
if
(
item
.
match
(
/^a$/i
)
&&
parseValue
.
match
(
/^p/i
)
&&
(
'
h
'
in
parsingObject
||
'
hh
'
in
parsingObject
)
)
{
isPM
=
true
}
}
// Calculate it in minutes and return.
return
(
isPM
?
hour
+
12
:
hour
)
*
MINUTES_IN_HOUR
+
minutes
}
//TimePicker.prototype.parse
/**
* Various formats to display the object in.
*/
TimePicker
.
prototype
.
formats
=
{
h
:
function
(
string
,
timeObject
)
{
// If there's string, then get the digits length.
// Otherwise return the selected hour in "standard" format.
return
string
?
_
.
digits
(
string
)
:
timeObject
.
hour
%
HOURS_TO_NOON
||
HOURS_TO_NOON
},
hh
:
function
(
string
,
timeObject
)
{
// If there's a string, then the length is always 2.
// Otherwise return the selected hour in "standard" format with a leading zero.
return
string
?
2
:
_
.
lead
(
timeObject
.
hour
%
HOURS_TO_NOON
||
HOURS_TO_NOON
)
},
H
:
function
(
string
,
timeObject
)
{
// If there's string, then get the digits length.
// Otherwise return the selected hour in "military" format as a string.
return
string
?
_
.
digits
(
string
)
:
''
+
(
timeObject
.
hour
%
24
)
},
HH
:
function
(
string
,
timeObject
)
{
// If there's string, then get the digits length.
// Otherwise return the selected hour in "military" format with a leading zero.
return
string
?
_
.
digits
(
string
)
:
_
.
lead
(
timeObject
.
hour
%
24
)
},
i
:
function
(
string
,
timeObject
)
{
// If there's a string, then the length is always 2.
// Otherwise return the selected minutes.
return
string
?
2
:
_
.
lead
(
timeObject
.
mins
)
},
a
:
function
(
string
,
timeObject
)
{
// If there's a string, then the length is always 4.
// Otherwise check if it's more than "noon" and return either am/pm.
return
string
?
4
:
MINUTES_IN_DAY
/
2
>
timeObject
.
time
%
MINUTES_IN_DAY
?
'
a.m.
'
:
'
p.m.
'
},
A
:
function
(
string
,
timeObject
)
{
// If there's a string, then the length is always 2.
// Otherwise check if it's more than "noon" and return either am/pm.
return
string
?
2
:
MINUTES_IN_DAY
/
2
>
timeObject
.
time
%
MINUTES_IN_DAY
?
'
AM
'
:
'
PM
'
},
// Create an array by splitting the formatting string passed.
toArray
:
function
(
formatString
)
{
return
formatString
.
split
(
/
(
h
{1,2}
|H
{1,2}
|i|a|A|!.
)
/g
)
},
// Format an object into a string using the formatting options.
toString
:
function
(
formatString
,
itemObject
)
{
var
clock
=
this
return
clock
.
formats
.
toArray
(
formatString
).
map
(
function
(
label
)
{
return
_
.
trigger
(
clock
.
formats
[
label
],
clock
,
[
0
,
itemObject
]
)
||
label
.
replace
(
/^!/
,
''
)
}).
join
(
''
)
}
}
//TimePicker.prototype.formats
/**
* Check if two time units are the exact.
*/
TimePicker
.
prototype
.
isTimeExact
=
function
(
one
,
two
)
{
var
clock
=
this
// When we’re working with minutes, do a direct comparison.
if
(
(
_
.
isInteger
(
one
)
&&
_
.
isInteger
(
two
)
)
||
(
typeof
one
==
'
boolean
'
&&
typeof
two
==
'
boolean
'
)
)
{
return
one
===
two
}
// When we’re working with time representations, compare the “pick” value.
if
(
(
_
.
isDate
(
one
)
||
$
.
isArray
(
one
)
)
&&
(
_
.
isDate
(
two
)
||
$
.
isArray
(
two
)
)
)
{
return
clock
.
create
(
one
).
pick
===
clock
.
create
(
two
).
pick
}
// When we’re working with range objects, compare the “from” and “to”.
if
(
$
.
isPlainObject
(
one
)
&&
$
.
isPlainObject
(
two
)
)
{
return
clock
.
isTimeExact
(
one
.
from
,
two
.
from
)
&&
clock
.
isTimeExact
(
one
.
to
,
two
.
to
)
}
return
false
}
/**
* Check if two time units overlap.
*/
TimePicker
.
prototype
.
isTimeOverlap
=
function
(
one
,
two
)
{
var
clock
=
this
// When we’re working with an integer, compare the hours.
if
(
_
.
isInteger
(
one
)
&&
(
_
.
isDate
(
two
)
||
$
.
isArray
(
two
)
)
)
{
return
one
===
clock
.
create
(
two
).
hour
}
if
(
_
.
isInteger
(
two
)
&&
(
_
.
isDate
(
one
)
||
$
.
isArray
(
one
)
)
)
{
return
two
===
clock
.
create
(
one
).
hour
}
// When we’re working with range objects, check if the ranges overlap.
if
(
$
.
isPlainObject
(
one
)
&&
$
.
isPlainObject
(
two
)
)
{
return
clock
.
overlapRanges
(
one
,
two
)
}
return
false
}
/**
* Flip the “enabled” state.
*/
TimePicker
.
prototype
.
flipEnable
=
function
(
val
)
{
var
itemObject
=
this
.
item
itemObject
.
enable
=
val
||
(
itemObject
.
enable
==
-
1
?
1
:
-
1
)
}
/**
* Mark a collection of times as “disabled”.
*/
TimePicker
.
prototype
.
deactivate
=
function
(
type
,
timesToDisable
)
{
var
clock
=
this
,
disabledItems
=
clock
.
item
.
disable
.
slice
(
0
)
// If we’re flipping, that’s all we need to do.
if
(
timesToDisable
==
'
flip
'
)
{
clock
.
flipEnable
()
}
else
if
(
timesToDisable
===
false
)
{
clock
.
flipEnable
(
1
)
disabledItems
=
[]
}
else
if
(
timesToDisable
===
true
)
{
clock
.
flipEnable
(
-
1
)
disabledItems
=
[]
}
// Otherwise go through the times to disable.
else
{
timesToDisable
.
map
(
function
(
unitToDisable
)
{
var
matchFound
// When we have disabled items, check for matches.
// If something is matched, immediately break out.
for
(
var
index
=
0
;
index
<
disabledItems
.
length
;
index
+=
1
)
{
if
(
clock
.
isTimeExact
(
unitToDisable
,
disabledItems
[
index
]
)
)
{
matchFound
=
true
break
}
}
// If nothing was found, add the validated unit to the collection.
if
(
!
matchFound
)
{
if
(
_
.
isInteger
(
unitToDisable
)
||
_
.
isDate
(
unitToDisable
)
||
$
.
isArray
(
unitToDisable
)
||
(
$
.
isPlainObject
(
unitToDisable
)
&&
unitToDisable
.
from
&&
unitToDisable
.
to
)
)
{
disabledItems
.
push
(
unitToDisable
)
}
}
})
}
// Return the updated collection.
return
disabledItems
}
//TimePicker.prototype.deactivate
/**
* Mark a collection of times as “enabled”.
*/
TimePicker
.
prototype
.
activate
=
function
(
type
,
timesToEnable
)
{
var
clock
=
this
,
disabledItems
=
clock
.
item
.
disable
,
disabledItemsCount
=
disabledItems
.
length
// If we’re flipping, that’s all we need to do.
if
(
timesToEnable
==
'
flip
'
)
{
clock
.
flipEnable
()
}
else
if
(
timesToEnable
===
true
)
{
clock
.
flipEnable
(
1
)
disabledItems
=
[]
}
else
if
(
timesToEnable
===
false
)
{
clock
.
flipEnable
(
-
1
)
disabledItems
=
[]
}
// Otherwise go through the disabled times.
else
{
timesToEnable
.
map
(
function
(
unitToEnable
)
{
var
matchFound
,
disabledUnit
,
index
,
isRangeMatched
// Go through the disabled items and try to find a match.
for
(
index
=
0
;
index
<
disabledItemsCount
;
index
+=
1
)
{
disabledUnit
=
disabledItems
[
index
]
// When an exact match is found, remove it from the collection.
if
(
clock
.
isTimeExact
(
disabledUnit
,
unitToEnable
)
)
{
matchFound
=
disabledItems
[
index
]
=
null
isRangeMatched
=
true
break
}
// When an overlapped match is found, add the “inverted” state to it.
else
if
(
clock
.
isTimeOverlap
(
disabledUnit
,
unitToEnable
)
)
{
if
(
$
.
isPlainObject
(
unitToEnable
)
)
{
unitToEnable
.
inverted
=
true
matchFound
=
unitToEnable
}
else
if
(
$
.
isArray
(
unitToEnable
)
)
{
matchFound
=
unitToEnable
if
(
!
matchFound
[
2
]
)
matchFound
.
push
(
'
inverted
'
)
}
else
if
(
_
.
isDate
(
unitToEnable
)
)
{
matchFound
=
[
unitToEnable
.
getFullYear
(),
unitToEnable
.
getMonth
(),
unitToEnable
.
getDate
(),
'
inverted
'
]
}
break
}
}
// If a match was found, remove a previous duplicate entry.
if
(
matchFound
)
for
(
index
=
0
;
index
<
disabledItemsCount
;
index
+=
1
)
{
if
(
clock
.
isTimeExact
(
disabledItems
[
index
],
unitToEnable
)
)
{
disabledItems
[
index
]
=
null
break
}
}
// In the event that we’re dealing with an overlap of range times,
// make sure there are no “inverted” times because of it.
if
(
isRangeMatched
)
for
(
index
=
0
;
index
<
disabledItemsCount
;
index
+=
1
)
{
if
(
clock
.
isTimeOverlap
(
disabledItems
[
index
],
unitToEnable
)
)
{
disabledItems
[
index
]
=
null
break
}
}
// If something is still matched, add it into the collection.
if
(
matchFound
)
{
disabledItems
.
push
(
matchFound
)
}
})
}
// Return the updated collection.
return
disabledItems
.
filter
(
function
(
val
)
{
return
val
!=
null
})
}
//TimePicker.prototype.activate
/**
* The division to use for the range intervals.
*/
TimePicker
.
prototype
.
i
=
function
(
type
,
value
/*, options*/
)
{
return
_
.
isInteger
(
value
)
&&
value
>
0
?
value
:
this
.
item
.
interval
}
/**
* Create a string for the nodes in the picker.
*/
TimePicker
.
prototype
.
nodes
=
function
(
isOpen
)
{
var
clock
=
this
,
settings
=
clock
.
settings
,
selectedObject
=
clock
.
item
.
select
,
highlightedObject
=
clock
.
item
.
highlight
,
viewsetObject
=
clock
.
item
.
view
,
disabledCollection
=
clock
.
item
.
disable
return
_
.
node
(
'
ul
'
,
_
.
group
({
min
:
clock
.
item
.
min
.
pick
,
max
:
clock
.
item
.
max
.
pick
,
i
:
clock
.
item
.
interval
,
node
:
'
li
'
,
item
:
function
(
loopedTime
)
{
loopedTime
=
clock
.
create
(
loopedTime
)
var
timeMinutes
=
loopedTime
.
pick
,
isSelected
=
selectedObject
&&
selectedObject
.
pick
==
timeMinutes
,
isHighlighted
=
highlightedObject
&&
highlightedObject
.
pick
==
timeMinutes
,
isDisabled
=
disabledCollection
&&
clock
.
disabled
(
loopedTime
),
formattedTime
=
_
.
trigger
(
clock
.
formats
.
toString
,
clock
,
[
settings
.
format
,
loopedTime
]
)
return
[
_
.
trigger
(
clock
.
formats
.
toString
,
clock
,
[
_
.
trigger
(
settings
.
formatLabel
,
clock
,
[
loopedTime
]
)
||
settings
.
format
,
loopedTime
]
),
(
function
(
klasses
)
{
if
(
isSelected
)
{
klasses
.
push
(
settings
.
klass
.
selected
)
}
if
(
isHighlighted
)
{
klasses
.
push
(
settings
.
klass
.
highlighted
)
}
if
(
viewsetObject
&&
viewsetObject
.
pick
==
timeMinutes
)
{
klasses
.
push
(
settings
.
klass
.
viewset
)
}
if
(
isDisabled
)
{
klasses
.
push
(
settings
.
klass
.
disabled
)
}
return
klasses
.
join
(
'
'
)
})(
[
settings
.
klass
.
listItem
]
),
'
data-pick=
'
+
loopedTime
.
pick
+
'
'
+
_
.
ariaAttr
({
role
:
'
option
'
,
label
:
formattedTime
,
selected
:
isSelected
&&
clock
.
$node
.
val
()
===
formattedTime
?
true
:
null
,
activedescendant
:
isHighlighted
?
true
:
null
,
disabled
:
isDisabled
?
true
:
null
})
]
}
})
+
// * For Firefox forms to submit, make sure to set the button’s `type` attribute as “button”.
_
.
node
(
'
li
'
,
_
.
node
(
'
button
'
,
settings
.
clear
,
settings
.
klass
.
buttonClear
,
'
type=button data-clear=1
'
+
(
isOpen
?
''
:
'
disabled
'
)
+
'
'
+
_
.
ariaAttr
({
controls
:
clock
.
$node
[
0
].
id
})
),
''
,
_
.
ariaAttr
({
role
:
'
presentation
'
})
),
settings
.
klass
.
list
,
_
.
ariaAttr
({
role
:
'
listbox
'
,
controls
:
clock
.
$node
[
0
].
id
})
)
}
//TimePicker.prototype.nodes
/**
* Extend the picker to add the component with the defaults.
*/
TimePicker
.
defaults
=
(
function
(
prefix
)
{
return
{
// Clear
clear
:
'
Clear
'
,
// The format to show on the `input` element
format
:
'
h:i A
'
,
// The interval between each time
interval
:
30
,
// Picker close behavior
closeOnSelect
:
true
,
closeOnClear
:
true
,
// Classes
klass
:
{
picker
:
prefix
+
'
'
+
prefix
+
'
--time
'
,
holder
:
prefix
+
'
__holder
'
,
list
:
prefix
+
'
__list
'
,
listItem
:
prefix
+
'
__list-item
'
,
disabled
:
prefix
+
'
__list-item--disabled
'
,
selected
:
prefix
+
'
__list-item--selected
'
,
highlighted
:
prefix
+
'
__list-item--highlighted
'
,
viewset
:
prefix
+
'
__list-item--viewset
'
,
now
:
prefix
+
'
__list-item--now
'
,
buttonClear
:
prefix
+
'
__button--clear
'
}
}
})(
Picker
.
klasses
().
picker
)
/**
* Extend the picker to add the time picker.
*/
Picker
.
extend
(
'
pickatime
'
,
TimePicker
)
}));
src/main/webapp/static/plugins/pickadate/3.5.6/themes-source/_variables.less
0 → 100644
View file @
a866cd37
// ==========================================================================
// $VARIABLES
// ==========================================================================
//
// Base colors
//
@blue: #0089ec;
@blue-hover: #b1dcfb;
@black: #000;
@white: #fff;
//
// Backgrounds
//
@bg-white: @white;
@bg-grey-light: #f2f2f2;
//
// Borders
//
@border-grey: #777;
@border-grey-light: #ddd;
@border-select: darken( @border-grey-light, 15% );
//
// Buttons
//
@clear-red: #e20;
//
// Picker base
//
// Make sure nothing is above the picker.
@picker-z-index: 10000;
// Animation speeds.
@speed-animate-in: .15s;
// Focused input border color.
@input-active-border: @blue;
// Typography.
@base-font-size: 16px;
@base-line-height: 1.2;
// Corners.
@picker-border-radius: 5px;
// Drop shadows.
@picker-box-shadow: 0 12px 36px 16px rgba(0,0,0,.24);
@picker-box-shadow-light: 0 6px 18px 1px rgba(0,0,0,.12);
// Height breakpoints.
@breakpoint-tiny: 26.5em; // 424px @ 16px
@breakpoint-small: 33.875em; // 542px @ 16px
@breakpoint-medium: 40.125em; // 642px @ 16px
@breakpoint-large: 46.75em; // 748px @ 16px
// Width breakpoints.
@breakpoint-width-tiny: 24.5em; // 392px @ 16px
//
// Date picker options
//
// The year and weekday labels.
@year-weekday-label: #999;
// “Today” tag indicators.
@blue-tag: #0059bc;
@disabled-tag: #aaa;
// Disabled things.. such as days, month nav, etc.
@disabled-things-bg: #f5f5f5;
@disabled-things-text: #ddd;
@disabled-highlighted-things-bg: #bbb;
//
// Theme configurations
//
// The “default” min & max widths.
@picker-min-width: 256px;
@picker-max-width: 666px;
// The time picker min & max widths.
@time-min-width: @picker-min-width;
@time-max-width: 320px;
// The “classic” theme settings.
@classic-max-width: @picker-max-width - 200px;
@classic-min-width: @picker-min-width - 80px;
@classic-max-height: 25em;
@classic-box-shadow: 0 6px 18px 1px rgba(0,0,0,.12);
// ==========================================================================
// $MIXINS
// ==========================================================================
//
// Common picker item states
//
// Highlighted.
.picker-item-highlighted () {
border-color: @blue;
}
// Hovered.
.picker-item-hovered () {
cursor: pointer;
color: @black;
background: @blue-hover;
}
// Selected.
.picker-item-selected () {
background: @blue;
color: @white;
}
// Disabled.
.picker-item-disabled () {
background: @disabled-things-bg;
border-color: @disabled-things-bg;
color: @disabled-things-text;
cursor: default;
}
//
// Opacity
//
.opacity( @decimal ) {
@percent: @decimal * 100;
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=@{percent})";
filter: ~"alpha(opacity=@{percent})";
-moz-opacity: @decimal;
opacity: @decimal;
}
src/main/webapp/static/plugins/pickadate/3.5.6/themes-source/base.date.less
0 → 100644
View file @
a866cd37
/* ==========================================================================
$BASE-DATE-PICKER
========================================================================== */
@import "_variables.less";
/**
* The picker box.
*/
.picker__box {
padding: 0 1em;
}
/**
* The header containing the month and year stuff.
*/
.picker__header {
text-align: center;
position: relative;
margin-top: .75em;
}
/**
* The month and year labels.
*/
.picker__month,
.picker__year {
font-weight: 500;
display: inline-block;
margin-left: .25em;
margin-right: .25em;
}
.picker__year {
color: @year-weekday-label;
font-size: .8em;
font-style: italic;
}
/**
* The month and year selectors.
*/
.picker__select--month,
.picker__select--year {
border: 1px solid @border-select;
height: 2em;
padding: .5em; // For firefox
margin-left: .25em;
margin-right: .25em;
// For `tiny` width screens, move it up a bit.
@media ( min-width: @breakpoint-width-tiny ) {
margin-top: -.5em;
}
}
.picker__select--month {
width: 35%;
}
.picker__select--year {
width: 22.5%;
}
.picker__select--month:focus,
.picker__select--year:focus {
border-color: @blue;
}
/**
* The month navigation buttons.
*/
.picker__nav--prev,
.picker__nav--next {
position: absolute;
padding: .5em 1.25em;
width: 1em;
height: 1em;
box-sizing: content-box;
top: -.25em;
// For `tiny` width screens, move it up a bit.
@media ( min-width: @breakpoint-width-tiny ) {
top: -.33em;
}
}
.picker__nav--prev {
left: -1em;
padding-right: 1.25em;
// For `tiny` width screens, increase the padding a bit.
@media ( min-width: @breakpoint-width-tiny ) {
padding-right: 1.5em;
}
}
.picker__nav--next {
right: -1em;
padding-left: 1.25em;
// For `tiny` width screens, increase the padding a bit.
@media ( min-width: @breakpoint-width-tiny ) {
padding-left: 1.5em;
}
}
.picker__nav--prev:before,
.picker__nav--next:before {
content: " ";
border-top: .5em solid transparent;
border-bottom: .5em solid transparent;
border-right: .75em solid @black;
width: 0;
height: 0;
display: block;
margin: 0 auto;
}
.picker__nav--next:before {
border-right: 0;
border-left: .75em solid @black;
}
// Hovered date picker items.
.picker__nav--prev:hover,
.picker__nav--next:hover {
.picker-item-hovered;
}
// Disabled month nav.
.picker__nav--disabled,
.picker__nav--disabled:hover,
.picker__nav--disabled:before,
.picker__nav--disabled:before:hover {
cursor: default;
background: none;
border-right-color: @disabled-things-bg;
border-left-color: @disabled-things-bg;
}
/**
* The calendar table of dates
*/
.picker__table {
text-align: center;
border-collapse: collapse;
border-spacing: 0;
table-layout: fixed;
font-size: inherit;
width: 100%;
margin-top: .75em;
margin-bottom: .5em;
// For `small` screens, increase the spacing a tad.
@media ( min-height: @breakpoint-small ) {
margin-bottom: .75em;
}
}
// Remove browser stylings on a table cell.
.picker__table td {
margin: 0;
padding: 0;
}
/**
* The weekday labels
*/
.picker__weekday {
width: 14.285714286%; // 100/7
font-size: .75em;
padding-bottom: .25em;
color: @year-weekday-label;
font-weight: 500;
/* Increase the spacing a tad */
@media ( min-height: @breakpoint-small ) {
padding-bottom: .5em;
}
}
/**
* The days on the calendar
*/
.picker__day {
padding: .3125em 0;
font-weight: 200;
border: 1px solid transparent;
}
// Today.
.picker__day--today {
position: relative;
}
.picker__day--today:before {
content: " ";
position: absolute;
top: 2px;
right: 2px;
width: 0;
height: 0;
border-top: .5em solid @blue-tag;
border-left: .5em solid transparent;
}
// Disabled day.
.picker__day--disabled:before {
border-top-color: @disabled-tag;
}
// Out of focus days.
.picker__day--outfocus {
color: @disabled-things-text;
}
// Hovered date picker items.
.picker__day--infocus:hover,
.picker__day--outfocus:hover {
.picker-item-hovered;
}
// Highlighted and hovered/focused dates.
.picker__day--highlighted {
.picker-item-highlighted;
}
.picker__day--highlighted:hover,
.picker--focused .picker__day--highlighted {
.picker-item-hovered;
}
// Selected and hovered/focused dates.
.picker__day--selected,
.picker__day--selected:hover,
.picker--focused .picker__day--selected {
.picker-item-selected;
}
// Disabled dates.
.picker__day--disabled,
.picker__day--disabled:hover,
.picker--focused .picker__day--disabled {
.picker-item-disabled;
}
// Disabled and highlighted dates.
.picker__day--highlighted.picker__day--disabled,
.picker__day--highlighted.picker__day--disabled:hover {
background: @disabled-highlighted-things-bg;
}
/**
* The footer containing the "today", "clear", and "close" buttons.
*/
.picker__footer {
text-align: center;
}
// Today, clear, and close buttons.
.picker__button--today,
.picker__button--clear,
.picker__button--close {
border: 1px solid @white;
background: @white;
font-size: .8em;
padding: .66em 0;
font-weight: bold;
width: 33%;
display: inline-block;
vertical-align: bottom;
}
.picker__button--today:hover,
.picker__button--clear:hover,
.picker__button--close:hover {
.picker-item-hovered;
border-bottom-color: @blue-hover;
}
.picker__button--today:focus,
.picker__button--clear:focus,
.picker__button--close:focus {
background: @blue-hover;
border-color: @blue;
outline: none;
}
// Today, clear, and close “indicators”.
.picker__button--today:before,
.picker__button--clear:before,
.picker__button--close:before {
position: relative;
display: inline-block;
height: 0;
}
.picker__button--today:before,
.picker__button--clear:before {
content: " ";
margin-right: .45em;
}
.picker__button--today:before {
top: -.05em;
width: 0;
border-top: .66em solid @blue-tag;
border-left: .66em solid transparent;
}
.picker__button--clear:before {
top: -.25em;
width: .66em;
border-top: 3px solid @clear-red;
}
.picker__button--close:before {
content: "\D7"; // ×
top: -.1em;
vertical-align: top;
font-size: 1.1em;
margin-right: .35em;
color: @border-grey;
}
// Today when “disabled”.
.picker__button--today[disabled],
.picker__button--today[disabled]:hover {
.picker-item-disabled;
}
.picker__button--today[disabled]:before {
border-top-color: @disabled-tag;
}
src/main/webapp/static/plugins/pickadate/3.5.6/themes-source/base.less
0 → 100644
View file @
a866cd37
/* ==========================================================================
$BASE-PICKER
========================================================================== */
@import "_variables.less";
/**
* Note: the root picker element should *NOT* be styled more than what’s here.
*/
.picker {
// The base font stylings.
font-size: @base-font-size;
text-align: left;
line-height: @base-line-height;
color: @black;
// The picker shouldn’t affect or be affected by elements around it.
position: absolute;
z-index: @picker-z-index;
// The picker shouldn’t be selectable.
user-select: none;
}
/**
* The picker input element.
*/
.picker__input {
cursor: default;
}
/**
* When the picker is opened, the input element is “activated”.
*/
.picker__input.picker__input--active {
border-color: @input-active-border;
}
/**
* The holder is the only “scrollable” top-level container element.
*/
.picker__holder {
width: 100%;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
}
src/main/webapp/static/plugins/pickadate/3.5.6/themes-source/base.time.less
0 → 100644
View file @
a866cd37
/* ==========================================================================
$BASE-TIME-PICKER
========================================================================== */
@import "_variables.less";
/**
* The list of times.
*/
.picker__list {
list-style: none;
padding: 0.75em 0 4.2em;
margin: 0;
}
/**
* The times on the clock.
*/
.picker__list-item {
border-bottom: 1px solid @border-grey-light;
border-top: 1px solid @border-grey-light;
margin-bottom: -1px; // Prevent border from doubling up.
position: relative;
background: @bg-white;
padding: .75em 1.25em;
// For `large` screens, reduce the padding to show more in view.
@media ( min-height: @breakpoint-large ) {
padding: .5em 1em;
}
}
/* Hovered time */
.picker__list-item:hover {
.picker-item-hovered;
border-color: @blue;
z-index: 10;
}
/* Highlighted and hovered/focused time */
.picker__list-item--highlighted {
.picker-item-highlighted;
z-index: 10;
}
.picker__list-item--highlighted:hover,
.picker--focused .picker__list-item--highlighted {
.picker-item-hovered;
}
/* Selected and hovered/focused time */
.picker__list-item--selected,
.picker__list-item--selected:hover,
.picker--focused .picker__list-item--selected {
.picker-item-selected;
z-index: 10;
}
/* Disabled time */
.picker__list-item--disabled,
.picker__list-item--disabled:hover,
.picker--focused .picker__list-item--disabled {
.picker-item-disabled;
border-color: @border-grey-light;
z-index: auto;
}
/**
* The clear button
*/
.picker--time {
.picker__button--clear {
display: block;
width: 80%;
margin: 1em auto 0;
padding: 1em 1.25em;
background: none;
border: 0;
font-weight: 500;
font-size: .67em;
text-align: center;
text-transform: uppercase;
color: #666;
}
.picker__button--clear:hover,
.picker__button--clear:focus {
.picker-item-hovered;
background: @clear-red;
border-color: @clear-red;
cursor: pointer;
color: @white;
outline: none;
}
.picker__button--clear:before {
top: -.25em;
color: #666;
font-size: 1.25em;
font-weight: bold;
}
.picker__button--clear:hover:before,
.picker__button--clear:focus:before {
color: @white;
border-color: @white;
}
}
src/main/webapp/static/plugins/pickadate/3.5.6/themes-source/classic.date.less
0 → 100644
View file @
a866cd37
/* ==========================================================================
$CLASSIC-DATE-PICKER
========================================================================== */
@import "_variables.less";
src/main/webapp/static/plugins/pickadate/3.5.6/themes-source/classic.less
0 → 100644
View file @
a866cd37
/*!
* Classic picker styling for pickadate.js
* Demo: http://amsul.github.io/pickadate.js
*/
@import "_variables.less";
/**
* Note: the root picker element should *NOT* be styled more than what’s here.
*/
.picker {
// Make it full-width so that it doesn’t collapse.
width: 100%;
}
/**
* The holder is the base of the picker.
*/
.picker__holder {
// The base stylings.
position: absolute;
background: @bg-white;
// Add a light border - except top & bottom to let it collapse.
border: 1px solid lighten( @border-grey, 20% );
border-top-width: 0;
border-bottom-width: 0;
// Round the bottom corners.
border-radius: 0 0 @picker-border-radius @picker-border-radius;
// Let’s not go 100% + 2px.
box-sizing: border-box;
// Specify the min & max widths.
min-width: @classic-min-width;
max-width: @classic-max-width;
// Hide everything to begin with.
max-height: 0;
.opacity( 0 );
// Tilt the picker.
transform: translateY( -1em ) perspective( 600px ) rotateX( 10deg );
// Everything should be smoothly animated – the height & border should wait till the rest is done.
transition: transform @speed-animate-in ease-out,
opacity @speed-animate-in ease-out,
max-height 0s @speed-animate-in,
border-width 0s @speed-animate-in;
}
/**
* The frame and wrap work together to ensure that
* clicks within the picker don’t reach the holder.
*/
.picker__frame {
padding: 1px;
}
.picker__wrap {
margin: -1px;
}
/**
* When the picker opens...
*/
.picker--opened {
.picker__holder {
// Reveal the content.
max-height: @classic-max-height;
.opacity( 1 );
// Expand the top & bottom borders.
border-top-width: 1px;
border-bottom-width: 1px;
// Straighten the picker.
transform: translateY( 0 ) perspective( 600px ) rotateX( 0 );
// Everything should be smoothly animated – except the height & border.
transition: transform @speed-animate-in ease-out,
opacity @speed-animate-in ease-out,
max-height 0s,
border-width 0s;
// Add a light shadow.
box-shadow: @classic-box-shadow;
}
}
src/main/webapp/static/plugins/pickadate/3.5.6/themes-source/classic.time.less
0 → 100644
View file @
a866cd37
/* ==========================================================================
$CLASSIC-TIME-PICKER
========================================================================== */
@import "_variables.less";
/**
* Note: the root picker element should __NOT__ be styled
* more than what’s here. Style the `.picker__holder` instead.
*/
.picker--time {
// Adjust the min & max widths.
min-width: @time-min-width;
max-width: @time-max-width;
}
/**
* The holder is the base of the picker.
*/
.picker--time .picker__holder {
// Add a slight background color.
background: @bg-grey-light;
// For `medium` screens, reduce the font-size a bit to get more in view.
@media ( min-height: @breakpoint-medium ) {
font-size: .875em;
}
}
/**
* The box contains the list of times.
*/
.picker--time .picker__box {
// Remove any stylings overflowing from the date picker.
padding: 0;
// Make the “viewset” time position relative to the box.
position: relative;
}
src/main/webapp/static/plugins/pickadate/3.5.6/themes-source/default.date.less
0 → 100644
View file @
a866cd37
/* ==========================================================================
$DEFAULT-DATE-PICKER
========================================================================== */
@import "_variables.less";
src/main/webapp/static/plugins/pickadate/3.5.6/themes-source/default.less
0 → 100644
View file @
a866cd37
/*!
* Default mobile-first, responsive styling for pickadate.js
* Demo: http://amsul.github.io/pickadate.js
*/
@import "_variables.less";
/**
* Note: the root picker element should *NOT* be styled more than what’s here.
*/
.picker {}
/**
* Make the holder and frame fullscreen.
*/
.picker__holder,
.picker__frame {
top: 0;
bottom: 0;
left: 0;
right: 0;
// Nudge everything off-screen to begin with.
transform: translateY(100%);
}
/**
* The holder should overlay the entire screen.
*/
.picker__holder {
// Fill the screen and fix the position.
position: fixed;
// Fade out the background, then immediately shift the holder out of view.
transition: background @speed-animate-in ease-out, transform 0s @speed-animate-in;
// Avoid flickering of the page on webkit browsers
-webkit-backface-visibility: hidden;
}
/**
* The frame that bounds the box contents of the picker.
*/
.picker__frame {
position: absolute;
// Specify the min & max widths and center align it.
margin: 0 auto;
min-width: @picker-min-width;
max-width: @picker-max-width;
width: 100%; // For IE9 & 10 to keep it centered.
// Hide it to begin with.
.opacity( 0 );
// Animate the frame in and out of view.
transition: all @speed-animate-in ease-out;
// For `small` screens...
@media ( min-height: @breakpoint-small ) {
// Reveal what’s beyond to allow drop shadows, et al.
overflow: visible;
// Align to the bottom edge instead of top.
top: auto;
bottom: -100%;
// Prevent it from overflowing over the top edge.
max-height: 80%;
}
// For `medium` screens...
@media ( min-height: @breakpoint-medium ) {
// Move away from the bottom edge.
margin-bottom: 7.5%;
}
}
/**
* The wrapper sets the stage to vertically align the box contents.
*/
.picker__wrap {
display: table;
width: 100%;
height: 100%;
// For `small` screens, remove the “middle-aligned” styling
@media ( min-height: @breakpoint-small ) {
display: block;
}
}
/**
* The box contains all the picker contents.
*/
.picker__box {
background: @bg-white;
// To start with, vertically align to center
display: table-cell;
vertical-align: middle;
// For `tiny` screens, increase the font size a bit
@media ( min-height: @breakpoint-tiny ) {
font-size: 1.25em;
}
// For `small` screens...
@media ( min-height: @breakpoint-small ) {
// Remove the “middle-aligned” styling
display: block;
// Increase the font size a bit more
font-size: 1.33em;
// Add the borders except the bottom one
border: 1px solid @border-grey;
border-top-color: lighten( @border-grey, 7% );
border-bottom-width: 0;
// Make ‘em rounded at the top corners
border-radius: @picker-border-radius @picker-border-radius 0 0;
// And finally, add a nice shadow
box-shadow: @picker-box-shadow;
}
// For `medium` screens...
@media ( min-height: @breakpoint-medium ) {
// Increase the font size.
font-size: 1.5em;
// Reveal all borders and round all corners.
border-bottom-width: 1px;
border-radius: @picker-border-radius;
}
}
/**
* When the picker opens...
*/
.picker--opened {
// Immediately move the holder to the top edge then fade in an overlay
.picker__holder {
// Move it to the top edge
transform: translateY(0);
// Show a translucent black background (order is important for IE)
background: transparent;
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#1E000000,endColorstr=#1E000000)"; // IE8
zoom: 1;
background: rgba(0,0,0,.32); // Normal browsers
// Animate in the background
transition: background @speed-animate-in ease-out;
}
// Smoothly move the content to the top edge while fading it in
.picker__frame {
// Move to the top edge
transform: translateY(0);
// Ånd then reveal the content
.opacity( 1 );
// For `small` screens, move to the bottom edge instead
@media ( min-height: @breakpoint-small ) {
top: auto;
bottom: 0;
}
}
}
src/main/webapp/static/plugins/pickadate/3.5.6/themes-source/default.time.less
0 → 100644
View file @
a866cd37
/* ==========================================================================
$DEFAULT-TIME-PICKER
========================================================================== */
@import "_variables.less";
/**
* The frame the bounds the time picker.
*/
.picker--time .picker__frame {
// Adjust the min & max widths.
min-width: @time-min-width;
max-width: @time-max-width;
}
/**
* The picker box.
*/
.picker--time .picker__box {
// Keep the font-size small to show more in view.
font-size: 1em;
// Add a slight background color.
background: @bg-grey-light;
// Remove the side paddings.
padding: 0;
// For `medium` screens, move it away from the bottom edge of the screen.
@media ( min-height: @breakpoint-medium ) {
margin-bottom: 5em;
}
}
Prev
1
…
4
5
6
7
8
9
10
11
12
…
19
Next
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment