Bursaphelenchus
Bursaphelenchus

Reputation: 25

R Shiny Module does not update input value on different tabs

I have an app which works with tabpanels that use many of the same inputs, and must be rendered using renderUI to respond to user data. I've noticed my modulated inputs give priority to the first menu they're rendered in and disregard changes made in different panels

The following is a simplified working example of the basic issue

library(shiny)
addexButtons <- function(id, label = "ROCParam") {
    ns <- NS(id)
    uiOutput(ns("roccondicionals"), label = label)
    
}

numbmod <- function(input, output, session, ndata) {
    output$roccondicionals <- renderUI({
        tagList(numericInput('numb', 'Choose Num', value = 0,))
    })
}

ui <- fluidPage(navbarPage(
    'App',
    tabPanel(title = 'Menu 1',
             sidebarLayout(
                 sidebarPanel(addexButtons("counter1", "Adder")),
                 mainPanel(textOutput('sumtotal'))
             )),
    
    tabPanel(title = 'Menu 2',
             sidebarLayout(
                 sidebarPanel(addexButtons("counter2", "Multiplier"),),
                 mainPanel(textOutput('multiplytotal'))
             ))
    
))



server <- function(input, output) {
    callModule(numbmod, "counter1")
    callModule(numbmod, "counter2")
    
    output$sumtotal <-
        renderText(paste0('5 + ', input$numb, ' = ', input$numb + 5))
    
    output$multiplytotal <-
        renderText(paste0('5 x ', input$numb, ' = ', input$numb * 5))
}

shinyApp(ui = ui, server = server)

If you run this example you will see that, by changing to menu 2 the value retains the information modified in Menu 1 (which is intended) however if I choose to modify this same value in the same tab I can't and must return to Menu 1 to do so.

Is there a way to be able to modify the same rendered input on two different tabs where the last modification is the one retained?

Upvotes: 1

Views: 731

Answers (1)

PeterD
PeterD

Reputation: 1511

As @YBS has already mentioned you cannot define two inputs with the same id. I would use updateNumericInput to automatically update the inputs when of the inputs is changed (triggered).

library(shiny)
addexButtons <- function(id, label = "ROCParam") {
  ns <- NS(id)
  uiOutput(ns("roccondicionals"), label = label)    
  }

numbmod <- function(input, output, session, ndata, n) {
  output$roccondicionals <- renderUI({
    numericInput(paste0("numb",n), 'Choose Num', value = 0)
  })
}

ui <- fluidPage(navbarPage(
  'App', id = "App",
  tabPanel(title = 'Menu1',
           tab_id = "tab1",
           sidebarLayout(
             sidebarPanel(addexButtons("counter1", "Adder")),
             mainPanel(textOutput('sumtotal'))
           )),
  
  tabPanel(title = 'Menu2',
           tab_id = "tab2",
           sidebarLayout(
             sidebarPanel(addexButtons("counter2", "Multiplier"),),
             mainPanel(textOutput('multiplytotal'))
           ))
  
))



server <- function(input, output, session) {

  observeEvent(input$numb1, {
  updateNumericInput(session, "numb2", value = input$numb1)
    updateNavbarPage(session,"App", "Menu2")
  })
  
  observeEvent(input$numb2, {
    updateNumericInput(session, "numb1", value = input$numb2)
    updateNavbarPage(session,"App", "Menu1")

  })
    
  callModule(numbmod, "counter1",n = 1)
  callModule(numbmod, "counter2",n = 2)
  output$sumtotal <-
    renderText(paste0('5 + ', input$numb1, ' = ', input$numb1 + 5))
  
  output$multiplytotal <-
    renderText(paste0('5 x ', input$numb2, ' = ', input$numb2 * 5))
}

shinyApp(ui = ui, server = server)

Upvotes: 1

Related Questions