简体   繁体   中英

Same inputs on different tabPanels in navbarPage, Shiny R

I have a shiny app with ui that consist of a navbarPage with different tabPanels. Inside those I would like to have the same buttons for every tab. So every tab has the same button that links to same inputs.

eg

ui <- navbarPage( theme = shinytheme("sandstone"),
              tabPanel(title="number one",
                       fluidRow(column(2, wellPanel(

                         sliderInput("one", "slider_one", value =0, min = 0, max=500, step=10),
                         sliderInput("two", "slider_two", value =250, min = 0, max=1000, step=10),
                       )),
                       column(8,
                              dataTableOutput('totals')
                              ))),

                tabPanel(title="number two" ,
                         fluidRow(column(2, wellPanel(
                           sliderInput("one", "slider_one", value =0, min = 0, max=500, step=10),
                           sliderInput("two", "slider_two", value =250, min = 0, max=1000, step=10)
                           )),
                           column(8,
                                         dataTableOutput('totals_2')),
                       )))

In the server part of the code I have some reactive values that are dependent on the inputs inserted and some outputs (with different names) that are dependent on the reactive values.

Is it possible to write the code for reactive values only one time, eg only for the inputs on the first tabPanel (since they are the same for both panels), or should I define the reactive values for every tabPanel by itself (in that case, I should also rename the inputs, so that they have different names on every tabPanel) ?

eg

server <- function(input, output) {

react <- reactive({some_function(input$one, input$two)})

output$totals<-renderDataTable({react()
  })

output$totals_2<-renderDataTable({react()
  })

}

So instead of that it should write the following.

ui <- navbarPage( theme = shinytheme("sandstone"),
              tabPanel(title="number one",
                       fluidRow(column(2, wellPanel(

                         sliderInput("one", "slider_one", value =0, min = 0, max=500, step=10),
                         sliderInput("two", "slider_two", value =250, min = 0, max=1000, step=10),
                       )),
                       column(8,
                              dataTableOutput('totals')
                              ))),

                tabPanel(title="number two" ,
                         fluidRow(column(2, wellPanel(
                           sliderInput("one1", "slider_one", value =0, min = 0, max=500, step=10),
                           sliderInput("two2", "slider_two", value =250, min = 0, max=1000, step=10)
                           )),
                           column(8,
                                         dataTableOutput('totals_2')),
                       )))
    server <- function(input, output) {

react <- reactive({some_function(input$one, input$two)})

react2 <- reactive({some_function(input$one1, input$two2)})

output$totals<-renderDataTable({react()
  })

output$totals_2<-renderDataTable({react2()
  })

}

Imo I think that is a lot of writing especially if you have a lot parameters.

I figured a way to create n amount of tabs with a loop.

library(shiny)
library(tidyverse)
library(shinythemes)

##modify n_ui to change de number of tabs

n_ui <- 10

ui <- fluidPage(
    uiOutput('repeated_tabs') ##uiOutput can eventually be extended to be reactive on users input to control the n of tabs from inside the app.
    ) 



server <- function(input, output, session) {
  ##create unique index for ids in each tab
  number_panel <- as.character(seq(1, n_ui))
  
    output$repeated_tabs <- renderUI({
    #map will create n tabPanel`s as specified in n_ui at the start of the script
     tabs <- map(number_panel, ~
                     tabPanel(title = paste('Tab', .x), 
                              fluidRow(
                                column(4,
                                       wellPanel(
                                                 sliderInput(paste0('one', .x), "slider_one", value =0, min = 0, max=500, step=10),
                                                 sliderInput(paste0('two',.x), "slider_two", value =250, min = 0, max=1000, step=10),
                                      )),
                                column(8,
                                       dataTableOutput(paste0('totals', .x))
                              ))) ) 
      
      
     tabisize <- partial(navbarPage, title = 'n Tabs app', theme = shinytheme("sandstone"))
      
     exec(tabisize, !!!tabs) #lets me pass each element in tabs as an individual argument (a loop wont do it, neither purrr::reduce()) 
    })  
    
    #to acces tab1 'totals' output
    
    output$totals1 <- renderDataTable({iris}) 
    
    
    
    
}

shinyApp(ui, server)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM