diff --git a/NEWS.md b/NEWS.md index 5ddd7206..bb35245d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,9 @@ # teal.modules.hermes 0.1.5.9002 +### Miscellaneous +* Added placeholders for `assaySpec`, `adtteSpec` and `geneSpec` inputs when no option is selected. +* Disabled the select input for `assaySpec` and `adtteSpec` when there are no options available. + # teal.modules.hermes 0.1.5 ### Bug Fixes diff --git a/R/adtteSpec.R b/R/adtteSpec.R index 9e3d33c5..5feca2a3 100644 --- a/R/adtteSpec.R +++ b/R/adtteSpec.R @@ -107,10 +107,14 @@ adtteSpecInput <- function(inputId, # nolint ns <- NS(inputId) - selectInput( - inputId = ns("paramcd"), - label = label_paramcd, - choices = "" + tagList( + selectizeInput( + inputId = ns("paramcd"), + label = label_paramcd, + choices = "", + options = list(placeholder = "- Nothing selected -") + ), + include_js_files("dropdown.js") ) } @@ -295,6 +299,12 @@ adtteSpecServer <- function(id, # nolint sort(unique(adtte_joined[[adtte_vars$paramcd]])) # Order should not matter. }) + # Start by disabling selection, will be overriden if there are valid choices. + session$sendCustomMessage( + "toggle_dropdown", + list(input_id = session$ns("paramcd"), disabled = TRUE) + ) + # Once available endpoints change, we update choices (and also the selection # if nothing was selected earlier) and warn the user if previous endpoint is # not available. @@ -310,11 +320,15 @@ adtteSpecServer <- function(id, # nolint )) "" } - updateSelectInput( - session, + updateSelectizeInput( "paramcd", choices = paramcd_choices, - selected = new_selected + selected = new_selected, + session = session + ) + session$sendCustomMessage( + "toggle_dropdown", + list(input_id = session$ns("paramcd"), disabled = (length(paramcd_choices) == 0)) ) }) diff --git a/R/assaySpec.R b/R/assaySpec.R index 55d4c7a3..9c72ab7d 100644 --- a/R/assaySpec.R +++ b/R/assaySpec.R @@ -16,10 +16,16 @@ assaySpecInput <- function(inputId, # nolint assert_string(label_assays, min.chars = 1L) ns <- NS(inputId) - selectInput( - inputId = ns("name"), - label = label_assays, - choices = "" + tagList( + selectizeInput( + inputId = ns("name"), + label = label_assays, + choices = character(0), + options = list( + placeholder = "- Nothing selected -" + ) + ), + include_js_files("dropdown.js") ) } @@ -119,15 +125,18 @@ assaySpecServer <- function(id, # nolint hermes::h_short_list(removed_assays), "as per app specifications" )) } + if (length(remaining_assays) == 0) { + remaining_assays <- character(0) + } remaining_assays }) observeEvent(choices(), { choices <- choices() - updateSelectInput( - session, - "name", - choices = choices + updateSelectizeInput(session, "name", choices = choices) + session$sendCustomMessage( + "toggle_dropdown", + list(input_id = session$ns("name"), disabled = (length(choices) == 0)) ) }) diff --git a/R/geneSpec.R b/R/geneSpec.R index deef6e21..f6ea0b9f 100644 --- a/R/geneSpec.R +++ b/R/geneSpec.R @@ -107,6 +107,7 @@ geneSpecInput <- function(inputId, # nolint multiple = TRUE, selected = 1, options = list( + placeholder = "- Nothing selected -", render = I("{ option: function(item, escape) { return '
' + item.label + '
' + diff --git a/inst/js/dropdown.js b/inst/js/dropdown.js new file mode 100644 index 00000000..1937f1a4 --- /dev/null +++ b/inst/js/dropdown.js @@ -0,0 +1,26 @@ +// Toggle enable/disable of a dropdown +// +// This can be done by `{shinyjs::enable/disable}` R package if that package is +// added to the dependecies. +// Parameters +// `message` should have `input_id` string and `disabled` logical properties. +Shiny.addCustomMessageHandler('toggle_dropdown', function(message) { + const input_id = message.input_id; + const disabled = message.disabled; + + let el = document.getElementById(input_id) + + if (el.selectize !== undefined) { + el = el.selectize; + if (disabled) { + el.lock(); + el.disable(); + } else { + el.unlock(); + el.enable(); + } + } else { + // Fallback in case selectize is not enabled + el.disabled = disabled ? 'disabled' : ''; + } +}); diff --git a/tests/testthat/_snaps/assaySpec.md b/tests/testthat/_snaps/assaySpec.md index ddce3e42..d1dfc3af 100644 --- a/tests/testthat/_snaps/assaySpec.md +++ b/tests/testthat/_snaps/assaySpec.md @@ -6,8 +6,34 @@
- - + +
+ diff --git a/tests/testthat/test-adtteSpec.R b/tests/testthat/test-adtteSpec.R index d70a2571..7a24c219 100644 --- a/tests/testthat/test-adtteSpec.R +++ b/tests/testthat/test-adtteSpec.R @@ -175,7 +175,15 @@ test_that("adtteSpecInput creates expected HTML", { label_paramcd = "Select right PARAMCD" )) - expect_tag(result) + expect_class(result, "shiny.tag.list") + expect_length(result, 2) + + # First element is a div tag + expect_tag(result[[1]]) + + # Second element is the contents of a single js file + expect_length(result[[2]], 1) + expect_tag(result[[2]][[1]]) }) # nolint start