2020-08-30 12:18:16 +02:00
Grocy . Components . DateTimePicker2 = { } ;
2020-01-23 18:58:05 +01:00
Grocy . Components . DateTimePicker2 . GetInputElement = function ( )
{
return $ ( '.datetimepicker2' ) . find ( 'input' ) . not ( ".form-check-input" ) ;
}
Grocy . Components . DateTimePicker2 . GetValue = function ( )
{
return Grocy . Components . DateTimePicker2 . GetInputElement ( ) . val ( ) ;
}
2021-06-23 22:13:54 +02:00
Grocy . Components . DateTimePicker2 . SetValue = function ( value , inputElement = Grocy . Components . DateTimePicker2 . GetInputElement ( ) )
2020-01-23 18:58:05 +01:00
{
// "Click" the shortcut checkbox when the desired value is
// not the shortcut value and it is currently set
2021-06-23 22:13:54 +02:00
var shortcutValue = $ ( "#datetimepicker2-shortcut" ) . data ( "datetimepicker-shortcut-value" ) ;
2020-01-23 18:58:05 +01:00
if ( value != shortcutValue && $ ( "#datetimepicker2-shortcut" ) . is ( ":checked" ) )
{
$ ( "#datetimepicker2-shortcut" ) . click ( ) ;
}
2021-06-23 22:13:54 +02:00
inputElement . val ( value ) ;
inputElement . keyup ( ) ;
2020-01-23 18:58:05 +01:00
}
Grocy . Components . DateTimePicker2 . Clear = function ( )
{
2022-04-03 17:03:23 +02:00
Grocy . Components . DateTimePicker2 . Init ( true ) ;
2020-01-23 18:58:05 +01:00
Grocy . Components . DateTimePicker2 . GetInputElement ( ) . val ( "" ) ;
// "Click" the shortcut checkbox when the desired value is
// not the shortcut value and it is currently set
value = "" ;
var shortcutValue = $ ( "#datetimepicker2-shortcut" ) . data ( "datetimepicker2-shortcut-value" ) ;
if ( value != shortcutValue && $ ( "#datetimepicker2-shortcut" ) . is ( ":checked" ) )
{
$ ( "#datetimepicker2-shortcut" ) . click ( ) ;
}
2020-11-10 20:57:49 +01:00
$ ( '#datetimepicker2-timeago' ) . text ( '' ) ;
2020-01-23 18:58:05 +01:00
}
Grocy . Components . DateTimePicker2 . ChangeFormat = function ( format )
{
$ ( ".datetimepicker2" ) . datetimepicker ( "destroy" ) ;
Grocy . Components . DateTimePicker2 . GetInputElement ( ) . data ( "format" , format ) ;
Grocy . Components . DateTimePicker2 . Init ( ) ;
if ( format == "YYYY-MM-DD" )
{
2022-04-03 17:03:23 +02:00
Grocy . Components . DateTimePicker2 . GetInputElement ( ) . addClass ( "date-only-datetimepicker2" ) ;
2020-01-23 18:58:05 +01:00
}
else
{
2022-04-03 17:03:23 +02:00
Grocy . Components . DateTimePicker2 . GetInputElement ( ) . removeClass ( "date-only-datetimepicker2" ) ;
2020-01-23 18:58:05 +01:00
}
}
var startDate = null ;
if ( Grocy . Components . DateTimePicker2 . GetInputElement ( ) . data ( 'init-with-now' ) === true )
{
startDate = moment ( ) . format ( Grocy . Components . DateTimePicker2 . GetInputElement ( ) . data ( 'format' ) ) ;
}
if ( Grocy . Components . DateTimePicker2 . GetInputElement ( ) . data ( 'init-value' ) . length > 0 )
{
startDate = moment ( Grocy . Components . DateTimePicker2 . GetInputElement ( ) . data ( 'init-value' ) ) . format ( Grocy . Components . DateTimePicker2 . GetInputElement ( ) . data ( 'format' ) ) ;
}
var limitDate = moment ( '2999-12-31 23:59:59' ) ;
if ( Grocy . Components . DateTimePicker2 . GetInputElement ( ) . data ( 'limit-end-to-now' ) === true )
{
limitDate = moment ( ) ;
}
2022-04-03 17:03:23 +02:00
Grocy . Components . DateTimePicker2 . Init = function ( reInit = false )
2020-01-23 18:58:05 +01:00
{
2022-04-03 17:03:23 +02:00
if ( reInit )
{
$ ( ".datetimepicker2" ) . datetimepicker ( "destroy" ) ;
}
2021-06-23 22:13:54 +02:00
$ ( ".datetimepicker2" ) . each ( function ( )
{
$ ( this ) . datetimepicker (
{
format : $ ( this ) . find ( "input" ) . data ( 'format' ) ,
buttons : {
2022-04-03 22:32:25 +02:00
showToday : Grocy . Components . DateTimePicker2 . GetInputElement ( ) . data ( 'limit-end-to-now' ) !== true ,
2021-06-23 22:13:54 +02:00
showClose : true
} ,
calendarWeeks : Grocy . CalendarShowWeekNumbers ,
maxDate : limitDate ,
locale : moment . locale ( ) ,
defaultDate : startDate ,
useCurrent : false ,
icons : {
2025-01-08 20:50:35 +01:00
time : 'fa-solid fa-clock' ,
date : 'fa-solid fa-calendar' ,
2022-04-04 20:10:29 +02:00
up : 'fa-solid fa-arrow-up' ,
down : 'fa-solid fa-arrow-down' ,
previous : 'fa-solid fa-chevron-left' ,
next : 'fa-solid fa-chevron-right' ,
today : 'fa-solid fa-calendar-day' ,
2025-01-08 20:50:35 +01:00
clear : 'fa-solid fa-trash-can' ,
2022-04-04 20:10:29 +02:00
close : 'fa-solid fa-check'
2021-06-23 22:13:54 +02:00
} ,
sideBySide : true ,
keyBinds : {
up : function ( widget ) { } ,
down : function ( widget ) { } ,
'control up' : function ( widget ) { } ,
'control down' : function ( widget ) { } ,
left : function ( widget ) { } ,
right : function ( widget ) { } ,
pageUp : function ( widget ) { } ,
pageDown : function ( widget ) { } ,
enter : function ( widget ) { } ,
escape : function ( widget ) { } ,
'control space' : function ( widget ) { } ,
t : function ( widget ) { } ,
'delete' : function ( widget ) { }
}
} ) ;
} ) ;
2020-01-23 18:58:05 +01:00
}
Grocy . Components . DateTimePicker2 . Init ( ) ;
Grocy . Components . DateTimePicker2 . GetInputElement ( ) . on ( 'keyup' , function ( e )
{
2020-01-27 19:00:49 +01:00
$ ( '.datetimepicker2' ) . datetimepicker ( 'hide' ) ;
2020-01-23 18:58:05 +01:00
2021-06-23 22:13:54 +02:00
var inputElement = $ ( e . currentTarget )
var value = inputElement . val ( ) ;
2022-02-06 18:13:25 +01:00
var lastCharacter = value . slice ( - 1 ) . toLowerCase ( ) ;
2020-01-23 18:58:05 +01:00
var now = new Date ( ) ;
var centuryStart = Number . parseInt ( now . getFullYear ( ) . toString ( ) . substring ( 0 , 2 ) + '00' ) ;
var centuryEnd = Number . parseInt ( now . getFullYear ( ) . toString ( ) . substring ( 0 , 2 ) + '99' ) ;
2021-06-23 22:13:54 +02:00
var format = inputElement . data ( 'format' ) ;
var nextInputElement = $ ( inputElement . data ( 'next-input-selector' ) ) ;
2020-08-29 16:41:27 +02:00
2025-09-14 10:32:26 +02:00
if ( ! nextInputElement . is ( "input" ) )
{
nextInputElement = nextInputElement . find ( "input" ) ;
}
2022-02-06 18:13:25 +01:00
// If input is empty and any arrow key is pressed, set date to today
2020-01-23 18:58:05 +01:00
if ( value . length === 0 && ( e . keyCode === 38 || e . keyCode === 40 || e . keyCode === 37 || e . keyCode === 39 ) )
{
2021-06-23 22:13:54 +02:00
Grocy . Components . DateTimePicker2 . SetValue ( moment ( new Date ( ) , format , true ) . format ( format ) , inputElement ) ;
2020-01-23 18:58:05 +01:00
nextInputElement . focus ( ) ;
}
2022-02-06 18:13:25 +01:00
else if ( value === 'x' || value === 'X' ) // Shorthand for never overdue
2020-01-23 18:58:05 +01:00
{
2021-06-23 22:13:54 +02:00
Grocy . Components . DateTimePicker2 . SetValue ( moment ( '2999-12-31 23:59:59' ) . format ( format ) , inputElement ) ;
2020-01-23 18:58:05 +01:00
nextInputElement . focus ( ) ;
}
2022-02-06 18:13:25 +01:00
else if ( value . length === 4 && ! ( Number . parseInt ( value ) > centuryStart && Number . parseInt ( value ) < centuryEnd ) ) // Shorthand for MMDD
2020-01-23 18:58:05 +01:00
{
var date = moment ( ( new Date ( ) ) . getFullYear ( ) . toString ( ) + value ) ;
if ( date . isBefore ( moment ( ) ) )
{
date . add ( 1 , "year" ) ;
}
2021-06-23 22:13:54 +02:00
Grocy . Components . DateTimePicker2 . SetValue ( date . format ( format ) , inputElement ) ;
2020-01-23 18:58:05 +01:00
nextInputElement . focus ( ) ;
}
2022-02-06 18:13:25 +01:00
else if ( value . length === 8 && $ . isNumeric ( value ) ) // Shorthand for YYYYMMDD
2020-01-23 18:58:05 +01:00
{
2021-06-23 22:13:54 +02:00
Grocy . Components . DateTimePicker2 . SetValue ( value . replace ( /(\d{4})(\d{2})(\d{2})/ , '$1-$2-$3' ) , inputElement ) ;
2020-01-23 18:58:05 +01:00
nextInputElement . focus ( ) ;
}
2022-02-06 18:13:25 +01:00
else if ( value . length === 7 && $ . isNumeric ( value . substring ( 0 , 6 ) ) && ( value . substring ( 6 , 7 ) . toLowerCase ( ) === "e" || value . substring ( 6 , 7 ) . toLowerCase ( ) === "+" ) ) // Shorthand for YYYYMM[e/+]
2020-01-23 18:58:05 +01:00
{
var date = moment ( value . substring ( 0 , 4 ) + "-" + value . substring ( 4 , 6 ) + "-01" ) . endOf ( "month" ) ;
2021-06-23 22:13:54 +02:00
Grocy . Components . DateTimePicker2 . SetValue ( date . format ( format ) , inputElement ) ;
2020-01-23 18:58:05 +01:00
nextInputElement . focus ( ) ;
}
2022-02-06 18:13:25 +01:00
else if ( ( value . startsWith ( "+" ) || value . startsWith ( "-" ) ) && ( lastCharacter == "d" || lastCharacter == "m" || lastCharacter == "y" ) ) // Shorthand for [+/-]n[d/m/y]
{
2023-02-06 20:22:10 +01:00
var n = Number . parseInt ( value . substring ( 1 , value . length - 1 ) ) ;
2022-02-06 18:13:25 +01:00
if ( value . startsWith ( "-" ) )
{
n = n * - 1 ;
}
if ( lastCharacter == "d" )
{
Grocy . Components . DateTimePicker2 . SetValue ( moment ( ) . add ( n , "days" ) . format ( format ) ) ;
}
else if ( lastCharacter == "m" )
{
Grocy . Components . DateTimePicker2 . SetValue ( moment ( ) . add ( n , "months" ) . format ( format ) ) ;
}
else if ( lastCharacter == "y" )
{
Grocy . Components . DateTimePicker2 . SetValue ( moment ( ) . add ( n , "years" ) . format ( format ) ) ;
}
}
2020-01-23 18:58:05 +01:00
else
{
var dateObj = moment ( value , format , true ) ;
if ( dateObj . isValid ( ) )
{
if ( e . shiftKey )
{
// WITH shift modifier key
if ( e . keyCode === 38 ) // Up
{
2021-06-23 22:13:54 +02:00
Grocy . Components . DateTimePicker2 . SetValue ( dateObj . add ( - 1 , 'months' ) . format ( format ) , inputElement ) ;
2020-01-23 18:58:05 +01:00
}
else if ( e . keyCode === 40 ) // Down
{
2021-06-23 22:13:54 +02:00
Grocy . Components . DateTimePicker2 . SetValue ( dateObj . add ( 1 , 'months' ) . format ( format ) , inputElement ) ;
2020-01-23 18:58:05 +01:00
}
else if ( e . keyCode === 37 ) // Left
{
2021-06-23 22:13:54 +02:00
Grocy . Components . DateTimePicker2 . SetValue ( dateObj . add ( - 1 , 'years' ) . format ( format ) , inputElement ) ;
2020-01-23 18:58:05 +01:00
}
else if ( e . keyCode === 39 ) // Right
{
2021-06-23 22:13:54 +02:00
Grocy . Components . DateTimePicker2 . SetValue ( dateObj . add ( 1 , 'years' ) . format ( format ) , inputElement ) ;
2020-01-23 18:58:05 +01:00
}
}
else
{
// WITHOUT shift modifier key
if ( e . keyCode === 38 ) // Up
{
2021-06-23 22:13:54 +02:00
Grocy . Components . DateTimePicker2 . SetValue ( dateObj . add ( - 1 , 'days' ) . format ( format ) , inputElement ) ;
2020-01-23 18:58:05 +01:00
}
else if ( e . keyCode === 40 ) // Down
{
2021-06-23 22:13:54 +02:00
Grocy . Components . DateTimePicker2 . SetValue ( dateObj . add ( 1 , 'days' ) . format ( format ) , inputElement ) ;
2020-01-23 18:58:05 +01:00
}
else if ( e . keyCode === 37 ) // Left
{
2021-06-23 22:13:54 +02:00
Grocy . Components . DateTimePicker2 . SetValue ( dateObj . add ( - 1 , 'weeks' ) . format ( format ) , inputElement ) ;
2020-01-23 18:58:05 +01:00
}
else if ( e . keyCode === 39 ) // Right
{
2021-06-23 22:13:54 +02:00
Grocy . Components . DateTimePicker2 . SetValue ( dateObj . add ( 1 , 'weeks' ) . format ( format ) , inputElement ) ;
2020-01-23 18:58:05 +01:00
}
}
}
}
2022-03-07 17:57:14 +01:00
$ ( '#datetimepicker2-timeago' ) . attr ( "datetime" , Grocy . Components . DateTimePicker2 . GetValue ( ) ) ;
RefreshContextualTimeago ( ".datetimepicker2-wrapper" ) ;
2020-01-23 18:58:05 +01:00
//Custom validation
value = Grocy . Components . DateTimePicker2 . GetValue ( ) ;
dateObj = moment ( value , format , true ) ;
var element = Grocy . Components . DateTimePicker2 . GetInputElement ( ) [ 0 ] ;
if ( ! dateObj . isValid ( ) )
{
if ( $ ( element ) . hasAttr ( "required" ) )
{
element . setCustomValidity ( "error" ) ;
2020-08-29 16:41:27 +02:00
}
2020-01-23 18:58:05 +01:00
}
else
{
if ( Grocy . Components . DateTimePicker2 . GetInputElement ( ) . data ( 'limit-end-to-now' ) === true && dateObj . isAfter ( moment ( ) ) )
{
element . setCustomValidity ( "error" ) ;
}
else if ( Grocy . Components . DateTimePicker2 . GetInputElement ( ) . data ( 'limit-start-to-now' ) === true && dateObj . isBefore ( moment ( ) ) )
{
element . setCustomValidity ( "error" ) ;
}
else
{
element . setCustomValidity ( "" ) ;
}
var earlierThanLimit = Grocy . Components . DateTimePicker2 . GetInputElement ( ) . data ( "earlier-than-limit" ) ;
2023-02-06 20:22:10 +01:00
if ( earlierThanLimit )
2020-01-23 18:58:05 +01:00
{
if ( moment ( value ) . isBefore ( moment ( earlierThanLimit ) ) )
{
$ ( "#datetimepicker-earlier-than-info" ) . removeClass ( "d-none" ) ;
}
else
{
$ ( "#datetimepicker-earlier-than-info" ) . addClass ( "d-none" ) ;
}
}
}
// "Click" the shortcut checkbox when the shortcut value was
// entered manually and it is currently not set
var shortcutValue = $ ( "#datetimepicker2-shortcut" ) . data ( "datetimepicker2-shortcut-value" ) ;
if ( value == shortcutValue && ! $ ( "#datetimepicker2-shortcut" ) . is ( ":checked" ) )
{
$ ( "#datetimepicker2-shortcut" ) . click ( ) ;
}
} ) ;
Grocy . Components . DateTimePicker2 . GetInputElement ( ) . on ( 'input' , function ( e )
{
2020-11-10 20:57:49 +01:00
$ ( '#datetimepicker2-timeago' ) . attr ( "datetime" , Grocy . Components . DateTimePicker2 . GetValue ( ) ) ;
2021-06-24 07:46:32 +02:00
RefreshContextualTimeago ( ".datetimepicker2-wrapper" ) ;
2020-01-23 18:58:05 +01:00
} ) ;
2020-01-27 19:00:49 +01:00
$ ( '.datetimepicker2' ) . on ( 'update.datetimepicker' , function ( e )
2020-01-23 18:58:05 +01:00
{
Grocy . Components . DateTimePicker2 . GetInputElement ( ) . trigger ( 'input' ) ;
} ) ;
2020-01-27 19:00:49 +01:00
$ ( '.datetimepicker2' ) . on ( 'hide.datetimepicker' , function ( e )
2020-01-23 18:58:05 +01:00
{
Grocy . Components . DateTimePicker2 . GetInputElement ( ) . trigger ( 'input' ) ;
Grocy . Components . DateTimePicker2 . GetInputElement ( ) . trigger ( 'change' ) ;
Grocy . Components . DateTimePicker2 . GetInputElement ( ) . trigger ( 'keypress' ) ;
2020-04-12 18:41:23 +02:00
Grocy . Components . DateTimePicker2 . GetInputElement ( ) . trigger ( 'keyup' ) ;
2020-01-23 18:58:05 +01:00
} ) ;
$ ( "#datetimepicker2-shortcut" ) . on ( "click" , function ( )
{
if ( this . checked )
{
var value = $ ( "#datetimepicker2-shortcut" ) . data ( "datetimepicker2-shortcut-value" ) ;
Grocy . Components . DateTimePicker2 . SetValue ( value ) ;
Grocy . Components . DateTimePicker2 . GetInputElement ( ) . attr ( "readonly" , "" ) ;
$ ( Grocy . Components . DateTimePicker2 . GetInputElement ( ) . data ( 'next-input-selector' ) ) . focus ( ) ;
}
else
{
Grocy . Components . DateTimePicker2 . SetValue ( "" ) ;
Grocy . Components . DateTimePicker2 . GetInputElement ( ) . removeAttr ( "readonly" ) ;
Grocy . Components . DateTimePicker2 . GetInputElement ( ) . focus ( ) ;
}
Grocy . Components . DateTimePicker2 . GetInputElement ( ) . trigger ( 'input' ) ;
Grocy . Components . DateTimePicker2 . GetInputElement ( ) . trigger ( 'change' ) ;
Grocy . Components . DateTimePicker2 . GetInputElement ( ) . trigger ( 'keypress' ) ;
} ) ;