Hello I am trying to build a shiny app for species sampling. For each species that is selected I need to select in which kind of sampling, and if it is selected in a pin-point sampling it needs to be counted, here is a working example:
library(shiny)
library(shinyMobile)
ui = f7Page(
title = "Show navbar",
f7SingleLayout(
navbar = f7Navbar("Hide/Show navbar"),
f7Button(inputId = "toggle", "Toggle navbar", color = "red"),
f7Text(inputId = "SpeciesName", label = "SpeciesName"),
shinyMobile::f7Card(
f7Flex(
textOutput("SpeciesAgain"),
uiOutput("Sampling_type_ui"),
uiOutput("SpeciesCount")
)
)
)
)
server = function(input, output, session) {
output$SpeciesAgain <- renderText({input$SpeciesName})
output$Sampling_type_ui <- renderUI({
req(input$SpeciesName)
f7Select(inputId = "Sampling_type",
label = "Sampling type",
choices = c("Pin-point", "5m circle", "15m circle"))
})
output$SpeciesCount <- renderUI({
if (req(input$Sampling_type) == "Pin-point") {
shinyMobile::f7Stepper(inputId = "Species1", label = "Species count", min = 1, max = 1000, step = 1, value = 1)
}
})
observeEvent(input$toggle, {
updateF7Navbar()
})
}
shinyApp(ui, server)
This is working just as I want since, it waits until I write a species name, for the f7select
to appear, and if I select Pin-point I can use the counter to get the number of individuals.
However I will need to select several species in the real app, which is why I want to turn this into a Shiny Module. This is what I have tried:
library(shiny)
library(shinyMobile)
#Species <- "Nothofagus"
Species_UI <- function(id){
f7Text(inputId = NS(id,"SpeciesName"), label = "SpeciesName")
shinyMobile::f7Card(
f7Flex(
textOutput(NS(id, "SpeciesAgain")),
uiOutput(NS(id, "Sampling_type_ui")),
uiOutput(NS(id,"SpeciesCount"))
)
)
}
Species_Server <- function(id){
moduleServer(id, function(input, output, session) {
output$SpeciesAgain <- renderText({input$SpeciesName})
output$Sampling_type_ui <- renderUI({
req(input$SpeciesName)
f7Select(inputId = "Sampling_type",
label = "Sampling type",
choices = c("Pin-point", "5m circle", "15m circle"))
})
output$SpeciesCount <- renderUI({
if (req(input$Sampling_type) == "Pin-point") {
shinyMobile::f7Stepper(inputId = "Species1", label = "Species count", min = 1, max = 1000, step = 1, value = 1)
}
})
})
}
library(shiny)
library(shinyMobile)
ui = f7Page(
title = "Show navbar",
f7SingleLayout(
navbar = f7Navbar("Hide/Show navbar"),
f7Button(inputId = "toggle", "Toggle navbar", color = "red"),
Species_UI("Species")
)
)
server = function(input, output, session) {
Species_Server("Species")
observeEvent(input$toggle, {
updateF7Navbar()
})
}
shinyApp(ui, server)
Now when I do this, the UI in the modules does not appear in the app, but I can't figure out what is wrong.
in a final option of the app I want to replace the f7Text
that I use to input the species for a f7SmartSelect
, Where the input for species names is as follows:
library(shiny)
library(shinyMobile)
ui = f7Page(
title = "Show navbar",
f7SingleLayout(
navbar = f7Navbar("Hide/Show navbar"),
f7Button(inputId = "toggle", "Toggle navbar", color = "red"),
f7SmartSelect(inputId = "SpeciesName", label = "SpeciesName",
choices = c("Species1", "Species2", "Species3", "Species4", "Species5"),
multiple = T, openIn = "popup"),
shinyMobile::f7Card(
f7Flex(
textOutput("SpeciesAgain"),
uiOutput("Sampling_type_ui"),
uiOutput("SpeciesCount")
)
)
)
)
server = function(input, output, session) {
output$SpeciesAgain <- renderText({input$SpeciesName})
output$Sampling_type_ui <- renderUI({
req(input$SpeciesName)
f7Select(inputId = "Sampling_type",
label = "Sampling type",
choices = c("Pin-point", "5m circle", "15m circle"))
})
output$SpeciesCount <- renderUI({
if (req(input$Sampling_type) == "Pin-point") {
shinyMobile::f7Stepper(inputId = "Species1", label = "Species count", min = 1, max = 1000, step = 1, value = 1)
}
})
observeEvent(input$toggle, {
updateF7Navbar()
})
}
shinyApp(ui, server)
So that the module is repeated for each species
Any help is welcome
Two issues in your code:
tagList()
so you need to usetagList(
f7Text(inputId = NS(id,"SpeciesName"), label = "SpeciesName"),
shinyMobile::f7Card(
f7Flex(
textOutput(NS(id, "SpeciesAgain")),
uiOutput(NS(id, "Sampling_type_ui")),
uiOutput(NS(id,"SpeciesCount"))
)
)
)
f7Select()
), you still need to be careful about the namespace. In the server
part of a module, you need to use session$ns(id-of-input)
. This is specified in the section "Using renderUI within modules" of the R Shiny modules article. In your case you should use:f7Select(inputId = session$ns("Sampling_type"),
label = "Sampling type",
choices = c("Pin-point", "5m circle", "15m circle"))
Small addition: usually, in the UI part of a module, it is better to define ns <- NS(id)
and then to use ns(id-of-input)
. Similarly, in the server part of a module, you can define ns <- session$ns
.