Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ Imports:
htmltools
URL: https://github.com/rstudio/shiny-incubator
BugReports: https://github.com/rstudio/shiny-incubator/issues
RoxygenNote: 5.0.1
4 changes: 3 additions & 1 deletion NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Generated by roxygen2 (4.1.1): do not edit by hand
# Generated by roxygen2: do not edit by hand

export(commandInput)
export(durationInput)
export(matrixInput)
export(periodInput)
import(shiny)
42 changes: 42 additions & 0 deletions R/durationInput.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#' Duration Input
#'
#' Creates a set of linked numeric inputs that represent hour, minute and seconds
#' Returns duration in seconds.
#'
#' @param inputId Input variable to assign the control's value to.
#' @param label Display label for the control, or \code{NULL} for no label.
#' @param value Initial value as number of seconds or a list of values for hour, minute, second
#' @param width CSS width property
#'
#' @export
durationInput <- function(inputId, label, value = list(hour = 0, minute = 0, second = 0), step = NULL, width="50px") {
if(!is.list(value)) {
value = list(
hour = floor(value / 3600),
minute = floor((value %% 3600) / 60),
second = (value %% 60) %% 60
)
}
style = ifelse(!is.null(width), paste0("width: ", shiny::validateCssUnit(width), ";"), '')

input = shiny::tags$div(
id = inputId,
class = "shiny-input-duration form-group shiny-input-container",
shiny::tags$label(label, `for` = inputId),
shiny::tags$br(),
shiny::tags$input(class = "hour", type = "number", value = value$hour, style = style),
shiny::tags$input(class = "minute", type = "number", value = value$minute, style = style),
shiny::tags$input(class = "second", type = "number", value = value$second, style = style,
step = if(!is.null(step)) step)
)

depend = htmltools::htmlDependency("shinyincubator_durationinput",
packageVersion("shinyIncubator"),
system.file("durationinput", package="shinyIncubator"),
script="duration-input-bindings.js"
)

shiny::tagList(
htmltools::attachDependencies(input, depend)
)
}
35 changes: 35 additions & 0 deletions R/periodInput.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#' Period Input
#'
#' Creates a set of linked numeric inputs that represent hour, minute and seconds.
#' Returns a list of hour, minute, and seconds
#'
#' @param inputId Input variable to assign the control's value to.
#' @param label Display label for the control, or \code{NULL} for no label.
#' @param value list of initial values.
#' @param width CSS width property
#'
#' @export
periodInput <- function(inputId, label, value = list(hour = 0, minute = 0, second = 0), step = NULL, width="50px") {
style = ifelse(!is.null(width), paste0("width: ", shiny::validateCssUnit(width), ";"), '')

input = shiny::tags$div(
id = inputId,
class = "shiny-input-period form-group shiny-input-container",
shiny::tags$label(label, `for` = inputId),
shiny::tags$br(),
shiny::tags$input(class = "hour", type = "number", value = value$hour, style = style),
shiny::tags$input(class = "minute", type = "number", value = value$minute, style = style),
shiny::tags$input(class = "second", type = "number", value = value$second, style = style,
step = if(!is.null(step)) step)
)

depend = htmltools::htmlDependency("shinyincubator_durationinput",
packageVersion("shinyIncubator"),
system.file("periodinput", package="shinyIncubator"),
script="period-input-bindings.js"
)

shiny::tagList(
htmltools::attachDependencies(input, depend)
)
}
59 changes: 59 additions & 0 deletions inst/durationinput/duration-input-bindings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// custom input binding for duration
var durationInputBinding = new Shiny.InputBinding();
$.extend(durationInputBinding, {
find: function(scope) {
return $(scope).find('.shiny-input-duration');
},

getId: function(el) {
return el.id;
},

getValue: function(el) {
return 3600 * parseInt($(el).find('.hour').val()) +
60 * parseInt($(el).find('.minute').val()) +
parseInt($(el).find('.second').val());
},

setValue: function(el, value) {
},

receiveMessage: function(el, data) {
if (data.hasOwnProperty('step')) {
el.step = data.step;
}

$(el).trigger('change');
},

subscribe: function(el, callback) {
$(el).on('change.durationInputBinding', function(event) {
var hour = $(el).find('.hour');
var min = $(el).find('.minute');
var sec = $(el).find('.second');
var hourVal = parseInt(hour.val());
var minVal = parseInt(min.val());
var secVal = parseInt(sec.val());
var totalSeconds = 3600 * hourVal + 60 * minVal + secVal;

if (hourVal < 0) {
hour.val(0);
}

if (minVal < 0 || minVal >= 60 || secVal < 0 || secVal >= 60) {
totalSeconds = Math.max(totalSeconds, 0)
sec.val(totalSeconds % 3600 % 60);
min.val(Math.floor(totalSeconds % 3600 / 60));
hour.val(Math.floor(totalSeconds / 3600));
}

callback();
});

},

unsubscribe: function(el) {
$(el).off('.durationInputBinding');
}
});
Shiny.inputBindings.register(durationInputBinding, 'shiny.durationInput');
5 changes: 5 additions & 0 deletions inst/examples/durationinput/server.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
shinyServer(function(input, output, session) {
output$durationtxt <- renderPrint({
input$durationtest
})
})
12 changes: 12 additions & 0 deletions inst/examples/durationinput/ui.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
library(shinyIncubator)
shinyUI(fluidPage(
fluidRow(
durationInput(
inputId = "durationtest",
label = "label",
step = 5,
value = 100
),
verbatimTextOutput("durationtxt")
)
))
5 changes: 5 additions & 0 deletions inst/examples/periodinput/server.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
shinyServer(function(input, output, session) {
output$periodtxt <- renderPrint({
input$periodtest
})
})
16 changes: 16 additions & 0 deletions inst/examples/periodinput/ui.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
library(shinyIncubator)
shinyUI(fluidPage(
fluidRow(
periodInput(
inputId = "periodtest",
label = "label",
step = 5,
value = list(
hour = 1,
minute = 10,
seconds = 55
)
),
verbatimTextOutput("periodtxt")
)
))
61 changes: 61 additions & 0 deletions inst/periodinput/period-input-bindings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// custom input binding for time periods
var periodInputBinding = new Shiny.InputBinding();
$.extend(periodInputBinding, {
find: function(scope) {
return $(scope).find('.shiny-input-period');
},

getId: function(el) {
return el.id;
},

getValue: function(el) {
return {
hour: parseInt($(el).find('.hour').val()),
minute: parseInt($(el).find('.minute').val()),
second: parseInt($(el).find('.second').val())
};
},

setValue: function(el, value) {
},

receiveMessage: function(el, data) {
if (data.hasOwnProperty('step')) {
el.step = data.step;
}

$(el).trigger('change');
},

subscribe: function(el, callback) {
$(el).on('change.periodInputBinding', function(event) {
var hour = $(el).find('.hour');
var min = $(el).find('.minute');
var sec = $(el).find('.second');
var hourVal = parseInt(hour.val());
var minVal = parseInt(min.val());
var secVal = parseInt(sec.val());
var totalSeconds = 3600 * hourVal + 60 * minVal + secVal;

if (hourVal < 0) {
hour.val(0);
}

if (minVal < 0 || minVal >= 60 || secVal < 0 || secVal >= 60) {
totalSeconds = Math.max(totalSeconds, 0)
sec.val(totalSeconds % 3600 % 60);
min.val(Math.floor(totalSeconds % 3600 / 60));
hour.val(Math.floor(totalSeconds / 3600));
}

callback();
});

},

unsubscribe: function(el) {
$(el).off('.periodInputBinding');
}
});
Shiny.inputBindings.register(periodInputBinding, 'shiny.periodInput');
4 changes: 2 additions & 2 deletions man/commandInput.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions man/durationInput.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/matrixInput.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions man/periodInput.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.