shinyWidgets icon indicating copy to clipboard operation
shinyWidgets copied to clipboard

VirtualSelectInput not registering input

Open nedhermann opened this issue 3 years ago • 1 comments

I added some javascript to an application to toggle between elements. These elements contain their own VirtualSelectInputs. Whenever I try to toggle to the non-default element (or "Second Option" in the code below), the input doesn't seem to register when I select between the options.

library(shiny)
library(shinyWidgets)

ui <- div(
  style = "display: flex; width: 50%;",
  
  # js to toggle between cards
  tags$script("
  
      $(function () {
          $('#toggle_options').change(function () {
              const opt = $(this).val();
      
              if (opt === 'First') {
                  $('#second-option').hide();
                  $('#first-option').show();
              } else if (opt === 'Second') {
                  $('#first-option').hide();
                  $('#second-option').show();
              }
      
          });
      });
              "),
  
  # to toggle between option cards
  div(
    style = "width: 50%;",
    virtualSelectInput(
      inputId = "toggle_options",
      label = "Toggle Options",
      choices = c("First", "Second"),
      selected = "First")
  ),
  
  # option cards
  div(
    style = "width: 50%;",
    
    # first option card (default)
    div(
      id = "first-option",
      virtualSelectInput(
        inputId = "first_vs",
        label = "First Options",
        choices = 1:10,
        autoSelectFirstOption = FALSE
      ),
      verbatimTextOutput("first_print")
    ),
    
    # second option card
    div(
      id = "second-option",
      virtualSelectInput(
        inputId = "second_vs",
        label = "Second Options",
        choices = 1:10,
        autoSelectFirstOption = FALSE
      ),
      verbatimTextOutput("second_print")
    )
  )
)

server <- function(input, output, session){
  
  output$first_print <- renderPrint(input$first_vs)
  output$second_print <- renderPrint(input$second_vs)
  
}

shinyApp(ui = ui, server = server)

032353935d7258f96d02cee57f70d978

nedhermann avatar Sep 25 '22 12:09 nedhermann

Changing the javascript to this seems to make it work. Would like to know why the original method didn't work though.


// or some class etc
      $(function () {
          $('#toggle_options').change(function () {
              const opt = $(this).val();
      
              if (opt === 'First') {
                  $('#second-option').css({'visibility' : 'hidden', 'height' : '0px', 'width' : '0px'});
                  $('#first-option').css({'visibility' : '', 'height' : '', 'width' : ''});
              } else if (opt === 'Second') {
                  $('#first-option').css({'visibility' : 'hidden', 'height' : '0px', 'width' : '0px'});
                  $('#second-option').css({'visibility' : '', 'height' : '', 'width' : ''});
              }
      
          });
      });

ghost avatar Sep 25 '22 13:09 ghost

Hello, The input is registered, the issue is with verbatimTextOutput, output in shiny are not calculated unless visible on the page. And with you custom javascript shiny doesn't know when the output is visible. You can check if an element is hidden or not with session$clientData$output_<outputId>_hidden.

Here's a demo :

library(shiny)
library(shinyWidgets)

ui <- div(
  style = "display: flex; width: 50%;",
  
  # js to toggle between cards
  tags$script("
  
      $(function () {
          $('#toggle_options').change(function () {
              const opt = $(this).val();
      
              if (opt === 'First') {
                  $('#second-option').hide();
                  $('#first-option').show();
              } else if (opt === 'Second') {
                  $('#first-option').hide();
                  $('#second-option').show();
              }
      
          });
      });
              "),
  
  # to toggle between option cards
  div(
    style = "width: 50%;",
    virtualSelectInput(
      inputId = "toggle_options",
      label = "Toggle Options",
      choices = c("First", "Second"),
      selected = "First")
  ),
  
  # option cards
  div(
    style = "width: 50%;",
    
    # first option card (default)
    div(
      id = "first-option",
      virtualSelectInput(
        inputId = "first_vs",
        label = "First Options",
        choices = 1:10,
        autoSelectFirstOption = FALSE
      ),
      verbatimTextOutput("first_print")
    ),
    
    # second option card
    div(
      id = "second-option",
      virtualSelectInput(
        inputId = "second_vs",
        label = "Second Options",
        choices = (1:10)*10,
        autoSelectFirstOption = FALSE
      ),
      verbatimTextOutput("second_print")
    )
  )
)

ui <- tagList(
  ui,
  tags$p("Is second verbatim output hidden?"),
  verbatimTextOutput("is_hidden"),
  tags$button("Trigger shown", onclick = "$('#second_print').trigger('shown');")
)

server <- function(input, output, session){
  
  output$first_print <- renderPrint(input$first_vs)
  output$second_print <- renderPrint(input$second_vs)
  
  output$is_hidden <- renderPrint(session$clientData$output_second_print_hidden)
}

shinyApp(ui = ui, server = server)

Victor

pvictor avatar Nov 04 '22 08:11 pvictor