In the below MWE code, the two tabs generated by running the code, "Liabilities module" and "Interest rates", are identical. They are intended as two different paths to the same data table and plots (showing rates) currently generated by running the code.
But these 2 tabs need to diverge as they further develop, in terms of other action buttons in the sidebar panel and in terms of the action buttons appearing at the top of the main panels for each of the respective tabs. For sake of easy example, I'd like to add a "Test" action button to the "Liabilities module" but not to the "Interest rates" module.
How would I add multiple conditions to a conditional panel, so in this case "Test" action button appears in "Liabilities module" but not in "Interest rates" tabs? As shown in the image at the bottom.
My humble attempt to do this is marked # ATTEMPT # in the below MWE; naturally, it doesn't work so I had to comment it out.
MWE code:
library(shiny)
library(shinyMatrix)
library(shinyjs)
matrix4Default <- matrix(c(0.2), 4, 1, dimnames = list(c("A", "B", "C", "D"), NULL))
matrix4Input <- function(x, matrix4Input) {
matrixInput(
x,
value = matrix4Input,
rows = list(extend = FALSE, names = TRUE),
cols = list(
extend = FALSE,
names = FALSE,
editableNames = FALSE
),
class = "numeric"
)
}
vectorBaseRate <- function(x, y) {
a <- rep(y, x)
b <- seq(1:x)
c <- data.frame(x = b, y = a)
return(c)
}
vectorBaseRatePlot <- function(w, x, y, z) {
plot(
w[, 1],
sapply(w[, 2], function(x)
gsub("%", "", x)),
main = x,
xlab = y,
ylab = z
)
}
ui <- pageWithSidebar(
headerPanel("Model..."),
sidebarPanel(fluidRow(helpText(h5(
strong("Base Input Panel")
))), uiOutput("Panels")),
mainPanel(tabsetPanel(
tabPanel(
"Liabilities module",
value = 4,
fluidRow(
radioButtons(
inputId = "showRates4",
label = h5(strong(helpText(
"Select model output to view:"
))),
choices = c('Rates values', 'Rates plots'),
selected = 'Rates values',
inline = TRUE
),
uiOutput('showTab4Results')
)
),
# close tab panel
tabPanel(
"Interest rates",
value = 5,
fluidRow(
radioButtons(
inputId = "showRates5",
label = h5(strong(helpText(
"Select model output to view:"
))),
choices = c('Rates values', 'Rates plots'),
selected = 'Rates values',
inline = TRUE
),
uiOutput('showTab5Results')
)
),
# close tab panel
id = "tabselected"
))
) # close tabset panel, main panel, page with sidebar
server <- function(input, output, session) {
matrix4 <- reactive(input$matrix4)
baseRate <-
function() {
vectorBaseRate(60, input$matrix4[1, 1])
} # Must remain in server section
output$Panels <- renderUI({
conditionalPanel(
condition = "input.tabselected==4 || input.tabselected==5", actionButton('modRates', 'Modify Rates'),
# ATTEMPT # condition = "input.tabselected==4", actionButton('test','Test')
) # close conditional panel
}) # close renderUI
vectorRates <- reactive({
if (is.null(input$modRates)){DF <- NULL}
else {
if (input$modRates < 1) {DF <- cbind(Period = 1:60, BaseRate = 0.2)}
else {
req(input$matrix4)
DF <- cbind(Period = 1:60, BaseRate = baseRate()[, 2])
} # close 2nd else
} # close 1st else
DF
}) # close reactive
observeEvent(input$resetRatesStruct, {updateMatrixInput(session, 'matrix4', matrix4Default)})
output$table5 <- output$table4 <- renderTable({vectorRates()})
output$graph5 <- output$graph4 <- renderPlot({
vectorBaseRatePlot(vectorRates(), "A Variable", "Period", "Rate")
})
output$showTab4Results <- renderUI({
if (input$showRates4 == 'Rates values'){tableOutput("table4")}
else {plotOutput("graph4")}
})
output$showTab5Results <- renderUI({
if (input$showRates5 == 'Rates values'){tableOutput("table5")}
else {plotOutput("graph5")}
})
observeEvent(input$modRates,
{
showModal(modalDialog(
matrix4Input("matrix4", if (is.null(input$matrix4))
matrix4Default
else
input$matrix4),
useShinyjs(),
footer = tagList(
actionButton("resetRatesStruct", "Reset"),
modalButton("Close")
)
))
} # close modalDialog, showModal, and showModal function
) # close observeEvent
} # close server
shinyApp(ui, server)
You can simply add another conditionalPanel
using a different condition.
Furthermore I dropped all renderUI
's as it is not necessary to create conditionalPanels on the server side. This should result in a faster UI.
I added some more buttons to show the concept:
library(shiny)
library(shinyMatrix)
library(shinyjs)
matrix4Default <- matrix(c(0.2), 4, 1, dimnames = list(c("A", "B", "C", "D"), NULL))
matrix4Input <- function(x, matrix4Input) {
matrixInput(
x,
value = matrix4Input,
rows = list(extend = FALSE, names = TRUE),
cols = list(
extend = FALSE,
names = FALSE,
editableNames = FALSE
),
class = "numeric"
)
}
vectorBaseRate <- function(x, y) {
a <- rep(y, x)
b <- seq(1:x)
c <- data.frame(x = b, y = a)
return(c)
}
vectorBaseRatePlot <- function(w, x, y, z) {
plot(
w[, 1],
sapply(w[, 2], function(x)
gsub("%", "", x)),
main = x,
xlab = y,
ylab = z
)
}
ui <- pageWithSidebar(
headerPanel("Model..."),
sidebarPanel(fluidRow(helpText(h5(
strong("Base Input Panel")
))),
conditionalPanel(
condition = "input.tabselected==4 || input.tabselected==5", actionButton('modRates', 'Modify Rates')
), # close conditional panel
conditionalPanel(
condition = "input.tabselected==4", actionButton('test1','Test')
)
),
mainPanel(
conditionalPanel(
condition = "input.tabselected==4", actionButton('test2','A mainPanel test button')
),
conditionalPanel(
condition = "input.tabselected==5", actionButton('test3','Another mainPanel test button')
),
tabsetPanel(
selected = 4,
conditionalPanel(
condition = "input.tabselected==4", actionButton('test4','A tabsetPanel test button')
),
conditionalPanel(
condition = "input.tabselected==5", actionButton('test5','Another tabsetPanel test button')
),
tabPanel(
"Liabilities module",
value = 4,
fluidRow(
radioButtons(
inputId = "showRates4",
label = h5(strong(helpText(
"Select model output to view:"
))),
choices = c('Rates values', 'Rates plots'),
selected = 'Rates values',
inline = TRUE
),
conditionalPanel(condition = "input.showRates4 == 'Rates values'", tableOutput("table4")),
conditionalPanel(condition = "input.showRates4 == 'Rates plots'", plotOutput("graph4"))
)
),
# close tab panel
tabPanel(
"Interest rates",
value = 5,
fluidRow(
radioButtons(
inputId = "showRates5",
label = h5(strong(helpText(
"Select model output to view:"
))),
choices = c('Rates values', 'Rates plots'),
selected = 'Rates values',
inline = TRUE
),
conditionalPanel(condition = "input.showRates5 == 'Rates values'", tableOutput("table5")),
conditionalPanel(condition = "input.showRates5 == 'Rates plots'", plotOutput("graph5"))
)
),
# close tab panel
id = "tabselected"
))
) # close tabset panel, main panel, page with sidebar
server <- function(input, output, session) {
matrix4 <- reactive(input$matrix4)
baseRate <- function() {
vectorBaseRate(60, input$matrix4[1, 1])
} # Must remain in server section
vectorRates <- reactive({
if (is.null(input$modRates)){DF <- NULL}
else {
if (input$modRates < 1) {DF <- cbind(Period = 1:60, BaseRate = 0.2)}
else {
req(input$matrix4)
DF <- cbind(Period = 1:60, BaseRate = baseRate()[, 2])
} # close 2nd else
} # close 1st else
DF
}) # close reactive
observeEvent(input$resetRatesStruct, {updateMatrixInput(session, 'matrix4', matrix4Default)})
output$table5 <- output$table4 <- renderTable({vectorRates()})
output$graph5 <- output$graph4 <- renderPlot({
vectorBaseRatePlot(vectorRates(), "A Variable", "Period", "Rate")
})
observeEvent(input$modRates,
{
showModal(modalDialog(
matrix4Input("matrix4", if (is.null(input$matrix4))
matrix4Default
else
input$matrix4),
useShinyjs(),
footer = tagList(
actionButton("resetRatesStruct", "Reset"),
modalButton("Close")
)
))
} # close modalDialog, showModal, and showModal function
) # close observeEvent
} # close server
shinyApp(ui, server)