15
15
# ' @param seconds Show input for seconds. Defaults to TRUE.
16
16
# ' @param minute.steps Round time to multiples of \code{minute.steps} (should be a whole number).
17
17
# ' If not NULL sets \code{seconds} to \code{FALSE}.
18
+ # ' @param use.civilian Use civilian time (12-hour format) instead of 24-hour format.
18
19
# '
19
20
# ' @returns Returns a \code{POSIXlt} object, which can be converted to
20
21
# ' a \code{POSIXct} object with \code{as.POSIXct} for more efficient storage.
46
47
# ' timeInput("time6", "Time:", seconds = FALSE),
47
48
# '
48
49
# ' # Use multiples of 5 minutes
49
- # ' timeInput("time7", "Time:", minute.steps = 5)
50
+ # ' timeInput("time7", "Time:", minute.steps = 5),
51
+ # '
52
+ # ' # Use civilian (non-military time)
53
+ # ' timeInput("time8", "Time:", use.civilian = TRUE)
50
54
# ' )
51
55
# '
52
56
# ' shinyApp(ui, server = function(input, output) { })
53
57
# ' }
54
58
# '
55
59
# ' @importFrom htmltools tagList singleton tags
56
60
# ' @export
57
- timeInput <- function (inputId , label , value = NULL , seconds = TRUE , minute.steps = NULL ) {
61
+ timeInput <- function (inputId , label , value = NULL , seconds = TRUE ,
62
+ minute.steps = NULL , use.civilian = FALSE , width = NULL ) {
58
63
if (is.null(value )) value <- getDefaultTime()
59
64
if (is.character(value )) value <- strptime(value , format = " %T" )
60
65
if (! is.null(minute.steps )) {
@@ -63,21 +68,75 @@ timeInput <- function(inputId, label, value = NULL, seconds = TRUE, minute.steps
63
68
value <- roundTime(value , minute.steps )
64
69
}
65
70
value_list <- dateToTimeList(value )
66
- style <- " width: 8ch"
71
+
72
+ div_style <- htmltools :: css(width = shiny :: validateCssUnit(width ))
73
+ el_width <- " 65px"
74
+ el_style <- htmltools :: css(`min-width` = shiny :: validateCssUnit(el_width ),
75
+ flex = " 1 1 auto" )
76
+
67
77
input.class <- " form-control"
78
+ # Set hour values
79
+ if (use.civilian ){
80
+ min_hour <- " 1"
81
+ max_hour <- " 12"
82
+ value_hour <- as.numeric(value_list $ hour )
83
+ if (value_hour == 0 ){
84
+ value_hour <- 12
85
+ } else if (value_hour > 12 ){
86
+ value_hour <- value_hour - 12
87
+ }
88
+ } else {
89
+ min_hour <- " 0"
90
+ max_hour <- " 23"
91
+ value_hour = as.character(value_list $ hour )
92
+ }
93
+ # Create UI input
68
94
tagList(
69
95
singleton(tags $ head(
70
96
tags $ script(src = " shinyTime/input_binding_time.js" )
71
97
)),
72
- tags $ div(id = inputId , class = " my-shiny-time-input form-group shiny input-container" ,
98
+ tags $ div(
99
+ id = inputId ,
100
+ class = " my-shiny-time-input form-group shiny-input-container" ,
101
+ style = div_style ,
73
102
shinyInputLabel(inputId , label , control = TRUE ),
74
- tags $ div(class = " input-group" ,
75
- tags $ input(type = " number" , min = " 0" , max = " 23" , step = " 1" , value = value_list $ hour ,
76
- style = style , class = paste(c(input.class , ' shinytime-hours' ), collapse = " " )),
77
- tags $ input(type = " number" , min = " 0" , max = " 59" , step = minute.steps , value = value_list $ min ,
78
- style = style , class = paste(c(input.class , ' shinytime-mins' ), collapse = " " )),
79
- if (seconds ) tags $ input(type = " number" , min = " 0" , max = " 59" , step = " 1" , value = value_list $ sec ,
80
- style = style , class = paste(c(input.class , ' shinytime-secs' ), collapse = " " )) else NULL
103
+ tags $ div(
104
+ class = " input-group" ,
105
+ style = htmltools :: css(display = " flex" ,
106
+ `flex-direction` = " row" ,
107
+ `flex-wrap` = " nowrap" ),
108
+ tags $ input(
109
+ type = " number" , min = min_hour , max = max_hour , step = " 1" ,
110
+ value = value_hour , style = el_style ,
111
+ class = paste(c(input.class , ' shinytime-hours' ), collapse = " " )
112
+ ),
113
+ tags $ input(
114
+ type = " number" , min = " 0" , max = " 59" , step = minute.steps ,
115
+ value = value_list $ min , style = el_style ,
116
+ class = paste(c(input.class , ' shinytime-mins' ), collapse = " " )
117
+ ),
118
+ if (seconds ){
119
+ tags $ input(
120
+ type = " number" , min = " 0" , max = " 59" , step = " 1" ,
121
+ value = value_list $ sec , style = el_style ,
122
+ class = paste(c(input.class , ' shinytime-secs' ), collapse = " " )
123
+ )
124
+ } else NULL ,
125
+ if (use.civilian ){
126
+ tags $ select(
127
+ tags $ option(
128
+ value = " AM" , " AM" ,
129
+ selected = if (value_list $ civilian == " AM" ) TRUE else NULL
130
+ ),
131
+ tags $ option(
132
+ value = " PM" , " PM" ,
133
+ selected = if (value_list $ civilian == " PM" ) TRUE else NULL
134
+ ),
135
+ style = htmltools :: css(`min-width` = shiny :: validateCssUnit(" 70px" ),
136
+ flex = " 1 1 auto" ),
137
+ class = paste(c(input.class , ' shinytime-civilian' ), collapse = " " )
138
+ )
139
+ } else NULL
81
140
)
82
141
)
83
142
)
@@ -113,7 +172,7 @@ timeInput <- function(inputId, label, value = NULL, seconds = TRUE, minute.steps
113
172
# ' @export
114
173
updateTimeInput <- function (session , inputId , label = NULL , value = NULL ) {
115
174
value <- dateToTimeList(value )
116
- message <- dropNulls(list (label = label , value = value ))
175
+ message <- dropNulls(list (label = label , value = value ))
117
176
session $ sendInputMessage(inputId , message )
118
177
}
119
178
@@ -127,3 +186,12 @@ updateTimeInput <- function(session, inputId, label = NULL, value = NULL) {
127
186
shinyTimeExample <- function () {
128
187
runApp(system.file(' example' , package = ' shinyTime' , mustWork = T ), display.mode = ' showcase' )
129
188
}
189
+
190
+ # ' Show the shinyTime debug app
191
+ # '
192
+ # ' App to test the input with a variety of options
193
+ # '
194
+ # ' @importFrom shiny runApp
195
+ shinyTimeDebug <- function () {
196
+ runApp(system.file(' debug' , package = ' shinyTime' , mustWork = T ), display.mode = ' normal' )
197
+ }
0 commit comments